diff --git a/includes/media.pages.inc b/includes/media.pages.inc index e625a7dd4cea459bfc9383abce8b132c36f042dc..72c36ecf42f9df873692c94ecd1af417ddc6007e 100644 --- a/includes/media.pages.inc +++ b/includes/media.pages.inc @@ -81,3 +81,196 @@ function media_file_edit_modal($form, &$form_state, $file, $js) { // Otherwise, just return the output. return $output; } + +/** + * File type migration page. + * + * Allows site administrator to execute migration of old/disabled/deleted + * file types to new ones. + */ +function media_upgrade_file_types($form, &$form_state) { + $migratable_types = _media_get_migratable_file_types(); + + // Silently return if there are no file types that need migration. + if (empty($migratable_types)) { + return array( + 'message' => array( + '#markup' => t('There are no file types that need migration.'), + ), + ); + } + + $form['message'] = array( + 'message' => array( + '#markup' => t('This page allows you to migrate deprecated and/or disabled file types to new ones. It will migrate files from old type to new one and optionally migrate fields and delete old type.'), + ), + ); + + $form['migrate_fields'] = array( + '#type' => 'checkbox', + '#title' => t('Migrate fields'), + '#default_value' => TRUE, + '#description' => t('Migrate fields and their values from old file types to new ones.'), + ); + $form['delete_old_type'] = array( + '#type' => 'checkbox', + '#title' => t('Delete old type'), + '#default_value' => FALSE, + '#description' => t('Delete old file type if migration was successful and delete operation is possible (type is not exported in code).'), + ); + $form['migrate_mimes'] = array( + '#type' => 'checkbox', + '#title' => t('Migrate type mime-type'), + '#default_value' => TRUE, + '#description' => t('Move mime-type from old type to new one.'), + ); + + $form['upgradable_types'] = array( + '#type' => 'fieldset', + '#title' => t('Upgradable file types'), + ); + + $options = array('- ' . t('Do not upgrade') . ' -'); + foreach (file_type_get_enabled_types() as $type) { + $options[$type->type] = $type->label; + } + + foreach ($migratable_types as $machine_name) { + $type = file_type_load($machine_name); + if (!$type) { + $type = new stdClass; + $type->label = $type->type = $machine_name; + } + $form['upgradable_types'][$machine_name] = array( + '#type' => 'select', + '#title' => $type->label, + '#options' => $options, + '#description' => t( + 'Select file type which you want to migrate @type to. Select %no_upgrade if type should stay as it is.', + array('@type' => $type->label, '%no_upgrade' => '- ' . t('Do not upgrade') . ' -')), + ); + } + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Start migraton'), + ); + + return $form; +} + +/** + * File type migration page submit handler. + */ +function media_upgrade_file_types_submit($form, &$form_state) { + $migratable_types = _media_get_migratable_file_types(); + $migrate = FALSE; + foreach ($migratable_types as $type) { + if ($form_state['values'][$type]) { + $migrate = TRUE; + break; + } + } + + // Return silently if no types were selected for migration. + if (!$migrate) { + return; + } + + // Use confirmation page/form. + $query = $form_state['values']; + unset($query['op']); + unset($query['submit']); + unset($query['form_id']); + unset($query['form_token']); + unset($query['form_build_id']); + + $form_state['redirect'] = array( + 'admin/structure/file-types/upgrade/confirm', + array('query' => $query), + ); +} + +/** + * File types migration confirmation page. + */ +function media_upgrade_file_types_confirm($form, &$form_state) { + return confirm_form( + $form, + t('Do you really want to migrate selected file types?'), + 'admin/structure/file-types/upgrade', + NULL, + t('Migrate') + ); +} + +/** + * File types migration confirmation page sumit. Executes actual migration. + */ +function media_upgrade_file_types_confirm_submit($form, &$form_state) { + $migratable_types = _media_get_migratable_file_types(); + foreach ($migratable_types as $type) { + if ($_GET[$type] && $bundle_new = file_type_load($_GET[$type])) { + // Old bundle might be deleted so let's fake some values. + $bundle_old = file_type_load($type); + if (empty($bundle_old)) { + $bundle_old = new stdClass; + $bundle_old->type = $type; + $bundle_old->mimetypes = array(); + $bundle_old->export_type = 2; + } + + // Migrate fields to new bundle. + if ($_GET['migrate_fields']) { + $old_fields = db_select('field_config_instance', 'fc')->fields('fc', array('field_name'))->condition('entity_type', 'file')->condition('bundle', $bundle_old->type)->execute()->fetchCol(); + $new_fields = db_select('field_config_instance', 'fc')->fields('fc', array('field_name'))->condition('entity_type', 'file')->condition('bundle', $bundle_new->type)->execute()->fetchCol(); + $fields_to_move = array_diff($old_fields, $new_fields); + $fields_to_drop = array_diff($old_fields, $fields_to_move); + + db_update('field_config_instance') + ->fields(array('bundle' => $bundle_new->type)) + ->condition('entity_type', 'file') + ->condition('bundle', $bundle_old->type) + ->condition('field_name', $fields_to_move, 'IN') + ->execute(); + + db_delete('field_config_instance') + ->condition('entity_type', 'file') + ->condition('bundle', $bundle_old->type) + ->condition('field_name', $fields_to_drop, 'IN') + ->execute(); + + field_cache_clear(); + module_invoke_all('field_attach_rename_bundle', 'file', $bundle_old->type, $bundle_new->type); + } + + // Migrate mimetypes to new bundle. + if ($_GET['migrate_mimes']) { + $changed = FALSE; + foreach ($bundle_old->mimetypes as $mime) { + if (!file_entity_match_mimetypes($bundle_new->mimetypes, $mime)) { + $bundle_new->mimetypes[] = $mime; + $changed = TRUE; + } + } + + if ($changed) { + file_type_save($bundle_new); + } + } + + // Delete old bundle. + if ($_GET['delete_old_type'] && $bundle_old->export_type == 1) { + file_type_delete($bundle_old); + } + + // Migrate files. + db_update('file_managed') + ->fields(array('type' => $bundle_new->type)) + ->condition('type', $bundle_old->type) + ->execute(); + } + } + + $form_state['redirect'] = 'admin/structure/file-types'; +} diff --git a/includes/media.variables.inc b/includes/media.variables.inc index 27b904bc1ddf346cad9ddfe1f99c255f451b7c60..b70d3c6786319f9a718c4a6cf42d9606e21bc3d1 100644 --- a/includes/media.variables.inc +++ b/includes/media.variables.inc @@ -160,6 +160,7 @@ function media_variable_default($name = NULL) { 'browser_library_empty_message' => NULL, 'browser_pager_limit' => NULL, 'browser_viewtype_default' => NULL, + 'display_types_migration_mess' => TRUE, ); } diff --git a/media.install b/media.install index ccb83556f22f990534abbee7c9d6fbe302bad389..adca24d528455a5291d41c946876859d4218431a 100644 --- a/media.install +++ b/media.install @@ -913,53 +913,12 @@ function media_update_7208() { } /** - * Update {file_managed}.type with the new file types provided by file_entity. + * DEPRECATED: Update {file_managed}.type with the new file types provided by + * file_entity. (Types migration has been moved to admin/structure/file-types/upgrade', + * where can be executed manually.) */ function media_update_7209() { - // Reset static cache to ensure our new file types are recognized - drupal_static_reset('ctools_export_load_object_table_exists'); - // Go through file_managed table and update files with the new type names. - $enabled_types = file_type_get_enabled_types(); - - $query = db_select('file_managed', 'f') - ->fields('f', array('fid', 'type', 'filemime', 'uri')); - $files = $query->execute()->fetchAllAssoc('fid'); - $failed = array(); - foreach ($files as $fid => $file) { - if (empty($file->filemime)) { - $file->filemime = file_get_mimetype($file->uri); - } - - $valid = FALSE; - foreach ($enabled_types as $type) { - if (in_array($file->filemime, $type->mimetypes)) { - $file->newtype = $type->type; - $valid = TRUE; - continue; - } - } - - if (!$valid) { - $failed[] = $file->uri; - // Mark this file with FILE_TYPE_NONE so it is easier to be tracked and - // updated later, instead of scanning the whole table again. - $file->newtype = FILE_TYPE_NONE; - } - - if ($file->newtype != $file->type) { - db_update('file_managed') - ->fields(array('type' => $file->newtype)) - ->condition('fid', $file->fid) - ->execute(); - } - } - - if (!empty($failed)) { - return t('The following file(s) have a mimetype that does not belong to any file entity type. Please update manually.') . PHP_EOL . implode(PHP_EOL, $failed); - } - - return t('All files types converted succesfully.'); } /** @@ -1021,3 +980,26 @@ function _media_update_7204_update_views_display_options(&$display_options, $vie } return $updated; } + +/** + * Re-create application file type for legacy reasons. + */ +function media_update_7212() { + module_load_include('inc', 'file_entity', 'file_entity.file_api'); + if (!file_type_load('application')) { + $application = (object) array( + 'api_version' => 1, + 'type' => 'application', + 'label' => t('Application'), + 'description' => t('Multipurpose type - kept to support older sites.'), + 'mimetypes' => array(), + 'streams' => array( + 'public', + ), + ); + + file_type_save($application); + $application = file_type_load('application'); + file_type_disable($application); + } +} diff --git a/media.module b/media.module index cd7419e703d0476bb655df80463cef411c363369..fd597897faa930786c6a531f58097a90bdb12e02 100644 --- a/media.module +++ b/media.module @@ -202,6 +202,24 @@ function media_menu() { 'type' => MENU_CALLBACK, ); + // Upgrade interface for old file types. + $items['admin/structure/file-types/upgrade'] = array( + 'title' => 'Upgrade types', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('media_upgrade_file_types'), + 'access arguments' => array('administer file types'), + 'file' => 'includes/media.pages.inc', + 'type' => MENU_CALLBACK, + ); + $items['admin/structure/file-types/upgrade/confirm'] = array( + 'title' => 'Upgrade types', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('media_upgrade_file_types_confirm'), + 'access arguments' => array('administer file types'), + 'file' => 'includes/media.pages.inc', + 'type' => MENU_CALLBACK, + ); + return $items; } @@ -357,6 +375,15 @@ function media_page_alter(&$page) { } } } + + // Check if there are file types that need migration and display a message + // to user if so. + $menu = menu_get_item(); + if (media_variable_get('display_types_migration_mess') && $menu['path'] == 'admin/structure/file-types') { + if ($migratable_types = _media_get_migratable_file_types()) { + drupal_set_message(t('There are disabled/deleted file types that can be migrated to their new alternatives. Visit migration page to get more information.', array('!url' => url('admin/structure/file-types/upgrade')))); + } + } } /** @@ -1266,3 +1293,24 @@ function media_get_remote_stream_wrappers() { $wrappers = array_diff_key($wrappers, file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL_HIDDEN)); return $wrappers; } + + +/** + * Checks if there are any files that belong to disabled or deleted file + * types. + * + * @return Array of file types (machine names) that are candidates for + * migration. + */ +function _media_get_migratable_file_types() { + $query = db_select('file_managed', 'f') + ->fields('f', array('type')) + ->distinct(); + $types = $query->execute()->fetchCol(); + $enabled_types = array(); + foreach (file_type_get_enabled_types() as $type) { + $enabled_types[] = $type->type; + } + + return array_diff($types, $enabled_types); +}