So you want to add a managed file field to your theme settings to allow for an additional logo, great! Using FAPI and a theme-settings.php file it will be a piece of cake. Not so fast….
The sticking point here is that a managed file once uploaded has to have its status changed to 1 to make it persist. If you don’t change that status then cron will come along and merrily remove it after 6 hours, leaving you with a broken image on your theme.
Add the field to the theme settings in the usual way
MYTHEME_form_system_theme_settings_alter(&$form, $form_state) {
$form['secondary_logo'] = array(
'#title' => t('Secondary logo'),
'#description' => t('A description'),
'#type' => 'managed_file',
'#upload_location' => 'public://secondary-logo/',
'#upload_validators' => array(
'file_validate_extensions' => array('gif png jpg jpeg'),
),
'#default_value' => theme_get_setting('secondary_logo'),
);
}
This gets the field on the settings screen, but doesn’t allow you to persist by altering the status. On any normal form you could use hook_form_submit(), but unfortunately this does not work with theme settings.
The fix is to add a custom submit handler to the form, but due to a bug in the theme settings system you need to specify your theme settings file as a dependency. Add the following to the MYTHEME_form_system_theme_settings_alter function
$form['#submit'][] = 'MYTHEME_settings_form_submit';
// Get all themes.
$themes = list_themes();
// Get the current theme
$active_theme = $GLOBALS['theme_key'];
$form_state['build_info']['files'][] = str_replace("/$active_theme.info", '', $themes[$active_theme]->filename) . '/theme-settings.php'
It is important to note that as you are now altering the $form_state variable you need to add an & to the parameter so that it is passed by reference.
Now you can create the submit handler to actually change the status of the file.
function MYTHEME_settings_form_submit(&$form, $form_state) {
$image_fid = $form_state['values']['secondary_logo'];
$image = file_load($image_fid);
if (is_object($image)) {
// Check to make sure that the file is set to be permanent.
if ($image->status == 0) {
// Update the status.
$image->status = FILE_STATUS_PERMANENT;
// Save the update.
file_save($image);
// Add a reference to prevent warnings.
file_usage_add($image, 'MYTHEME', 'theme', 1);
}
}
}
And there you have it, you should be able to keep hold of your file for longer than 6 hours.
Disclaimer
I was put on the right track to this solution and have used code from this stack overflow question.

Leave a Reply to Sleepy DogCancel reply