$uuid->generate(), 'entity_types' => array(), 'cardinality' => 1, 'translatable' => FALSE, 'locked' => FALSE, 'settings' => array(), 'indexes' => array(), 'active' => TRUE, 'status' => 1, 'langcode' => 'und', ); // Set the storage. $field_config['storage'] = array( 'type' => 'field_sql_storage', 'module' => 'field_sql_storage', 'active' => TRUE, 'settings' => array(), ); // Save in config. Drupal::config('field.field.' . $field_config['id']) ->setData($field_config) ->save(); // Create storage for the field. This requires a field entity, but cannot use // the regular entity_create() function here. $field_entity = new Field($field_config); field_sql_storage_field_storage_create_field($field_entity); } /** * Writes a field instance directly to configuration. * * Upgrades using this function need to use hook_update_dependencies() to ensure * they get executed after field_update_8003(). * * @param array $field_config * An array of field properties. * @param array $instance_config * An array of field instance properties. * * @ingroup update_api */ function _update_8003_field_create_instance(array $field_config, array &$instance_config) { $uuid = new Uuid(); // Merge in defaults. $instance_config += array( 'description' => '', 'required' => FALSE, 'uuid' => $uuid->generate(), 'field_uuid' => $field_config['uuid'], 'field_type' => $field_config['type'], 'default_value' => array(), 'default_value_function' => '', 'settings' => array(), 'widget' => array(), 'status' => 1, 'langcode' => 'und', ); // Save in config. Drupal::config('field.instance.' . $instance_config['id']) ->setData($instance_config) ->save(); } /** * @addtogroup updates-7.x-to-8.x * @{ */ /** * Empty update - moved into field_update_8003(). */ function field_update_8001() { } /** * Migrate all instance widget and display settings to configuration. * * @ingroup config_upgrade */ function field_update_8002() { $form_displays = $displays = array(); module_load_install('entity'); $query = db_select('field_config_instance', 'fc')->fields('fc'); foreach ($query->execute() as $record) { // Unserialize the data array and start investigating the display key // which holds the configuration of this instance for all view modes. $data = unserialize($record->data); // Skip field instances that were created directly with the new API earlier // in the upgrade path. if (!isset($data['widget']) && !isset($data['display'])) { continue; } // Migrate 'widget' settings. if (isset($data['widget'])) { $widget_options = $data['widget']; // Determine name and create initial entry in the $form_displays array. $form_display_id = $record->entity_type . '.' . $record->bundle . '.default'; if (!isset($form_displays[$form_display_id])) { $form_displays[$form_display_id] = _update_8000_entity_get_form_display($record->entity_type, $record->bundle, 'default'); } // We do not need the 'module' key anymore. unset($widget_options['module']); $form_displays[$form_display_id]->set("content.$record->field_name", $widget_options); } // Migrate 'display' settings. if (isset($data['display'])) { foreach ($data['display'] as $view_mode => $display_options) { // Determine name and create initial entry in the $displays array if it // does not exist yet. $display_id = $record->entity_type . '.' . $record->bundle . '.' . $view_mode; if (!isset($displays[$display_id])) { $displays[$display_id] = _update_8000_entity_get_display($record->entity_type, $record->bundle, $view_mode); } // The display object does not store hidden fields. if ($display_options['type'] != 'hidden') { // We do not need the 'module' key anymore. unset($display_options['module']); $displays[$display_id]->set("content.$record->field_name", $display_options); } } } // Remove the 'widget' and 'display' keys and save the record back into the // table. unset($data['display'], $data['widget']); db_update('field_config_instance') ->condition('id', $record->id) ->fields(array( 'data' => serialize($data), )) ->execute(); } // Migration of 'extra_fields' display settings. Avoid calling // entity_get_info() by fetching the relevant variables directly in the // variable table. $variables = array_map('unserialize', db_query("SELECT name, value FROM {variable} WHERE name LIKE '%field_bundle_settings_%'")->fetchAllKeyed()); foreach ($variables as $variable_name => $variable_value) { if (preg_match('/field_bundle_settings_(.*)__(.*)/', $variable_name, $matches)) { $variable_needs_update = FALSE; $entity_type = $matches[1]; $bundle = $matches[2]; if (isset($variable_value['extra_fields']['form'])) { foreach ($variable_value['extra_fields']['form'] as $field_name => $field_settings) { // Determine name and create initial entry in the $form_displays // array if it does not exist yet. $form_display_id = $entity_type . '.' . $bundle . '.default'; if (!isset($form_displays[$form_display_id])) { $form_displays[$form_display_id] = _update_8000_entity_get_form_display($entity_type, $bundle, 'default'); } $form_displays[$form_display_id]->set("content.$field_name", $field_settings); } // Remove the old entry. unset($variable_value['extra_fields']['form']); $variable_needs_update = TRUE; } if (isset($variable_value['extra_fields']['display'])) { foreach ($variable_value['extra_fields']['display'] as $field_name => $field_settings) { foreach ($field_settings as $view_mode => $display_options) { // Determine name and create initial entry in the $displays array // if it does not exist yet. $display_id = $entity_type . '.' . $bundle . '.' . $view_mode; if (!isset($displays[$display_id])) { $displays[$display_id] = _update_8000_entity_get_display($entity_type, $bundle, $view_mode); } // Set options in the display. $new_options = array('visible' => $display_options['visible']); // The display object only stores the weight for 'visible' extra // fields. if ($display_options['visible']) { $new_options['weight'] = $display_options['weight']; } $displays[$display_id]->set("content.$field_name", $new_options); } } // Remove the old entry. unset($variable_value['extra_fields']['display']); $variable_needs_update = TRUE; } if ($variable_needs_update) { variable_set($variable_name, $variable_value); } } } // Save the form displays to configuration. foreach ($form_displays as $config) { $config->save(); } // Save the displays to configuration. foreach ($displays as $config) { $config->save(); } } /** * Convert fields and instances to config. */ function field_update_8003() { $uuid = new Uuid(); $state = Drupal::state(); $deleted_fields = $state->get('field.field.deleted') ?: array(); $deleted_instances = $state->get('field.instance.deleted') ?: array(); $field_data = array(); // Migrate field definitions. $records = db_query("SELECT * FROM {field_config}")->fetchAll(PDO::FETCH_ASSOC); foreach ($records as $record) { $record['data'] = unserialize($record['data']); $config = array( 'id' => $record['field_name'], 'uuid' => $uuid->generate(), 'type' => $record['type'], 'module' => $record['module'], 'active' => $record['active'], 'settings' => $record['data']['settings'], 'storage' => array( 'type' => $record['storage_type'], 'module' => $record['storage_module'], 'active' => $record['storage_active'], 'settings' => $record['data']['storage']['settings'], ), 'locked' => $record['locked'], 'cardinality' => $record['cardinality'], 'translatable' => $record['translatable'], 'entity_types' => $record['data']['entity_types'], 'indexes' => $record['data']['indexes'] ?: array(), 'status' => 1, 'langcode' => 'und', ); // Reassign all list.module fields to be controlled by options.module. if ($config['module'] == 'list') { $config['module'] = 'options'; } // Save in either config or state. if (!$record['deleted']) { Drupal::config('field.field.' . $config['id']) ->setData($config) ->save(); } else { $config['deleted'] = TRUE; $deleted_fields[$config['uuid']] = $config; // Additionally, rename the data tables for deleted fields. Technically // this would belong in an update in field_sql_storage.module, but it is // easier to do it now, when the old numeric ID is available. if ($config['storage']['type'] == 'field_sql_storage') { $field = new Field($config); $tables = array( "field_deleted_data_{$record['id']}" => _field_sql_storage_tablename($field), "field_deleted_revision_{$record['id']}" => _field_sql_storage_revision_tablename($field), ); foreach ($tables as $table_old => $table_new) { if (db_table_exists($table_old)) { db_rename_table($table_old, $table_new); } } } } // Store the UUID and field type, they will be used when processing // instances. $field_data[$record['id']] = array( 'uuid' => $config['uuid'], 'type' => $record['type'], ); } // Migrate instance definitions. $records = db_query("SELECT * FROM {field_config_instance}")->fetchAll(PDO::FETCH_ASSOC); foreach ($records as $record) { $record['data'] = unserialize($record['data']); $config = array( 'id' => $record['entity_type'] . '.' . $record['bundle'] . '.' . $record['field_name'], 'uuid' => $uuid->generate(), 'field_uuid' => $field_data[$record['field_id']]['uuid'], 'field_type' => $field_data[$record['field_id']]['type'], 'entity_type' => $record['entity_type'], 'bundle' => $record['bundle'], 'label' => $record['data']['label'], 'description' => $record['data']['description'], 'required' => $record['data']['required'], 'default_value' => isset($record['data']['default_value']) ? $record['data']['default_value'] : array(), 'default_value_function' => isset($record['data']['default_value_function']) ? $record['data']['default_value_function'] : '', 'settings' => $record['data']['settings'], 'status' => 1, 'langcode' => 'und', ); // Save in either config or state. if (!$record['deleted']) { Drupal::config('field.instance.' . $config['id']) ->setData($config) ->save(); } else { $config['deleted'] = TRUE; $deleted_instances[$config['uuid']] = $config; } // Update {file_usage} table in case this instance has a default image. if (!empty($config['settings']['default_image'])) { db_update('file_usage') ->fields(array('id' => $config['field_uuid'])) ->condition('type', 'default_image') ->condition('module', 'image') ->condition('id', $record['field_id']) ->condition('fid', $config['settings']['default_image']) ->execute(); } } // Save the deleted fields and instances in state. $state->set('field.field.deleted', $deleted_fields); $state->set('field.instance.deleted', $deleted_instances); } /** * Moves field_storage_default and field_language_fallback to config. * * @ingroup config_upgrade */ function field_update_8004() { update_variable_set('field_language_fallback', TRUE); update_variables_to_config('field.settings', array( 'field_storage_default' => 'default_storage', 'field_language_fallback' => 'language_fallback', )); } /** * Removes the 'user_register_form' setting from field instances and populates * the user.user.register form display. */ function field_update_8005() { $uuid = new Uuid(); $user_default_form_display = Drupal::config('entity.form_display.user.user.default'); $user_register_config_data = array( 'id' => 'user.user.register', 'uuid' => $uuid->generate(), 'targetEntityType' => 'user', 'bundle' => 'user', 'mode' => 'register', 'content' => array(), ); foreach (config_get_storage_names_with_prefix('field.instance') as $config_id) { $instance_config = Drupal::config($config_id); if ($instance_config->get('entity_type') == 'user' && $instance_config->get('settings.user_register_form')) { list(, , $field_id) = explode('.', $instance_config->get('id')); $user_register_config_data['content'][$field_id] = $user_default_form_display->get('content.' . $field_id); } $settings = $instance_config->get('settings'); unset($settings['user_register_form']); $instance_config->set('settings', $settings)->save(); } // Save the new 'register' form display. Drupal::config('entity.form_display.user.user.register') ->setData($user_register_config_data) ->save(); } /** * @} End of "addtogroup updates-7.x-to-8.x". * The next series of updates should start at 9000. */