From 2441750bd141699a3c0646d38b357401052509b2 Mon Sep 17 00:00:00 2001 From: Bala Bosch Date: Tue, 6 Mar 2018 00:31:31 -0500 Subject: [PATCH 1/6] Added funcationality to convert drupal 7 entityreference fields to backdrop reference fields. --- reference.install | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/reference.install b/reference.install index 90961f6..9c3edf3 100644 --- a/reference.install +++ b/reference.install @@ -23,3 +23,81 @@ function reference_field_schema($field) { ), ); } + +/** + * Implements hook_install(). + * + * Convert entityreference fields to reference fields. + */ +function reference_install() { + $names = config_get_names_with_prefix('field.instance.'); + foreach ($names as $name) { + $config = config($name); + $settings = $config->get(); + + // 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['module'] == 'entityreference') { + // 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(); + + // Add missing key. + $settings['default_value_function'] = NULL; + + // Move bundle filtering to instance settings. + $settings['settings']['bundles'] = $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). + list(, , , , $field_name) = explode('.', $name); + $field_config = config('field.field.' . $field_name); + $field_settings = $field_config->get(); + + $field_settings['module'] = 'reference'; + $field_settings['type'] = 'reference'; + + // Discard all settings except target entity type. + $field_settings['settings'] = array( + 'entity_type' => $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. + field_cache_clear(); +} From 4b1f5c7f341db43b8bfe015d93b54c527c17eec6 Mon Sep 17 00:00:00 2001 From: Bala Bosch Date: Tue, 6 Mar 2018 00:55:10 -0500 Subject: [PATCH 2/6] Moved conversion of entityreference fields to update function. --- reference.install | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/reference.install b/reference.install index 9c3edf3..524a3a2 100644 --- a/reference.install +++ b/reference.install @@ -26,10 +26,16 @@ function reference_field_schema($field) { /** * Implements hook_install(). - * - * Convert entityreference fields to reference fields. */ function reference_install() { + // Reset schema version, so update hooks can be processed after installation. + backdrop_set_installed_schema_version('reference', '0'); +} + +/** + * Convert entityreference fields to reference fields. + */ +function reference_update_1000() { $names = config_get_names_with_prefix('field.instance.'); foreach ($names as $name) { $config = config($name); From 9ef9af63b6040ff4c03a199fca02df27d4a29997 Mon Sep 17 00:00:00 2001 From: Bala Bosch Date: Tue, 6 Mar 2018 12:32:08 -0500 Subject: [PATCH 3/6] Added conversion of backdrop references fields to reference fields. --- reference.install | 219 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 192 insertions(+), 27 deletions(-) diff --git a/reference.install b/reference.install index 524a3a2..f7eeb26 100644 --- a/reference.install +++ b/reference.install @@ -32,49 +32,194 @@ function reference_install() { 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) { - $config = config($name); - $settings = $config->get(); + // 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() { + $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['module'] == 'entityreference') { - // Convert field instance. - $settings['widget']['module'] = 'reference'; + if ($field_settings['type'] == 'node_reference') { + $config = config($name); + $settings = $config->get(); - // Always set widget type to 'reference_autocomplete'; there is no - // 'entityreference_autocomplete_tags' option in reference module. - $settings['widget']['type'] = 'reference_autocomplete'; + $bundles = $field_settings['settings']['referenceable_types']; + $settings = _reference_install_update_field_instance_settings($settings, $bundles); - // Remove widget settings; no longer used. - $settings['widget']['settings'] = array(); + // 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; - // Add missing key. - $settings['default_value_function'] = NULL; + 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(); + } - // Move bundle filtering to instance settings. - $settings['settings']['bundles'] = $field_settings['settings']['handler_settings']['target_bundles']; + // 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 'entityreference_entity_view': + case 'user_reference_user': $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', + 'view_mode' => isset($settings['display']['default']['settings']['node_reference_view_mode']) ? $settings['display']['default']['settings']['node_reference_view_mode'] : 'full', ); break; - case 'entityreference_label': - case 'entityreference_entity_id': + 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'; @@ -83,27 +228,47 @@ function reference_update_1000() { // Before saving, convert field base (we first had to move some old // field base settings into the instance settings). - list(, , , , $field_name) = explode('.', $name); - $field_config = config('field.field.' . $field_name); - $field_settings = $field_config->get(); + $field_settings = _reference_install_update_field_base_settings($field_settings, 'user'); + $field_config->setData($field_settings); + $field_config->save(); - $field_settings['module'] = 'reference'; - $field_settings['type'] = 'reference'; + // Now save field instance settings. + $config->setData($settings); + $config->save(); - // Discard all settings except target entity type. - $field_settings['settings'] = array( - 'entity_type' => $field_settings['settings']['target_type'], - ); + // 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 = $field_settings['settings']['allowed_values']; + $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, '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'] . '_tid'); } } // Clear caches to ensure updated fields are loaded. + /* @todo Invoking field_cache_clear() doesn't refresh fields in UI. */ field_cache_clear(); } From acfa155ef77fb8109ca30e07d1a05347b0eede08 Mon Sep 17 00:00:00 2001 From: Bala Bosch Date: Tue, 6 Mar 2018 22:14:34 -0500 Subject: [PATCH 4/6] Changed references field update function to sue batches. Fixed a bug with taxonomy_term_reference fields. --- reference.install | 223 +++++++++++++++++++++++++--------------------- 1 file changed, 120 insertions(+), 103 deletions(-) diff --git a/reference.install b/reference.install index f7eeb26..1bb1ab6 100644 --- a/reference.install +++ b/reference.install @@ -150,125 +150,142 @@ function _reference_install_change_field($field_name, $field_name_old) { /** * Convert references fields to reference fields. */ -function reference_update_1001() { - $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'] == '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; +function reference_update_1001(&$sandbox) { + /* @todo Turn into batch process. https://www.drupal.org/forum/support/module-development-and-code-questions/2015-07-17/use-batch-api-in-hook_install */ + 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']); + } - 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(); - } + $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(); + // 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(); + // 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'); + // 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(); } - 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; + // 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(); - 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(); - } + // Now save field instance settings. + $config->setData($settings); + $config->save(); - // 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(); + // 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(); - // Now save field instance settings. - $config->setData($settings); - $config->save(); + $bundles = $field_settings['settings']['allowed_values']; + $settings = _reference_install_update_field_instance_settings($settings, $bundles); - // 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(); + // Set field formatter. + $settings['display']['default']['module'] = 'reference'; - $bundles = $field_settings['settings']['allowed_values']; - $settings = _reference_install_update_field_instance_settings($settings, $bundles); + // If custom formatter is used, reset to default formatter. + $settings['display']['default']['type'] = 'reference_link'; + $settings['display']['default']['settings'] = array(); - // Set field formatter. - $settings['display']['default']['module'] = 'reference'; + // 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(); - // If custom formatter is used, reset to default formatter. - $settings['display']['default']['type'] = 'reference_link'; - $settings['display']['default']['settings'] = array(); + // Now save field instance settings. + $config->setData($settings); + $config->save(); - // 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(); + // Updated db field name. + _reference_install_change_field($field_settings['field_name'], $field_settings['field_name'] . '_tid'); + } - // Now save field instance settings. - $config->setData($settings); - $config->save(); + $sandbox['current_index']++; + $sandbox['progress']++; - // Updated db field name. - _reference_install_change_field($field_settings['field_name'], $field_settings['field_name'] . '_tid'); - } + 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(); + // Clear caches to ensure updated fields are loaded. + /* @todo Invoking field_cache_clear() doesn't refresh fields in UI. */ + field_cache_clear(); + } } From 8d3860f3dcde630b099aaa938d7c09bf31d4e482 Mon Sep 17 00:00:00 2001 From: Bala Bosch Date: Wed, 7 Mar 2018 21:12:37 -0500 Subject: [PATCH 5/6] Fixed typo with taxonomy_term_reference field conversion. --- reference.install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference.install b/reference.install index 1bb1ab6..87868c6 100644 --- a/reference.install +++ b/reference.install @@ -263,7 +263,7 @@ function reference_update_1001(&$sandbox) { // 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_settings = _reference_install_update_field_base_settings($field_settings, 'taxonomy_term'); $field_config->setData($field_settings); $field_config->save(); From 605e9a0908eebb9c2457370c373c03efe795ce78 Mon Sep 17 00:00:00 2001 From: Bala Bosch Date: Mon, 12 Mar 2018 14:45:04 -0400 Subject: [PATCH 6/6] Fixed bug with taxonomy_term_reference loosing restrict setting. --- reference.install | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/reference.install b/reference.install index 87868c6..4cbc43d 100644 --- a/reference.install +++ b/reference.install @@ -151,7 +151,6 @@ function _reference_install_change_field($field_name, $field_name_old) { * Convert references fields to reference fields. */ function reference_update_1001(&$sandbox) { - /* @todo Turn into batch process. https://www.drupal.org/forum/support/module-development-and-code-questions/2015-07-17/use-batch-api-in-hook_install */ if (!isset($sandbox['progress'])) { $sandbox['progress'] = 0; $sandbox['names'] = config_get_names_with_prefix('field.instance.'); @@ -251,7 +250,11 @@ function reference_update_1001(&$sandbox) { $config = config($name); $settings = $config->get(); - $bundles = $field_settings['settings']['allowed_values']; + $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.