2

I'm upgrading the Mayo theme to Drupal 8. For Drupal 7 it worked like this in theme-settings.php with hook_form_system_theme_settings_alter():

  $form['adv_header']['header_bg'] = array(
    '#type' => 'file',
    '#title' => t('Upload header background image'),
    '#size' => 40,
    '#attributes' => array('enctype' => 'multipart/form-data'),
    '#description' => t('If you don\'t jave direct access to the server, use this field to upload your header background image'),
    '#element_validate' => array('mayo_header_bg_validate'),
  );

element_validate in the above called:

/**
 * Check and save the uploaded header background image
 */
function mayo_header_bg_validate($element, &$form_state) {
  global $base_url;

  $validators = array('file_validate_is_image' => array());
  $file = file_save_upload('header_bg', $validators, "public://", FILE_EXISTS_REPLACE);

  if ($file) {
    // change file's status from temporary to permanent and update file database
    $file->status = FILE_STATUS_PERMANENT;
    file_save($file);

    $file_url = file_create_url($file->uri);
    $file_url = str_ireplace($base_url, '', $file_url);

    // set to form
    $form_state['values']['header_bg_file'] = $file_url;
  }
}

For the Drupal 8 version I have added use Drupal\Core\Form\FormStateInterface; at the top of theme-settings.php and some changes to mayo_header_bg_validate(). So far it looks like this:

/**
 * Check and save the uploaded header background image
 */
function mayo_header_bg_validate($element, FormStateInterface $form_state) {
  global $base_url;

  $validators = array('file_validate_is_image' => array());
  $file = file_save_upload('header_bg', $validators, "public://", NULL, FILE_EXISTS_REPLACE);
  if ($file) {
    //change file's status from temporary to permanent and update file database
    $file->status = FILE_STATUS_PERMANENT;
    //file_save($file);

    $file_url = file_create_url($file->uri);
    $file_url = str_ireplace($base_url, '', $file_url);

     //set to form
    //$form_state['values']['header_bg_file'] = $file_url;
    $form_state->setValue(['header_bg_file'], $file_url);

  }
}

It does upload the image to /sites/default/files and put an entry into the file_managed table. file_save() is gone for Drupal 8 and I couldn't find a change log showing how to replace it for Drupal 8. 'header_bg' just shows a value of "/" in mayo.settings.

2 Answers 2

1

file_save_upload() returns an array of Drupal\file\Entity\File objects; you need to use File::getFileUri().

// ...    
$file = file_save_upload('header_bg', $validators, "public://", NULL, FILE_EXISTS_REPLACE);
$uri = $file[0]->getFileUri();
$form_state->setValue('header_bg_file', $uri);
// ...
4
  • When I tried that I got: Fatal error: Call to a member function getFileUri() on a non-object in C:\Users\John\Documents\My Webs\dev8\themes\mayo\theme-settings.php on line 1038
    – bumpaw
    Commented Jan 2, 2015 at 17:23
  • Check your form definition and check the form values. var_dump($values = $form_state->getValues());. see more in api.drupal.org/api/drupal/…
    – dmouse
    Commented Jan 3, 2015 at 3:10
  • try with $file[0]->getFileUri();
    – dmouse
    Commented Jan 3, 2015 at 3:51
  • This has the file uploaded and in the file_managed table. Just have to figure out how to get the status = 1 for Drupal 8.
    – bumpaw
    Commented Jan 6, 2015 at 3:04
4

I suggest you look at ThemeSettingsForm, which is where the code lives for the logo and favicon. Doing something similar there would work.

Note that it doesn't save the file, it just uses the file entity that it gets from the widget and puts it in a permanent place using file_unmanaged_copy().

Make sure to keep the conditional, so that you don't get a fatal error when not providing an image (I assume that's the problem with @dmouse's code example).

2
  • "I suggest you look at ThemeSettingsForm," I've been there several times in the past few days. I don't think $file = file_save_upload() is giving the proper result. When I try dpm($file); it fills the page with output for a moment and then disappears. I used a screen capture to grab it and I see the word "recursion" in there often which can't be good. It's probably some OOP thing that I'm not grasping. I do have Mayo 8 working pretty good except for a couple of small things like this.
    – bumpaw
    Commented Jan 3, 2015 at 0:09
  • Don't use dpm() in Drupal 8, use kint(), or $file->toArray(). Anyway, if you do something, then you should be fine, that means it does return something and that should be what you need.
    – Berdir
    Commented Jan 3, 2015 at 12:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.