Change from Drupal 7 media field to file field

By steinmb, 6 April, 2017

Upgraded from Drupal 6 to 7 or have a early Drupal 7 installation and there are a high change that you might still use the legacy Media field. This field used to be the only field that allowed us to use the media widget. It have since been replaced by a standard file/image field, provided by Drupal 7 core. Media also need the third part module, File entity (file_entity - https://www.drupal.org/project/file_entity). This module extends core file entity functionality.

After file field replaced it the code base got moved into a separate Media submodule (Media Field), and does these days only exist to provide legacy support. New installations should never use this. There are currently no migration path for this field to Drupal 8.x, and probably never will be. Migrating to Drupal 8 and you probably have to write your own migration code. A good workaround though is to first to change field type to image or file type.

The issue "Convert 'Media' fields to 'File' fields that use the 'Media file selector' widget" - https://www.drupal.org/node/1349058 have been around since 22 Nov 2011 without getting enough eyes and tests to be committed into the Media module, but as usual –—there is more than one way to skin a cat. Especially in Drupal.

A client came to me with a site containing lots of data and hundreds of different fields. The site dated back to Drupal 6 that at was at some point upgraded to Drupal 7. Having this special field type was in the end getting anoying and sometime produces unpredictable results. Some places it required custom code other places

leaving all kind of custom workarounds in config and code to make it match the other file and image fields.

The issue had been pending for a long time, every one hopeing that the field migration code to mature. That never happend and we decied to write a custom hook_update_N().

Drupal Helper module https://www.drupal.org/project/helper is a very useful module that can reduce the amount of code needed to pull this off. Without further ado. this was all we needed to pull this off.


/**
* Change legacy media field to a file field.
*/
function hook_update_N() {
// Get a list of all fields.
$fields = field_info_field_map();

// Obtain the machine name of all image fields and store them in an array.
foreach ($fields as $name => $field) {
if ($field['type'] == 'media') {
$image_fields[$name] = $field;
}
}

// Convert all media fields into file field.
if (!empty($image_fields)) {
foreach ($image_fields as $name => $field) {
$results[$name] = FieldChangeHelper::changeType($name, 'file');
}
}
}
?>

The site was also using the Features module. All config was stored in multiple feature modules. Even with that, changing field types proved to be quite easy. Even getting the migrated fields config commited into features worked and features came out clean after the update hook had run. The example here run the code when you run update (example.com/update) or from drush updatedb –but you can also choose to make it for a drush script that you execute with drush scr —but then you do not need wrap the code in a function.

Note: Inspiration to this is stolen from https://www.drupal.org/node/2481425 and run of file_entity and media 7.x-2.x version.