From 1fcea0a54b480012e24cdbd11023af6108d81356 Mon Sep 17 00:00:00 2001 From: Nathaniel Catchpole Date: Tue, 2 Jul 2013 11:22:09 +0100 Subject: [PATCH] Issue #2031707 by andypost, larowlan: Fixed field_sync_field_status() does not enable fields defined without hook_field_info(). --- core/modules/field/field.module | 21 ++-- .../field/Tests/reEnableModuleFieldTest.php | 117 ++++++++++++++++++ 2 files changed, 128 insertions(+), 10 deletions(-) create mode 100644 core/modules/field/lib/Drupal/field/Tests/reEnableModuleFieldTest.php diff --git a/core/modules/field/field.module b/core/modules/field/field.module index ad1147818ca..7a18b9e673c 100644 --- a/core/modules/field/field.module +++ b/core/modules/field/field.module @@ -199,7 +199,7 @@ function field_cron() { */ function field_system_info_alter(&$info, $file, $type) { // It is not safe to call field_read_fields() during maintenance mode. - if ($type == 'module' && module_hook($file->name, 'field_info') && !defined('MAINTENANCE_MODE')) { + if ($type == 'module' && !defined('MAINTENANCE_MODE')) { $fields = field_read_fields(array('module' => $file->name), array('include_deleted' => TRUE)); if ($fields) { $info['required'] = TRUE; @@ -419,18 +419,11 @@ function field_sync_field_status() { $changed = array(); $modules = $module_handler->getModuleList(); foreach ($modules as $module => $module_info) { - // Collect field types and storage backends exposed by the module. - $field_types = (array) $module_handler->invoke($module, 'field_info'); + // Collect storage backends exposed by the module. $storage_types = (array) $module_handler->invoke($module, 'field_storage_info'); - if ($field_types || $storage_types) { + if ($storage_types) { foreach ($fields as $uuid => &$field) { - // Associate field types. - if (isset($field_types[$field['type']]) && ($field['module'] !== $module || !$field['active'])) { - $field['module'] = $module; - $field['active'] = TRUE; - $changed[$uuid] = $field; - } // Associate storage backends. if (isset($storage_types[$field['storage']['type']]) && ($field['storage']['module'] !== $module || !$field['storage']['active'])) { $field['storage']['module'] = $module; @@ -441,12 +434,20 @@ function field_sync_field_status() { } } + $field_types = Drupal::service('plugin.manager.entity.field.field_type')->getDefinitions(); // Set fields with missing field type or storage modules to inactive. foreach ($fields as $uuid => &$field) { + // Associate field types. + if (isset($field_types[$field['type']]) && ($field['module'] != $field_types[$field['type']]['module'] || !$field['active'])) { + $field['module'] = $field_types[$field['type']]['module']; + $field['active'] = TRUE; + $changed[$uuid] = $field; + } if (!isset($modules[$field['module']]) && $field['active']) { $field['active'] = FALSE; $changed[$uuid] = $field; } + // Disassociate storage backends. if (!isset($modules[$field['storage']['module']]) && $field['storage']['active']) { $field['storage']['active'] = FALSE; $changed[$uuid] = $field; diff --git a/core/modules/field/lib/Drupal/field/Tests/reEnableModuleFieldTest.php b/core/modules/field/lib/Drupal/field/Tests/reEnableModuleFieldTest.php new file mode 100644 index 00000000000..6d4ed4ada52 --- /dev/null +++ b/core/modules/field/lib/Drupal/field/Tests/reEnableModuleFieldTest.php @@ -0,0 +1,117 @@ + 'Test field module re-enable', + 'description' => "Test the behavior of a field module after being disabled and re-enabled.", + 'group' => 'Field types' + ); + } + + function setUp() { + parent::setUp(); + + $this->drupalCreateContentType(array('type' => 'article')); + $this->article_creator = $this->drupalCreateUser(array('create article content', 'edit own article content')); + $this->drupalLogin($this->article_creator); + } + + /** + * Test the behavior of a field module after being disabled and re-enabled. + */ + function testReEnabledField() { + + // Add a telephone field to the article content type. + $field = entity_create('field_entity', array( + 'field_name' => 'field_telephone', + 'type' => 'telephone', + )); + $field->save(); + entity_create('field_instance', array( + 'field_name' => 'field_telephone', + 'label' => 'Telephone Number', + 'entity_type' => 'node', + 'bundle' => 'article', + ))->save(); + + entity_get_form_display('node', 'article', 'default') + ->setComponent('field_telephone', array( + 'type' => 'telephone_default', + 'settings' => array( + 'placeholder' => '123-456-7890', + ), + )) + ->save(); + + entity_get_display('node', 'article', 'default') + ->setComponent('field_telephone', array( + 'type' => 'telephone_link', + 'weight' => 1, + )) + ->save(); + + // Display the article node form and verify the telephone widget is present. + $this->drupalGet('node/add/article'); + $this->assertFieldByName("field_telephone[und][0][value]", '', 'Widget found.'); + + // Submit an article node with a telephone field so data exist for the + // field. + $edit = array( + "title" => $this->randomName(), + "field_telephone[und][0][value]" => "123456789", + ); + $this->drupalPost(NULL, $edit, t('Save')); + $this->assertRaw(''); + + // Disable the telephone module and re-enable it. + module_disable(array('telephone')); + module_enable(array('telephone')); + + // Display the article creation form and verify the widget still exists. + $this->drupalGet('node/add/article'); + $this->assertFieldByName("field_telephone[und][0][value]", '', 'Widget found.'); + + // Test that the module can't be disabled from the UI while there is data + // for it's fields. + $admin_user = $this->drupalCreateUser(array('access administration pages', 'administer modules')); + $this->drupalLogin($admin_user); + $this->drupalGet('admin/modules'); + $this->assertText('Fields type(s) in use'); + $field->delete(); + $this->drupalGet('admin/modules'); + $this->assertText('Fields pending deletion'); + $this->cronRun(); + $this->assertNoText('Fields type(s) in use'); + $this->assertNoText('Fields pending deletion'); + + } + +}