diff --git a/reference.install b/reference.install index 90961f6..4cbc43d 100644 --- a/reference.install +++ b/reference.install @@ -23,3 +23,272 @@ function reference_field_schema($field) { ), ); } + +/** + * Implements hook_install(). + */ +function reference_install() { + // Reset schema version, so update hooks can be processed after installation. + backdrop_set_installed_schema_version('reference', '0'); +} + +/** + * Helper function to update field base settings. + */ +function _reference_install_update_field_base_settings($settings, $target_enity_type) { + $settings['module'] = 'reference'; + $settings['type'] = 'reference'; + + // Discard all settings except target entity type. + $settings['settings'] = array( + 'entity_type' => $target_enity_type, + ); + + return $settings; +} + +/** + * Helper function to update field instance settings. + */ +function _reference_install_update_field_instance_settings($settings, array $bundles) { + // Convert field instance. + $settings['widget']['module'] = 'reference'; + + // Always set widget type to 'reference_autocomplete'; there is no + // 'entityreference_autocomplete_tags' option in reference module. + $settings['widget']['type'] = 'reference_autocomplete'; + + // Remove widget settings; no longer used. + $settings['widget']['settings'] = array(); + + // Change widget to active. + $settings['widget']['active'] = 1; + + // Add missing key. + $settings['default_value_function'] = NULL; + + // Move bundle filtering to instance settings. + $settings['settings']['bundles'] = $bundles; + + return $settings; +} + +/** + * Convert entityreference fields to reference fields. + */ +function reference_update_1000() { + $names = config_get_names_with_prefix('field.instance.'); + foreach ($names as $name) { + // Load field base settings first. + list(, , , , $field_name) = explode('.', $name); + $field_config = config('field.field.' . $field_name); + $field_settings = $field_config->get(); + + if ($field_settings['type'] == 'entityreference') { + $config = config($name); + $settings = $config->get(); + $settings = _reference_install_update_field_instance_settings($settings, $field_settings['settings']['handler_settings']['target_bundles']); + + // Set field formatter. + $settings['display']['default']['module'] = 'reference'; + switch ($settings['display']['default']['type']) { + case 'entityreference_entity_view': + $settings['display']['default']['type'] = 'reference_rendered'; + $settings['display']['default']['settings'] = array( + 'view_mode' => isset($settings['display']['default']['settings']['view_mode']) ? $settings['display']['default']['settings']['view_mode'] : 'full', + ); + break; + + case 'entityreference_label': + case 'entityreference_entity_id': + default: + // If custom formatter is used, reset to default formatter. + $settings['display']['default']['type'] = 'reference_link'; + $settings['display']['default']['settings'] = array(); + } + + // Before saving, convert field base (we first had to move some old + // field base settings into the instance settings). + $field_settings = _reference_install_update_field_base_settings($field_settings, $field_settings['settings']['target_type']); + $field_config->setData($field_settings); + $field_config->save(); + + // Now save field instance settings. + $config->setData($settings); + $config->save(); + } + } + + // Clear caches to ensure updated fields are loaded. + /* @todo Invoking field_cache_clear() doesn't refresh fields in UI. */ + field_cache_clear(); +} + +/** + * Helper function to update field instance settings. + */ +function _reference_install_change_field($field_name, $field_name_old) { + if (db_table_exists('field_data_' . $field_name)) { + $spec = array( + 'description' => 'The entity id of the target entity.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + ); + $indexes = array( + 'indexes' => array( + $field_name . '_target_id' => array($field_name . '_target_id'), + ), + ); + db_drop_index('field_data_' . $field_name, $field_name_old); + db_change_field('field_data_' . $field_name, $field_name_old, $field_name . '_target_id', $spec, $indexes); + db_drop_index('field_data_' . $field_name, $field_name_old); + db_change_field('field_revision_' . $field_name, $field_name_old, $field_name . '_target_id', $spec, $indexes); + } +} + +/** + * Convert references fields to reference fields. + */ +function reference_update_1001(&$sandbox) { + if (!isset($sandbox['progress'])) { + $sandbox['progress'] = 0; + $sandbox['names'] = config_get_names_with_prefix('field.instance.'); + $sandbox['current_index'] = 0; + $sandbox['max'] = count($sandbox['names']); + } + + $name = $sandbox['names'][$sandbox['current_index']]; + + // Load field base settings first. + list(, , , , $field_name) = explode('.', $name); + $field_config = config('field.field.' . $field_name); + $field_settings = $field_config->get(); + + if ($field_settings['type'] == 'node_reference') { + $config = config($name); + $settings = $config->get(); + + $bundles = $field_settings['settings']['referenceable_types']; + $settings = _reference_install_update_field_instance_settings($settings, $bundles); + + // Set field formatter. + $settings['display']['default']['module'] = 'reference'; + switch ($settings['display']['default']['type']) { + case 'node_reference_node': + $settings['display']['default']['type'] = 'reference_rendered'; + $settings['display']['default']['settings'] = array( + 'view_mode' => isset($settings['display']['default']['settings']['node_reference_view_mode']) ? $settings['display']['default']['settings']['node_reference_view_mode'] : 'full', + ); + break; + + case 'node_reference_default': + case 'node_reference_plain': + case 'node_reference_nid': + case 'node_reference_path': + default: + // If custom formatter is used, reset to default formatter. + $settings['display']['default']['type'] = 'reference_link'; + $settings['display']['default']['settings'] = array(); + } + + // Before saving, convert field base (we first had to move some old + // field base settings into the instance settings). + $field_settings = _reference_install_update_field_base_settings($field_settings, 'node'); + $field_config->setData($field_settings); + $field_config->save(); + + // Now save field instance settings. + $config->setData($settings); + $config->save(); + + // Updated db field name. + _reference_install_change_field($field_settings['field_name'], $field_settings['field_name'] . '_nid'); + } + elseif ($field_settings['type'] == 'user_reference') { + $config = config($name); + $settings = $config->get(); + + // User entities don't use bundles. + $bundles = array(); + $settings = _reference_install_update_field_instance_settings($settings, $bundles); + + // Set field formatter. + $settings['display']['default']['module'] = 'reference'; + switch ($settings['display']['default']['type']) { + case 'user_reference_user': + $settings['display']['default']['type'] = 'reference_rendered'; + $settings['display']['default']['settings'] = array( + 'view_mode' => isset($settings['display']['default']['settings']['node_reference_view_mode']) ? $settings['display']['default']['settings']['node_reference_view_mode'] : 'full', + ); + break; + + case 'user_reference_default': + case 'user_reference_plain': + case 'user_reference_uid': + case 'user_reference_path': + default: + // If custom formatter is used, reset to default formatter. + $settings['display']['default']['type'] = 'reference_link'; + $settings['display']['default']['settings'] = array(); + } + + // Before saving, convert field base (we first had to move some old + // field base settings into the instance settings). + $field_settings = _reference_install_update_field_base_settings($field_settings, 'user'); + $field_config->setData($field_settings); + $field_config->save(); + + // Now save field instance settings. + $config->setData($settings); + $config->save(); + + // Updated db field name. + _reference_install_change_field($field_settings['field_name'], $field_settings['field_name'] . '_uid'); + } + elseif ($field_settings['type'] == 'taxonomy_term_reference') { + $config = config($name); + $settings = $config->get(); + + $bundles = array(); + if (!empty($field_settings['settings']['allowed_values'][0]['vocabulary'])) { + $bundle = $field_settings['settings']['allowed_values'][0]['vocabulary']; + $bundles[$bundle] = $bundle; + } + $settings = _reference_install_update_field_instance_settings($settings, $bundles); + + // Set field formatter. + $settings['display']['default']['module'] = 'reference'; + + // If custom formatter is used, reset to default formatter. + $settings['display']['default']['type'] = 'reference_link'; + $settings['display']['default']['settings'] = array(); + + // Before saving, convert field base (we first had to move some old + // field base settings into the instance settings). + $field_settings = _reference_install_update_field_base_settings($field_settings, 'taxonomy_term'); + $field_config->setData($field_settings); + $field_config->save(); + + // Now save field instance settings. + $config->setData($settings); + $config->save(); + + // Updated db field name. + _reference_install_change_field($field_settings['field_name'], $field_settings['field_name'] . '_tid'); + } + + $sandbox['current_index']++; + $sandbox['progress']++; + + if ($sandbox['progress'] < $sandbox['max']) { + $sandbox['#finished'] = $sandbox['progress'] / $sandbox['max']; + } + else { + $sandbox['#finished'] = 1; + + // Clear caches to ensure updated fields are loaded. + /* @todo Invoking field_cache_clear() doesn't refresh fields in UI. */ + field_cache_clear(); + } +}