Issue #2031707 by andypost, larowlan: Fixed field_sync_field_status() does not enable fields defined without hook_field_info().

8.0.x
Nathaniel Catchpole 2013-07-02 11:22:09 +01:00
parent ffa96ebf6d
commit 1fcea0a54b
2 changed files with 128 additions and 10 deletions

View File

@ -199,7 +199,7 @@ function field_cron() {
*/ */
function field_system_info_alter(&$info, $file, $type) { function field_system_info_alter(&$info, $file, $type) {
// It is not safe to call field_read_fields() during maintenance mode. // 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)); $fields = field_read_fields(array('module' => $file->name), array('include_deleted' => TRUE));
if ($fields) { if ($fields) {
$info['required'] = TRUE; $info['required'] = TRUE;
@ -419,18 +419,11 @@ function field_sync_field_status() {
$changed = array(); $changed = array();
$modules = $module_handler->getModuleList(); $modules = $module_handler->getModuleList();
foreach ($modules as $module => $module_info) { foreach ($modules as $module => $module_info) {
// Collect field types and storage backends exposed by the module. // Collect storage backends exposed by the module.
$field_types = (array) $module_handler->invoke($module, 'field_info');
$storage_types = (array) $module_handler->invoke($module, 'field_storage_info'); $storage_types = (array) $module_handler->invoke($module, 'field_storage_info');
if ($field_types || $storage_types) { if ($storage_types) {
foreach ($fields as $uuid => &$field) { 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. // Associate storage backends.
if (isset($storage_types[$field['storage']['type']]) && ($field['storage']['module'] !== $module || !$field['storage']['active'])) { if (isset($storage_types[$field['storage']['type']]) && ($field['storage']['module'] !== $module || !$field['storage']['active'])) {
$field['storage']['module'] = $module; $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. // Set fields with missing field type or storage modules to inactive.
foreach ($fields as $uuid => &$field) { 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']) { if (!isset($modules[$field['module']]) && $field['active']) {
$field['active'] = FALSE; $field['active'] = FALSE;
$changed[$uuid] = $field; $changed[$uuid] = $field;
} }
// Disassociate storage backends.
if (!isset($modules[$field['storage']['module']]) && $field['storage']['active']) { if (!isset($modules[$field['storage']['module']]) && $field['storage']['active']) {
$field['storage']['active'] = FALSE; $field['storage']['active'] = FALSE;
$changed[$uuid] = $field; $changed[$uuid] = $field;

View File

@ -0,0 +1,117 @@
<?php
/**
* @file
* Contains \Drupal\field\reEnableModuleFieldTest.
*/
namespace Drupal\field\Tests;
use Drupal\simpletest\WebTestBase;
/**
* Tests a field is still present after it's module is disabled then re-enabled.
*/
class reEnableModuleFieldTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array(
'field',
'field_sql_storage',
'node',
// We use telephone module instead of test_field because test_field is
// hidden and does not display on the admin/modules page.
'telephone'
);
public static function getInfo() {
return array(
'name' => '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('<a href="tel:123456789">');
// 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');
}
}