Anytime I add a managed_file field to theme-settings.php, the field works, however, it gets saved with a status of 0 in the database.

When I add a submit handler to the theme settings form, I get a " Call to undefined function" error.

Of course, when I remove the managaed_file field, the undefined function error goes away and the submit handler fires as normal.

Has anyone tried doing this? Is there another way around this problem?

thanks! david

  • I'm thinking this might be a Drupal Core bug, if so I put in an issue here: drupal.org/node/1862892 However, I'd like to know if any of you guys got this to work. thanks! Commented Dec 10, 2012 at 14:32

2 Answers 2


The theme-settings.php is included from system_theme_settings(), which executes the following code.

// Call engine-specific settings.
$function = $themes[$key]->prefix . '_engine_settings';
if (function_exists($function)) {
  $form['engine_specific'] = array(
    '#type' => 'fieldset', 
    '#title' => t('Theme-engine-specific settings'), 
    '#description' => t('These settings only exist for the themes based on the %engine theme engine.', array('%engine' => $themes[$key]->prefix)),
  $function($form, $form_state);
foreach ($theme_keys as $theme) {
  // Include the theme-settings.php file.
  $filename = DRUPAL_ROOT . '/' . str_replace("/$theme.info", '', $themes[$theme]->filename) . '/theme-settings.php';
  if (file_exists($filename)) {
    require_once $filename;

  // Call theme-specific settings.
  $function = $theme . '_form_system_theme_settings_alter';
  if (function_exists($function)) {
    $function($form, $form_state);

Unfortunately, the file is not loaded from Drupal before any validation/submission handlers for that form are invoked.

When form_cache_get() is called, the following code is executed.

    foreach ($form_state['build_info']['files'] as $file) {
      if (is_array($file)) {
        $file += array('type' => 'inc', 'name' => $file['module']);
        module_load_include($file['type'], $file['module'], $file['name']);
      elseif (file_exists($file)) {
        require_once DRUPAL_ROOT . '/' . $file;

As form_get_cache() seems called before a form is validated/submitted, you could use the following code. (Replace mytheme with the short name of your theme.)

function mytheme_form_system_theme_settings_alter(&$form, &$form_state) {
  $theme = $GLOBALS['theme_key'];
  $themes = list_themes();

  $form_state['build_info']['files'][] = str_replace("/$theme.info", '', $themes[$theme]->filename) . '/theme-settings.php';

Another potential solution (the previous one did not work for me) would be to add some code in the theme-settings.php file that checks to see if the uploaded image is saved and if not saves it. This is not really the proper place to do something like this, but it is simple and it works. Here is the code I used.

// Defining the managed_file form element:
$form['header']['mytheme_header_image_custom'] = array(
    '#title'        => t('Custom Header Image File'),
    '#type'         => 'managed_file',
    '#description'  => t('Upload a custom header image for your site. Dimensions to display properly must be: 968 x 300'),
    '#default_value' => theme_get_setting('mytheme_header_image_custom'),
    '#upload_location' => 'public://theme_header_images/',
    '#upload_validators' => array(
        'file_validate_extensions' => array("png jpg jpeg gif"),

// Setting the status to saved permanently if needed.
$image_custom_index = theme_get_setting('mytheme_header_image_custom');
if (isset($image_custom_index)) {
    $fid = theme_get_setting('mytheme_header_image_custom');
    $file = file_load($fid);
    if ($file->status == 0) {
        $file->status = FILE_STATUS_PERMANENT;
        // Sets a Drupal message just for clarity.
        drupal_set_message(t('Header image saved.'), 'status');

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.