diff --git a/reference.install b/reference.install index 90961f6..aa06301 100644 --- a/reference.install +++ b/reference.install @@ -23,3 +23,207 @@ 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; +} + +/** + * 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_1000(&$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']]; + + $convert = FALSE; + $message = t('No references fields have been converted to reference fields in this update.'); + + if (substr($schema_version, 0, 1) == 7) { + // Upgrading from Drupal 7, convert fields. + $convert = TRUE; + } + elseif (substr($schema_version, 0, 1) == 1) { + // Upgrading from Previous Backdrop version of entityreference module. + $convert = settings_get('reference_convert_references', FALSE); + } + + if ($convert) { + // 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'); + } + + $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(); + + $message = t(':count references have been converted to reference fields in this update.', array(':count' => $sandbox['max'])); + $return = $message; + } +}