diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php index 566b2cc..7681bd4 100644 --- a/core/lib/Drupal/Core/Entity/EntityManager.php +++ b/core/lib/Drupal/Core/Entity/EntityManager.php @@ -194,7 +194,7 @@ public function processDefinition(&$definition, $plugin_id) { // Prepare entity schema fields SQL info for // Drupal\Core\Entity\DatabaseStorageControllerInterface::buildQuery(). - if (isset($definition['base_table'])) { + if (isset($definition['base_table']) && drupal_get_schema($definition['base_table']) !== FALSE) { $definition['schema_fields_sql']['base_table'] = drupal_schema_fields_sql($definition['base_table']); if (isset($definition['data_table'])) { $definition['schema_fields_sql']['data_table'] = drupal_schema_fields_sql($definition['data_table']); diff --git a/core/modules/block/custom_block/custom_block.module b/core/modules/block/custom_block/custom_block.module index 83117c8..7111990 100644 --- a/core/modules/block/custom_block/custom_block.module +++ b/core/modules/block/custom_block/custom_block.module @@ -252,7 +252,7 @@ function custom_block_add_body_field($block_type_id, $label = 'Block body') { 'entity_type' => 'custom_block', 'bundle' => $block_type_id, 'label' => $label, - 'widget' => array('type' => 'text_textarea_with_summary'), + 'widget_settings' => array('type' => 'text_textarea_with_summary'), 'settings' => array('display_summary' => FALSE), ); $instance = field_create_instance($instance); diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockTest.php index 27dbfa1..1069273 100644 --- a/core/modules/block/lib/Drupal/block/Tests/BlockTest.php +++ b/core/modules/block/lib/Drupal/block/Tests/BlockTest.php @@ -278,7 +278,7 @@ function testBlock() { // Check to see if the block was created by checking its configuration. $instance = entity_load('block', $block['theme'] . '.' . $block['machine_name']); - $this->assertEqual($instance->label(), $block['label'], 'Stored block title found.'); + $this->assertEqual($instance['label'](), $block['label'], 'Stored block title found.'); // Check whether the block can be moved to all available regions. foreach ($this->regions as $region) { diff --git a/core/modules/comment/comment.install b/core/modules/comment/comment.install index 48bb5a4..2c6d416 100644 --- a/core/modules/comment/comment.install +++ b/core/modules/comment/comment.install @@ -16,7 +16,7 @@ function comment_uninstall() { variable_del('comment_block_count'); $node_types = array_keys(node_type_get_types()); foreach ($node_types as $node_type) { - field_attach_delete_bundle('comment', 'comment_node_' . $node_type); + field_attach_delete_bundle('comment', 'comment_node_' . $node_type, FALSE); variable_del('comment_' . $node_type); variable_del('comment_anonymous_' . $node_type); variable_del('comment_controls_' . $node_type); diff --git a/core/modules/datetime/datetime.install b/core/modules/datetime/datetime.install index df1ed81..e0362a8 100644 --- a/core/modules/datetime/datetime.install +++ b/core/modules/datetime/datetime.install @@ -21,21 +21,3 @@ function datetime_field_schema($field) { ); return array('columns' => $db_columns, 'indexes' => $indexes); } - -/** - * Install the new to D8 Datetime module. - * - * As part of adding this new module to Drupal 8, the Datetime namespace is now - * reserved for this module. This is a possible conflict with a popular contrib - * field DateTime that existed in D7. Hence, any Datetime fields that may have - * existed prior to D8 need to renamed for later upgrade by contrib modules like - * the Date module. - */ -function datetime_install() { - db_update('field_config') - ->fields(array( - 'type' => 'datetime_old', - )) - ->condition('type', 'datetime') - ->execute(); -} diff --git a/core/modules/datetime/datetime.module b/core/modules/datetime/datetime.module index 79905f8..a7d6958 100644 --- a/core/modules/datetime/datetime.module +++ b/core/modules/datetime/datetime.module @@ -274,7 +274,7 @@ function datetime_default_value($entity, $field, $instance, $langcode) { $value = ''; $date = ''; - if ($instance['settings']['default_value'] == 'now') { + if ($instance['default_value'] == 'now') { // A default value should be in the format and timezone used for date // storage. $date = new DrupalDateTime('now', DATETIME_STORAGE_TIMEZONE); diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php index 57f2bfc..cdfdff4 100644 --- a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php +++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php @@ -12,7 +12,7 @@ use Drupal\Component\Plugin\Discovery\DiscoveryInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\field\Plugin\PluginSettingsBase; -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; use Drupal\Core\Datetime\DrupalDateTime; use Drupal\datetime\DateHelper; diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php index 479c613..997cebf 100644 --- a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php +++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php @@ -12,7 +12,7 @@ use Drupal\Component\Plugin\Discovery\DiscoveryInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\field\Plugin\PluginSettingsBase; -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; use Drupal\Core\Datetime\DrupalDateTime; /** diff --git a/core/modules/datetime/lib/Drupal/datetime/Tests/DateTimeFieldTest.php b/core/modules/datetime/lib/Drupal/datetime/Tests/DateTimeFieldTest.php index 232d019..674a5cf 100644 --- a/core/modules/datetime/lib/Drupal/datetime/Tests/DateTimeFieldTest.php +++ b/core/modules/datetime/lib/Drupal/datetime/Tests/DateTimeFieldTest.php @@ -53,19 +53,19 @@ function setUp() { 'type' => 'datetime', 'settings' => array('datetime_type' => 'date'), ); - field_create_field($this->field); + $this->field = field_create_field($this->field); $this->instance = array( 'field_name' => $this->field['field_name'], 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( + 'widget_settings' => array( 'type' => 'datetime_default', ), 'settings' => array( 'default_value' => 'blank', ), ); - field_create_instance($this->instance); + $this->instance = field_create_instance($this->instance); $this->display_options = array( 'type' => 'datetime_default', @@ -223,8 +223,8 @@ function testDatelistWidget() { $date_order = 'YMD'; $time_type = '12'; - $this->instance['widget']['type'] = 'datetime_datelist'; - $this->instance['widget']['settings'] = array( + $this->instance['widget_settings']['type'] = 'datetime_datelist'; + $this->instance['widget_settings']['settings'] = array( 'increment' => $increment, 'date_order' => $date_order, 'time_type' => $time_type, @@ -285,7 +285,7 @@ function testDefaultValue() { field_update_field($this->field); // Set the default value to 'now'. - $this->instance['settings']['default_value'] = 'now'; + $this->instance['default_value'] = 'now'; $this->instance['default_value_function'] = 'datetime_default_value'; field_update_instance($this->instance); @@ -303,7 +303,7 @@ function testDefaultValue() { $this->assertNoFieldByName("{$this->field['field_name']}[$langcode][0][value][time]", '', 'Time element found.'); // Set the default value to 'blank'. - $this->instance['settings']['default_value'] = 'blank'; + $this->instance['default_value'] = 'blank'; field_update_instance($this->instance); // Display creation form. diff --git a/core/modules/edit/lib/Drupal/edit/EditorBase.php b/core/modules/edit/lib/Drupal/edit/EditorBase.php index d2e4d09..a0844d1 100644 --- a/core/modules/edit/lib/Drupal/edit/EditorBase.php +++ b/core/modules/edit/lib/Drupal/edit/EditorBase.php @@ -9,7 +9,7 @@ use Drupal\Component\Plugin\PluginBase; use Drupal\edit\EditorInterface; -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; /** * Defines a base editor (Create.js PropertyEditor widget) implementation. diff --git a/core/modules/edit/lib/Drupal/edit/EditorInterface.php b/core/modules/edit/lib/Drupal/edit/EditorInterface.php index 251233a..df4c7f9 100644 --- a/core/modules/edit/lib/Drupal/edit/EditorInterface.php +++ b/core/modules/edit/lib/Drupal/edit/EditorInterface.php @@ -8,7 +8,7 @@ namespace Drupal\edit; use Drupal\Component\Plugin\PluginInspectionInterface; -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; /** * Defines an interface for in-place editors (Create.js PropertyEditor widgets). diff --git a/core/modules/edit/lib/Drupal/edit/EditorSelector.php b/core/modules/edit/lib/Drupal/edit/EditorSelector.php index 131eea2..fe71340 100644 --- a/core/modules/edit/lib/Drupal/edit/EditorSelector.php +++ b/core/modules/edit/lib/Drupal/edit/EditorSelector.php @@ -9,7 +9,7 @@ use Drupal\Component\Plugin\PluginManagerInterface; use Drupal\Component\Utility\NestedArray; -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; /** * Selects an in-place editor (an Editor plugin) for a field. diff --git a/core/modules/edit/lib/Drupal/edit/EditorSelectorInterface.php b/core/modules/edit/lib/Drupal/edit/EditorSelectorInterface.php index 2c180cd..926c7a6 100644 --- a/core/modules/edit/lib/Drupal/edit/EditorSelectorInterface.php +++ b/core/modules/edit/lib/Drupal/edit/EditorSelectorInterface.php @@ -7,7 +7,7 @@ namespace Drupal\edit; -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; /** * Interface for selecting an in-place editor (an Editor plugin) for a field. diff --git a/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php b/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php index 3ec8ce2..3e7dd21 100644 --- a/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php +++ b/core/modules/edit/lib/Drupal/edit/MetadataGenerator.php @@ -9,7 +9,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Component\Plugin\PluginManagerInterface; -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; use Drupal\edit\Access\EditEntityFieldAccessCheckInterface; diff --git a/core/modules/edit/lib/Drupal/edit/MetadataGeneratorInterface.php b/core/modules/edit/lib/Drupal/edit/MetadataGeneratorInterface.php index 2b6b1d8..71e447d 100644 --- a/core/modules/edit/lib/Drupal/edit/MetadataGeneratorInterface.php +++ b/core/modules/edit/lib/Drupal/edit/MetadataGeneratorInterface.php @@ -8,7 +8,7 @@ namespace Drupal\edit; use Drupal\Core\Entity\EntityInterface; -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; /** * Interface for generating in-place editing metadata for an entity field. diff --git a/core/modules/edit/lib/Drupal/edit/Plugin/edit/editor/DirectEditor.php b/core/modules/edit/lib/Drupal/edit/Plugin/edit/editor/DirectEditor.php index 0a386c5..95f75d9 100644 --- a/core/modules/edit/lib/Drupal/edit/Plugin/edit/editor/DirectEditor.php +++ b/core/modules/edit/lib/Drupal/edit/Plugin/edit/editor/DirectEditor.php @@ -9,7 +9,7 @@ use Drupal\edit\EditorBase; use Drupal\Core\Annotation\Plugin; -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; /** * Defines the "direct" Create.js PropertyEditor widget. diff --git a/core/modules/edit/lib/Drupal/edit/Plugin/edit/editor/FormEditor.php b/core/modules/edit/lib/Drupal/edit/Plugin/edit/editor/FormEditor.php index 59e8d67..d1bec24 100644 --- a/core/modules/edit/lib/Drupal/edit/Plugin/edit/editor/FormEditor.php +++ b/core/modules/edit/lib/Drupal/edit/Plugin/edit/editor/FormEditor.php @@ -9,7 +9,7 @@ use Drupal\edit\EditorBase; use Drupal\Core\Annotation\Plugin; -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; /** * Defines the "form" Create.js PropertyEditor widget. diff --git a/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php b/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php index c3a91fb..830b15c 100644 --- a/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php +++ b/core/modules/edit/lib/Drupal/edit/Tests/EditTestBase.php @@ -29,7 +29,6 @@ function setUp() { parent::setUp(); $this->installSchema('system', 'variable'); - $this->installSchema('field', array('field_config', 'field_config_instance')); $this->installSchema('field_test', 'test_entity'); // Set default storage backend. @@ -59,12 +58,12 @@ function setUp() { */ function createFieldWithInstance($field_name, $type, $cardinality, $label, $instance_settings, $widget_type, $widget_settings, $formatter_type, $formatter_settings) { $field = $field_name . '_field'; - $this->$field = array( + $field_definition = array( 'field_name' => $field_name, 'type' => $type, 'cardinality' => $cardinality, ); - $this->$field_name = field_create_field($this->$field); + $this->$field = field_create_field($field_definition); $instance = $field_name . '_instance'; $this->$instance = array( @@ -75,13 +74,13 @@ function createFieldWithInstance($field_name, $type, $cardinality, $label, $inst 'description' => $label, 'weight' => mt_rand(0, 127), 'settings' => $instance_settings, - 'widget' => array( + 'widget_settings' => array( 'type' => $widget_type, 'label' => $label, 'settings' => $widget_settings, ), ); - field_create_instance($this->$instance); + $this->$instance = field_create_instance($this->$instance); entity_get_display('test_entity', 'test_bundle', 'default') ->setComponent($field_name, array( diff --git a/core/modules/edit/tests/modules/lib/Drupal/edit_test/Plugin/edit/editor/WysiwygEditor.php b/core/modules/edit/tests/modules/lib/Drupal/edit_test/Plugin/edit/editor/WysiwygEditor.php index 943848f..50ec9e2 100644 --- a/core/modules/edit/tests/modules/lib/Drupal/edit_test/Plugin/edit/editor/WysiwygEditor.php +++ b/core/modules/edit/tests/modules/lib/Drupal/edit_test/Plugin/edit/editor/WysiwygEditor.php @@ -9,7 +9,7 @@ use Drupal\edit\EditorBase; use Drupal\Core\Annotation\Plugin; -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; /** * Defines the "wysiwyg" Create.js PropertyEditor widget. diff --git a/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php b/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php index c719c97..0aae0e0 100644 --- a/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php +++ b/core/modules/email/lib/Drupal/email/Tests/EmailFieldTest.php @@ -49,12 +49,12 @@ function testEmailField() { 'field_name' => drupal_strtolower($this->randomName()), 'type' => 'email', ); - field_create_field($this->field); + $this->field = field_create_field($this->field); $this->instance = array( 'field_name' => $this->field['field_name'], 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( + 'widget_settings' => array( 'type' => 'email_default', 'settings' => array( 'placeholder' => 'example@example.com', diff --git a/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php b/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php index 3396f89..ca5ad67 100644 --- a/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php +++ b/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php @@ -24,12 +24,6 @@ public static function getInfo() { ); } - protected function setUp() { - parent::setUp(); - - $this->installSchema('field', array('field_config', 'field_config_instance')); - } - /** * Tests basic CRUD operations on EntityDisplay objects. */ diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutocompleteTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutocompleteTest.php index 70961b0..f2633d0 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutocompleteTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutocompleteTest.php @@ -44,7 +44,7 @@ function setUp() { 'field_name' => $this->field_name, 'bundle' => 'article', 'entity_type' => 'node', - 'widget' => array( + 'widget_settings' => array( 'type' => 'options_select', ), 'settings' => array( @@ -57,7 +57,7 @@ function setUp() { ), ), ); - field_create_instance($this->instance); + $this->instance = field_create_instance($this->instance); entity_get_display('node', 'article', 'default') ->setComponent($this->instance['field_name'], array( 'type' => 'entity_reference_label', diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceItemTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceItemTest.php index 8906e4d..70e8fe7 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceItemTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceItemTest.php @@ -52,7 +52,7 @@ public function setUp() { 'entity_type' => 'entity_test', 'field_name' => 'field_test', 'bundle' => 'entity_test', - 'widget' => array( + 'widget_settings' => array( 'type' => 'options_select', ), 'settings' => array( diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionAccessTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionAccessTest.php index cf1c619..cfa678d 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionAccessTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionAccessTest.php @@ -58,7 +58,7 @@ protected function assertReferencable($field, $instance, $tests, $handler_name) */ public function testNodeHandler() { // Build a fake field instance. - $field = array( + $field = entity_create('field_entity', array( 'translatable' => FALSE, 'entity_types' => array(), 'settings' => array( @@ -67,15 +67,15 @@ public function testNodeHandler() { 'field_name' => 'test_field', 'type' => 'entity_reference', 'cardinality' => '1', - ); - $instance = array( + )); + $instance = entity_create('field_instance', array( 'settings' => array( 'handler' => 'default', 'handler_settings' => array( 'target_bundles' => array(), ), ), - ); + )); // Build a set of test data. // Titles contain HTML-special characters to test escaping. @@ -196,7 +196,7 @@ public function testNodeHandler() { */ public function testUserHandler() { // Build a fake field instance. - $field = array( + $field = entity_create('field_entity', array( 'translatable' => FALSE, 'entity_types' => array(), 'settings' => array( @@ -205,15 +205,15 @@ public function testUserHandler() { 'field_name' => 'test_field', 'type' => 'entity_reference', 'cardinality' => '1', - ); - $instance = array( + )); + $instance = entity_create('field_instance', array( 'settings' => array( 'handler' => 'default', 'handler_settings' => array( 'target_bundles' => array(), ), ), - ); + )); // Build a set of test data. $user_values = array( @@ -336,7 +336,7 @@ public function testUserHandler() { */ public function testCommentHandler() { // Build a fake field instance. - $field = array( + $field = entity_create('field_entity', array( 'translatable' => FALSE, 'entity_types' => array(), 'settings' => array( @@ -345,15 +345,15 @@ public function testCommentHandler() { 'field_name' => 'test_field', 'type' => 'entity_reference', 'cardinality' => '1', - ); - $instance = array( + )); + $instance = entity_create('field_instance', array( 'settings' => array( 'handler' => 'default', 'handler_settings' => array( 'target_bundles' => array(), ), ), - ); + )); // Build a set of test data. $node_values = array( diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php index cc768e2..ba6790c 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php @@ -55,7 +55,7 @@ public function testSort() { // Build a fake field instance. - $field = array( + $field = entity_create('field_entity', array( 'translatable' => FALSE, 'entity_types' => array(), 'settings' => array( @@ -64,9 +64,9 @@ public function testSort() { 'field_name' => 'test_field', 'type' => 'entity_reference', 'cardinality' => 1, - ); + )); - $instance = array( + $instance = entity_create('field_instance', array( 'settings' => array( 'handler' => 'default', 'handler_settings' => array( @@ -78,7 +78,7 @@ public function testSort() { ), ), ), - ); + )); // Build a set of test data. $node_values = array( diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/Views/SelectionTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/Views/SelectionTest.php index 6998209..e601121 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/Views/SelectionTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/Views/SelectionTest.php @@ -40,7 +40,7 @@ public function testSelectionHandler() { } // Build a fake field instance. - $field = array( + $field = entity_create('field_entity', array( 'translatable' => FALSE, 'entity_types' => array(), 'settings' => array( @@ -49,8 +49,8 @@ public function testSelectionHandler() { 'field_name' => 'test_field', 'type' => 'entity_reference', 'cardinality' => '1', - ); - $instance = array( + )); + $instance = entity_create('field_instance', array( 'settings' => array( 'handler' => 'views', 'handler_settings' => array( @@ -62,7 +62,7 @@ public function testSelectionHandler() { ), ), ), - ); + )); // Get values from selection handler. $handler = entity_reference_get_selection_handler($field, $instance); diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php index 29112ef..7c0f8b4 100644 --- a/core/modules/field/field.api.php +++ b/core/modules/field/field.api.php @@ -1055,7 +1055,7 @@ function hook_field_attach_delete_revision(\Drupal\Core\Entity\EntityInterface $ */ function hook_field_attach_purge(\Drupal\Core\Entity\EntityInterface $entity, $field, $instance) { // find the corresponding data in mymodule and purge it - if ($entity->entityType() == 'node' && $field->field_name == 'my_field_name') { + if ($entity->entityType() == 'node' && $field['field_name'] == 'my_field_name') { mymodule_remove_mydata($entity->nid); } } diff --git a/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc index 69102f4..455f320 100644 --- a/core/modules/field/field.attach.inc +++ b/core/modules/field/field.attach.inc @@ -1170,7 +1170,7 @@ function field_attach_insert(EntityInterface $entity) { $storages = array(); foreach (field_info_instances($entity->entityType(), $entity->bundle()) as $instance) { $field = field_info_field_by_id($instance['field_id']); - $field_id = $field['id']; + $field_id = $field['uuid']; $field_name = $field['field_name']; if (!empty($entity->$field_name)) { // Collect the storage backend if the field has not been written yet. @@ -1211,7 +1211,7 @@ function field_attach_update(EntityInterface $entity) { $storages = array(); foreach (field_info_instances($entity->entityType(), $entity->bundle()) as $instance) { $field = field_info_field_by_id($instance['field_id']); - $field_id = $field['id']; + $field_id = $field['uuid']; $field_name = $field['field_name']; // Leave the field untouched if $entity comes with no $field_name property, // but empty the field if it comes as a NULL value or an empty array. @@ -1254,7 +1254,7 @@ function field_attach_delete(EntityInterface $entity) { $storages = array(); foreach (field_info_instances($entity->entityType(), $entity->bundle()) as $instance) { $field = field_info_field_by_id($instance['field_id']); - $field_id = $field['id']; + $field_id = $field['uuid']; $storages[$field['storage']['type']][$field_id] = $field_id; } @@ -1287,7 +1287,7 @@ function field_attach_delete_revision(EntityInterface $entity) { $storages = array(); foreach (field_info_instances($entity->entityType(), $entity->bundle()) as $instance) { $field = field_info_field_by_id($instance['field_id']); - $field_id = $field['id']; + $field_id = $field['uuid']; $storages[$field['storage']['type']][$field_id] = $field_id; } @@ -1549,11 +1549,17 @@ function field_attach_create_bundle($entity_type, $bundle) { * The new name of the bundle. */ function field_attach_rename_bundle($entity_type, $bundle_old, $bundle_new) { - db_update('field_config_instance') - ->fields(array('bundle' => $bundle_new)) - ->condition('entity_type', $entity_type) - ->condition('bundle', $bundle_old) - ->execute(); + $instances = field_read_instances(); + foreach ($instances as $id => $instance) { + if ($instance['entity_type'] == $entity_type && $instance['bundle'] == $bundle_old) { + $new_instance_id = $instance['entity_type'] . '.' . $bundle_new . '.' . $instance['field_name']; + config('field.instance.' . $instance['entity_type'] . '.' . $bundle_old . '.' . $instance['field_name'])->rename('field.instance.' . $new_instance_id); + config('field.instance.' . $instance['entity_type'] . '.' . $bundle_new . '.' . $instance['field_name']) + ->set('bundle', $bundle_new) + ->set('id', $new_instance_id) + ->save(); + } + } // Clear the cache. field_cache_clear(); @@ -1569,7 +1575,7 @@ function field_attach_rename_bundle($entity_type, $bundle_old, $bundle_new) { } /** - * Notifies field.module the a bundle was deleted. + * Notifies field.module that a bundle was deleted. * * This deletes the data for the field instances as well as the field instances * themselves. This function actually just marks the data and field instances as @@ -1582,14 +1588,18 @@ function field_attach_rename_bundle($entity_type, $bundle_old, $bundle_new) { * The entity type to which the bundle is bound. * @param $bundle * The bundle to delete. + * @param $field_cleanup + * If TRUE, the field will be deleted as well if its last instance is being + * deleted. If FALSE, it is the caller's responsibility to handle the case of + * fields left without instances. Defaults to TRUE. */ -function field_attach_delete_bundle($entity_type, $bundle) { +function field_attach_delete_bundle($entity_type, $bundle, $field_cleanup = TRUE) { // First, delete the instances themselves. field_read_instances() must be // used here since field_info_instances() does not return instances for // disabled entity types or bundles. $instances = field_read_instances(array('entity_type' => $entity_type, 'bundle' => $bundle), array('include_inactive' => 1)); foreach ($instances as $instance) { - field_delete_instance($instance); + field_delete_instance($instance, $field_cleanup); } // Clear the cache. diff --git a/core/modules/field/field.crud.inc b/core/modules/field/field.crud.inc index f6ee8a2..06dd587 100644 --- a/core/modules/field/field.crud.inc +++ b/core/modules/field/field.crud.inc @@ -29,7 +29,7 @@ * field_create_instance() for that. * * @param $field - * A field definition array. The field_name and type properties are required. + * A field definition. The field_name and type properties are required. * Other properties, if omitted, will be given the following default values: * - cardinality: 1 * - locked: FALSE @@ -49,13 +49,20 @@ * hook_field_storage_info(). * * @return - * The $field array with the id property filled in. + * The $field entity. * * @throws Drupal\field\FieldException * * See: @link field Field API data structures @endlink. */ function field_create_field($field) { + + // Module developers can still pass in an array of properties + // into field_create_field(). + if (is_array($field)) { + $field = entity_create('field_entity', $field); + } + // Field name is required. if (empty($field['field_name'])) { throw new FieldException('Attempt to create an unnamed field.'); @@ -81,7 +88,7 @@ function field_create_field($field) { // We do not care about deleted fields. $prior_field = field_read_field($field['field_name'], array('include_inactive' => TRUE)); if (!empty($prior_field)) { - $message = $prior_field['active']? + $message = $prior_field['active'] ? t('Attempt to create field name %name which already exists and is active.', array('%name' => $field['field_name'])): t('Attempt to create field name %name which already exists, although it is inactive.', array('%name' => $field['field_name'])); throw new FieldException($message); @@ -96,16 +103,27 @@ function field_create_field($field) { } } - $field += array( + $defaults = array( 'entity_types' => array(), 'cardinality' => 1, 'translatable' => FALSE, - 'locked' => FALSE, 'settings' => array(), - 'storage' => array(), + 'bundles' => array(), + 'entity_types' => array(), + 'locked' => FALSE, 'deleted' => 0, + 'storage' => array(), + 'indexes' => array(), + 'foreign_keys' => array(), ); + // @todo This is set by entity_create right ? + foreach ($defaults as $key => $value) { + if (!isset($field[$key])) { + $field[$key] = $value; + } + } + // Check that the field type is known. $field_type = field_info_field_types($field['type']); if (!$field_type) { @@ -131,6 +149,9 @@ function field_create_field($field) { $field['storage']['settings'] += field_info_storage_settings($field['storage']['type']); $field['storage']['module'] = $storage_type['module']; $field['storage']['active'] = 1; + $field['storage_type'] = $field['storage']['type']; + $field['storage_module'] = $storage_type['module']; + $field['storage_active'] = 1; // Collect storage information. module_load_install($field['module']); $schema = (array) module_invoke($field['module'], 'field_schema', $field); @@ -141,60 +162,34 @@ function field_create_field($field) { throw new FieldException(t('Illegal field type columns.')); } // 'foreign keys' are hardcoded in the field type. - $field['foreign keys'] = $schema['foreign keys']; + $field['foreign_keys'] = $schema['foreign keys']; // 'indexes' can be both hardcoded in the field type, and specified in the // incoming $field definition. - $field += array( - 'indexes' => array(), - ); $field['indexes'] += $schema['indexes']; - // The serialized 'data' column contains everything from $field that does not - // have its own column and is not automatically populated when the field is - // read. - $data = $field; - unset($data['columns'], $data['field_name'], $data['type'], $data['active'], $data['module'], $data['storage_type'], $data['storage_active'], $data['storage_module'], $data['locked'], $data['cardinality'], $data['deleted']); // Additionally, do not save the 'bundles' property populated by // field_info_field(). - unset($data['bundles']); - - $record = array( - 'field_name' => $field['field_name'], - 'type' => $field['type'], - 'module' => $field['module'], - 'active' => $field['active'], - 'storage_type' => $field['storage']['type'], - 'storage_module' => $field['storage']['module'], - 'storage_active' => $field['storage']['active'], - 'locked' => $field['locked'], - 'data' => $data, - 'cardinality' => $field['cardinality'], - 'translatable' => $field['translatable'], - 'deleted' => $field['deleted'], - ); + $field['bundles'] = array(); - // Store the field and get the id back. - drupal_write_record('field_config', $record); - $field['id'] = $record['id']; + // Save the configuration. + $field['id'] = $field['field_name']; + $field->save(); // Invoke hook_field_storage_create_field after the field is // complete (e.g. it has its id). try { - // Invoke hook_field_storage_create_field after - // drupal_write_record() sets the field id. + // Invoke hook_field_storage_create_field. module_invoke($storage_type['module'], 'field_storage_create_field', $field); } catch (Exception $e) { // If storage creation failed, remove the field_config record before // rethrowing the exception. - db_delete('field_config') - ->condition('id', $field['id']) - ->execute(); + entity_delete_multiple('field_entity', array($field['field_name'])); throw $e; } // Clear caches - field_cache_clear(TRUE); + field_cache_clear(); // Invoke external hooks after the cache is cleared for API consistency. module_invoke_all('field_create_field', $field); @@ -224,6 +219,32 @@ function field_create_field($field) { * @see field_create_field() */ function field_update_field($field) { + + // Module developers can still pass in an array of properties + // into field_update_field(). + if (is_array($field)) { + $field_loaded = entity_load('field_entity', $field['field_name']); + if (empty($field_loaded)) { + throw new FieldException('Attempt to update a non-existent field.'); + } + // Override settings + // @todo should we make updating a field completely different ? + foreach ($field as $key => $value) { + if (is_array($value)) { + if ($key == 'indexes') { + $field_loaded[$key] = $value; + } + else { + $field_loaded[$key] += $value; + } + } + else { + $field_loaded[$key] = $value; + } + } + $field = $field_loaded; + } + // Check that the specified field exists. $prior_field = field_read_field($field['field_name']); if (empty($prior_field)) { @@ -231,8 +252,7 @@ function field_update_field($field) { } // Use the prior field values for anything not specifically set by the new - // field to be sure that all values are set. - $field += $prior_field; + // field to be sure that all values are set. // @todo remove ? $field['settings'] += $prior_field['settings']; // Some updates are always disallowed. @@ -255,9 +275,9 @@ function field_update_field($field) { $field['columns'] = $schema['columns']; // 'indexes' can be both hardcoded in the field type, and specified in the // incoming $field definition. - $field += array( - 'indexes' => array(), - ); + if (!isset($field['indexes'])) { + $field['indexes'] = array(); + } $field['indexes'] += $schema['indexes']; $has_data = field_has_data($field); @@ -276,23 +296,15 @@ function field_update_field($field) { // Save the new field definition. @todo: refactor with // field_create_field. - // The serialized 'data' column contains everything from $field that does not - // have its own column and is not automatically populated when the field is - // read. - $data = $field; - unset($data['columns'], $data['field_name'], $data['type'], $data['locked'], $data['module'], $data['cardinality'], $data['active'], $data['deleted']); // Additionally, do not save the 'bundles' property populated by // field_info_field(). - unset($data['bundles']); + $field['bundles'] = array(); - $field['data'] = $data; - - // Store the field and create the id. - $primary_key = array('id'); - drupal_write_record('field_config', $field, $primary_key); + // Save the configuration. + $field->save(); // Clear caches - field_cache_clear(TRUE); + field_cache_clear(); // Invoke external hooks after the cache is cleared for API consistency. module_invoke_all('field_update_field', $field, $prior_field, $has_data); @@ -342,53 +354,38 @@ function field_read_field($field_name, $include_additional = array()) { * field ID, otherwise it is keyed by field name. */ function field_read_fields($params = array(), $include_additional = array()) { - $query = db_select('field_config', 'fc', array('fetch' => PDO::FETCH_ASSOC)); - $query->fields('fc'); - - // Turn the conditions into a query. - foreach ($params as $key => $value) { - // Allow filtering on the 'entity_type' and 'bundle' columns of the - // field_config_instance table. - if ($key == 'entity_type' || $key == 'bundle') { - if (empty($fci_join)) { - $fci_join = $query->join('field_config_instance', 'fci', 'fc.id = fci.field_id'); - } - $key = 'fci.' . $key; - } - else { - $key = 'fc.' . $key; - } + $fields = array(); - $query->condition($key, $value); + // Check if we need to retrieve deleted fields. + $include_deleted = (isset($include_additional['include_deleted']) && $include_additional['include_deleted']) || (isset($params['deleted']) && $params['deleted']); + if ($include_deleted) { + $deleted_fields = state()->get('field.field.deleted') ?: array(); } + // Add active and storage active parameters. if (!isset($include_additional['include_inactive']) || !$include_additional['include_inactive']) { - $query - ->condition('fc.active', 1) - ->condition('fc.storage_active', 1); + $params['active'] = 1; + $params['storage_active'] = 1; } - $include_deleted = (isset($include_additional['include_deleted']) && $include_additional['include_deleted']); - if (!$include_deleted) { - $query->condition('fc.deleted', 0); + + // Get configuration fields. + $config_fields = entity_load_multiple('field_entity'); + + // Merge deleted fields. + if (!empty($deleted_fields)) { + $config_fields += $deleted_fields; } - $fields = array(); - $results = $query->execute(); - foreach ($results as $record) { - $field = unserialize($record['data']); - $field['id'] = $record['id']; - $field['field_name'] = $record['field_name']; - $field['type'] = $record['type']; - $field['module'] = $record['module']; - $field['active'] = $record['active']; - $field['storage']['type'] = $record['storage_type']; - $field['storage']['module'] = $record['storage_module']; - $field['storage']['active'] = $record['storage_active']; - $field['locked'] = $record['locked']; - $field['cardinality'] = $record['cardinality']; - $field['translatable'] = $record['translatable']; - $field['deleted'] = $record['deleted']; + foreach ($config_fields as $field) { + // Conditions. + foreach ($params as $key => $value) { + if ($field[$key] != $value) { + continue 2; + } + } + + // Invoke read field. module_invoke_all('field_read_field', $field); // Populate storage information. @@ -399,7 +396,7 @@ function field_read_fields($params = array(), $include_additional = array()) { $field_name = $field['field_name']; if ($include_deleted) { - $field_name = $field['id']; + $field_name = $field['uuid']; } $fields[$field_name] = $field; } @@ -415,6 +412,7 @@ function field_read_fields($params = array(), $include_additional = array()) { function field_delete_field($field_name) { // Delete all non-deleted instances. $field = field_info_field($field_name); + if (isset($field['bundles'])) { foreach ($field['bundles'] as $entity_type => $bundles) { foreach ($bundles as $bundle) { @@ -427,14 +425,17 @@ function field_delete_field($field_name) { // Mark field data for deletion. module_invoke($field['storage']['module'], 'field_storage_delete_field', $field); - // Mark the field for deletion. - db_update('field_config') - ->fields(array('deleted' => 1)) - ->condition('field_name', $field_name) - ->execute(); + // Delete the configuration of this field and save the field configuration + // in the key_value table so we can use it later during field_purge_batch(). + // This makes sure a new field can be created immediately with the same name. + $deleted_fields = state()->get('field.field.deleted') ?: array(); + $field['deleted'] = TRUE; + $deleted_fields[$field['uuid']] = $field; + state()->set('field.field.deleted', $deleted_fields); + entity_delete_multiple('field_entity', array($field['field_name'])); // Clear the cache. - field_cache_clear(TRUE); + field_cache_clear(); module_invoke_all('field_delete_field', $field); } @@ -474,7 +475,14 @@ function field_delete_field($field_name) { * * See: @link field Field API data structures @endlink. */ -function field_create_instance(&$instance) { +function field_create_instance($instance) { + + // Module developers can still pass in an array of properties + // into field_create_instance(). + if (is_array($instance)) { + $instance = entity_create('field_instance', $instance); + } + $field = field_read_field($instance['field_name']); if (empty($field)) { throw new FieldException(t("Attempt to create an instance of a field @field_name that doesn't exist or is currently inactive.", array('@field_name' => $instance['field_name']))); @@ -492,7 +500,7 @@ function field_create_instance(&$instance) { } // Set the field id. - $instance['field_id'] = $field['id']; + $instance['field_id'] = $field['uuid']; // Note that we do *not* prevent creating a field on non-existing bundles, // because that would break the 'Body as field' upgrade for contrib @@ -542,6 +550,27 @@ function field_create_instance(&$instance) { * @see field_create_instance() */ function field_update_instance($instance) { + + // Module developers can still pass in an array of properties + // into field_update_instance(). + if (is_array($instance)) { + $instance_loaded = entity_load('field_instance', $instance['entity_type'] . '.' . $instance['bundle'] . '.' . $instance['field_name']); + if (empty($instance_loaded)) { + throw new FieldException('Attempt to update a non-existent instance.'); + } + // Override settings + // @todo should we make updating a instance completely different ? + foreach ($instance as $key => $value) { + if (is_array($value)) { + $instance_loaded[$key] += $value; + } + else { + $instance_loaded[$key] = $value; + } + } + $instance = $instance_loaded; + } + // Check that the specified field exists. $field = field_read_field($instance['field_name']); if (empty($field)) { @@ -555,10 +584,7 @@ function field_update_instance($instance) { throw new FieldException(t("Attempt to update an instance of field @field on bundle @bundle that doesn't exist.", array('@field' => $instance['field_name'], '@bundle' => $instance['bundle']))); } - $instance['id'] = $prior_instance['id']; - $instance['field_id'] = $prior_instance['field_id']; - - _field_write_instance($instance, TRUE); + _field_write_instance($instance); // Clear caches. field_cache_clear(); @@ -571,74 +597,51 @@ function field_update_instance($instance) { * * @param $instance * An instance structure. - * @param $update - * Whether this is a new or existing instance. */ -function _field_write_instance(&$instance, $update = FALSE) { +function _field_write_instance($instance) { $field = field_read_field($instance['field_name']); $field_type = field_info_field_types($field['type']); - // Temporary workaround to allow incoming $instance as arrays or classed - // objects. - // @todo remove once the external APIs have been converted to use - // FieldInstance objects. - if (is_object($instance) && get_class($instance) == 'Drupal\field\FieldInstance') { - $instance = $instance->getArray(); - } - // Set defaults. - $instance += array( + $defaults = array( 'settings' => array(), - 'widget' => array(), + 'widget_settings' => array(), 'required' => FALSE, 'label' => $instance['field_name'], 'description' => '', 'deleted' => 0, ); + // @todo check if these are set by entity_create() (I guess so). + foreach ($defaults as $key => $value) { + if (!isset($instance[$key])) { + $instance[$key] = $value; + } + } // Set default instance settings. $instance['settings'] += field_info_instance_settings($field['type']); - // Set default widget and settings. - $instance['widget'] += array( + $instance['widget_settings'] += array( // TODO: what if no 'default_widget' specified ? 'type' => $field_type['default_widget'], 'settings' => array(), ); // If no weight specified, make sure the field sinks at the bottom. - if (!isset($instance['widget']['weight'])) { + if (!isset($instance['widget_settings']['weight'])) { $max_weight = field_info_max_weight($instance['entity_type'], $instance['bundle'], 'form'); - $instance['widget']['weight'] = isset($max_weight) ? $max_weight + 1 : 0; + $instance['widget_settings']['weight'] = isset($max_weight) ? $max_weight + 1 : 0; } // Check widget module. - $widget_type = field_info_widget_types($instance['widget']['type']); - $instance['widget']['module'] = $widget_type['module']; - $instance['widget']['settings'] += field_info_widget_settings($instance['widget']['type']); - - // The serialized 'data' column contains everything from $instance that does - // not have its own column and is not automatically populated when the - // instance is read. - $data = $instance; - unset($data['id'], $data['field_id'], $data['field_name'], $data['entity_type'], $data['bundle'], $data['deleted']); - - $record = array( - 'field_id' => $instance['field_id'], - 'field_name' => $instance['field_name'], - 'entity_type' => $instance['entity_type'], - 'bundle' => $instance['bundle'], - 'data' => $data, - 'deleted' => $instance['deleted'], - ); - // We need to tell drupal_update_record() the primary keys to trigger an - // update. - if ($update) { - $record['id'] = $instance['id']; - drupal_write_record('field_config_instance', $record, array('id')); - } - else { - drupal_write_record('field_config_instance', $record); - $instance['id'] = $record['id']; + $widget_type = field_info_widget_types($instance['widget_settings']['type']); + $instance['widget_settings']['module'] = $widget_type['module']; + $instance['widget_settings']['settings'] += field_info_widget_settings($instance['widget_settings']['type']); + + if (!isset($instance['id'])) { + $instance['id'] = $instance['entity_type'] . '.' . $instance['bundle'] . '.' . $instance['field_name']; } + + // Save into config. + $instance->save(); } /** @@ -673,8 +676,8 @@ function field_read_instance($entity_type, $field_name, $bundle, $include_additi * * @param $param * An array of properties to use in selecting a field instance. Valid keys - * include any column of the field_config_instance table. If NULL, all - * instances will be returned. + * include any property of the instance config object, except for data. + * If NULL, all instances will be returned. * @param $include_additional * The default behavior of this function is to not return field instances that * have been marked deleted, or whose field is inactive. Setting @@ -685,44 +688,66 @@ function field_read_instance($entity_type, $field_name, $bundle, $include_additi * An array of instances matching the arguments. */ function field_read_instances($params = array(), $include_additional = array()) { - $include_inactive = isset($include_additional['include_inactive']) && $include_additional['include_inactive']; - $include_deleted = isset($include_additional['include_deleted']) && $include_additional['include_deleted']; + $instances = array(); - $query = db_select('field_config_instance', 'fci', array('fetch' => PDO::FETCH_ASSOC)); - $query->join('field_config', 'fc', 'fc.id = fci.field_id'); - $query->fields('fci'); + $deleted_fields = state()->get('field.field.deleted'); + $include_inactive = isset($include_additional['include_inactive']) && $include_additional['include_inactive']; + $include_deleted = (isset($include_additional['include_deleted']) && $include_additional['include_deleted']) || (isset($params['deleted']) && $params['deleted']); - // Turn the conditions into a query. - foreach ($params as $key => $value) { - $query->condition('fci.' . $key, $value); + if ($include_deleted) { + $deleted_instances = state()->get('field.instance.deleted') ?: array(); } - if (!$include_inactive) { - $query - ->condition('fc.active', 1) - ->condition('fc.storage_active', 1); - } - if (!$include_deleted) { - $query->condition('fc.deleted', 0); - $query->condition('fci.deleted', 0); + + // Get configuration instances. + $config_instances = entity_load_multiple('field_instance'); + // Merge deleted instances. + if (!empty($deleted_instances)) { + $config_instances += $deleted_instances; } - $instances = array(); - $results = $query->execute(); + foreach ($config_instances as $instance) { + + $entity_info = entity_get_info($instance['entity_type']); + + // Get data from the field. If the field is marked as deleted, we + // need to get it from the state storage. + $field = entity_load('field_entity', $instance['field_name']); + if ($include_deleted) { + if (empty($field) && isset($deleted_fields[$instance['field_id']])) { + $field = $deleted_fields[$instance['field_id']]; + } + } + if (empty($field)) { + continue; + } + + // @todo do we really need this ? + $instance['active'] = $field['active']; + $instance['locked'] = $field['locked']; + $instance['type'] = $field['type']; + $instance['module'] = $field['module']; + $instance['storage_type'] = $field['storage']['type']; + $instance['storage_active'] = $field['storage']['active']; + $instance['storage_module'] = $field['storage']['module']; - foreach ($results as $record) { - // Filter out instances on unknown entity types (for instance because the - // module exposing them was disabled). - $entity_info = entity_get_info($record['entity_type']); if ($include_inactive || $entity_info) { - $instance = unserialize($record['data']); - $instance['id'] = $record['id']; - $instance['field_id'] = $record['field_id']; - $instance['field_name'] = $record['field_name']; - $instance['entity_type'] = $record['entity_type']; - $instance['bundle'] = $record['bundle']; - $instance['deleted'] = $record['deleted']; + // Conditions. + if (!$include_inactive) { + $params['active'] = 1; + $params['storage_active'] = 1; + } + if (!$include_deleted) { + $params['deleted'] = 0; + } + foreach ($params as $key => $value) { + if ($instance[$key] != $value) { + continue 2; + } + } + // Invoke read instance. module_invoke_all('field_read_instance', $instance); + $instances[] = $instance; } } @@ -740,13 +765,14 @@ function field_read_instances($params = array(), $include_additional = array()) * fields left without instances. Defaults to TRUE. */ function field_delete_instance($instance, $field_cleanup = TRUE) { - // Mark the field instance for deletion. - db_update('field_config_instance') - ->fields(array('deleted' => 1)) - ->condition('field_name', $instance['field_name']) - ->condition('entity_type', $instance['entity_type']) - ->condition('bundle', $instance['bundle']) - ->execute(); + + // Delete the configuration of this instance and save the configuration + // in the key_value table so we can use it later during field_purge_batch(). + $deleted_instances = state()->get('field.instance.deleted') ?: array(); + $instance['deleted'] = TRUE; + $deleted_instances[$instance['uuid']] = $instance; + state()->set('field.instance.deleted', $deleted_instances); + entity_delete_multiple('field_instance', array($instance['entity_type'] . '.' . $instance['bundle'] . '.' . $instance['field_name'])); // Clear the cache. field_cache_clear(); @@ -866,7 +892,7 @@ function field_purge_batch($batch_size) { $field = field_info_field_by_id($instance['field_id']); // Retrieve some entities. $query = $factory->get($entity_type) - ->condition('id:' . $field['id'] . '.deleted', 1) + ->condition('id:' . $field['uuid'] . '.deleted', 1) ->range(0, $batch_size); // If there's no bundle key, all results will have the same bundle. if (!empty($info[$entity_type]['entity_keys']['bundle'])) { @@ -884,7 +910,7 @@ function field_purge_batch($batch_size) { $ids->entity_id = $entity_id; $entities[$entity_id] = _field_create_entity_from_ids($ids); } - field_attach_load($entity_type, $entities, FIELD_LOAD_CURRENT, array('field_id' => $field['id'], 'deleted' => 1)); + field_attach_load($entity_type, $entities, FIELD_LOAD_CURRENT, array('field_id' => $field['uuid'], 'deleted' => 1)); foreach ($entities as $entity) { // Purge the data for the entity. field_purge_data($entity, $field, $instance); @@ -897,9 +923,9 @@ function field_purge_batch($batch_size) { } // Retrieve all deleted fields. Any that have no instances can be purged. - $fields = field_read_fields(array('deleted' => 1), array('include_deleted' => 1)); - foreach ($fields as $field) { - $instances = field_read_instances(array('field_id' => $field['id']), array('include_deleted' => 1)); + $deleted_fields = state()->get('field.field.deleted') ?: array(); + foreach ($deleted_fields as $field) { + $instances = field_read_instances(array('field_id' => $field['uuid']), array('include_deleted' => 1)); if (empty($instances)) { field_purge_field($field); } @@ -946,14 +972,14 @@ function field_purge_data(EntityInterface $entity, $field, $instance) { * The instance record to purge. */ function field_purge_instance($instance) { - db_delete('field_config_instance') - ->condition('id', $instance['id']) - ->execute(); - // Notify the storage engine. $field = field_info_field_by_id($instance['field_id']); module_invoke($field['storage']['module'], 'field_storage_purge_instance', $instance); + $deleted_instances = state()->get('field.instance.deleted'); + unset($deleted_instances[$instance['uuid']]); + state()->set('field.instance.deleted', $deleted_instances); + // Clear the cache. field_info_cache_clear(); @@ -971,14 +997,14 @@ function field_purge_instance($instance) { * The field record to purge. */ function field_purge_field($field) { - $instances = field_read_instances(array('field_id' => $field['id']), array('include_deleted' => 1)); + $instances = field_read_instances(array('field_id' => $field['uuid']), array('include_deleted' => 1)); if (count($instances) > 0) { throw new FieldException(t('Attempt to purge a field @field_name that still has instances.', array('@field_name' => $field['field_name']))); } - db_delete('field_config') - ->condition('id', $field['id']) - ->execute(); + $deleted_fields = state()->get('field.field.deleted'); + unset($deleted_fields[$field['uuid']]); + state()->set('field.field.deleted', $deleted_fields); // Notify the storage engine. module_invoke($field['storage']['module'], 'field_storage_purge_field', $field); diff --git a/core/modules/field/field.info b/core/modules/field/field.info index c74da0e..3c6c5fb 100644 --- a/core/modules/field/field.info +++ b/core/modules/field/field.info @@ -3,5 +3,4 @@ description = Field API to add fields to entities like nodes and users. package = Core version = VERSION core = 8.x -dependencies[] = field_sql_storage required = TRUE diff --git a/core/modules/field/field.info.inc b/core/modules/field/field.info.inc index b422b47..a4bc264 100644 --- a/core/modules/field/field.info.inc +++ b/core/modules/field/field.info.inc @@ -5,7 +5,7 @@ * Field Info API, providing information about available fields and field types. */ -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; use Drupal\field\FieldInfo; /** @@ -166,7 +166,7 @@ function _field_info_collate_types_reset() { * - FIELD_BEHAVIOR_DEFAULT: Use field.module default behavior. */ function field_behaviors_widget($op, $instance) { - $info = field_info_widget_types($instance['widget']['type']); + $info = field_info_widget_types($instance['widget_settings']['type']); return isset($info[$op]) ? $info[$op] : FIELD_BEHAVIOR_DEFAULT; } @@ -516,7 +516,7 @@ function field_info_max_weight($entity_type, $bundle) { // Collect weights for fields. foreach (field_info_instances($entity_type, $bundle) as $instance) { - $weights[] = $instance['widget']['weight']; + $weights[] = $instance['widget_settings']['weight']; } // Collect weights for extra fields. foreach (field_info_extra_fields($entity_type, $bundle, 'form') as $extra) { diff --git a/core/modules/field/field.install b/core/modules/field/field.install index 695fd89..6996474 100644 --- a/core/modules/field/field.install +++ b/core/modules/field/field.install @@ -5,162 +5,13 @@ * Install, update, and uninstall functions for the Field module. */ +use Drupal\Component\Uuid\Uuid; + /** * Implements hook_schema(). */ function field_schema() { - // Static (meta) tables. - $schema['field_config'] = array( - 'fields' => array( - 'id' => array( - 'type' => 'serial', - 'not null' => TRUE, - 'description' => 'The primary identifier for a field', - ), - 'field_name' => array( - 'type' => 'varchar', - 'length' => 32, - 'not null' => TRUE, - 'description' => 'The name of this field. Non-deleted field names are unique, but multiple deleted fields can have the same name.', - ), - 'type' => array( - 'type' => 'varchar', - 'length' => 128, - 'not null' => TRUE, - 'description' => 'The type of this field.', - ), - 'module' => array( - 'type' => 'varchar', - 'length' => 128, - 'not null' => TRUE, - 'default' => '', - 'description' => 'The module that implements the field type.', - ), - 'active' => array( - 'type' => 'int', - 'size' => 'tiny', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'Boolean indicating whether the module that implements the field type is enabled.', - ), - 'storage_type' => array( - 'type' => 'varchar', - 'length' => 128, - 'not null' => TRUE, - 'description' => 'The storage backend for the field.', - ), - 'storage_module' => array( - 'type' => 'varchar', - 'length' => 128, - 'not null' => TRUE, - 'default' => '', - 'description' => 'The module that implements the storage backend.', - ), - 'storage_active' => array( - 'type' => 'int', - 'size' => 'tiny', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'Boolean indicating whether the module that implements the storage backend is enabled.', - ), - 'locked' => array( - 'type' => 'int', - 'size' => 'tiny', - 'not null' => TRUE, - 'default' => 0, - 'description' => '@TODO', - ), - 'data' => array( - 'type' => 'blob', - 'size' => 'big', - 'not null' => TRUE, - 'serialize' => TRUE, - 'description' => 'Serialized data containing the field properties that do not warrant a dedicated column.', - ), - 'cardinality' => array( - 'type' => 'int', - 'size' => 'tiny', - 'not null' => TRUE, - 'default' => 0, - ), - 'translatable' => array( - 'type' => 'int', - 'size' => 'tiny', - 'not null' => TRUE, - 'default' => 0, - ), - 'deleted' => array( - 'type' => 'int', - 'size' => 'tiny', - 'not null' => TRUE, - 'default' => 0, - ), - ), - 'primary key' => array('id'), - 'indexes' => array( - 'field_name' => array('field_name'), - // Used by field_read_fields(). - 'active' => array('active'), - 'storage_active' => array('storage_active'), - 'deleted' => array('deleted'), - // Used by field_sync_field_status(). - 'module' => array('module'), - 'storage_module' => array('storage_module'), - 'type' => array('type'), - 'storage_type' => array('storage_type'), - ), - ); - $schema['field_config_instance'] = array( - 'fields' => array( - 'id' => array( - 'type' => 'serial', - 'not null' => TRUE, - 'description' => 'The primary identifier for a field instance', - ), - 'field_id' => array( - 'type' => 'int', - 'not null' => TRUE, - 'description' => 'The identifier of the field attached by this instance', - ), - 'field_name' => array( - 'type' => 'varchar', - 'length' => 32, - 'not null' => TRUE, - 'default' => '' - ), - 'entity_type' => array( - 'type' => 'varchar', - 'length' => 32, - 'not null' => TRUE, - 'default' => '' - ), - 'bundle' => array( - 'type' => 'varchar', - 'length' => 128, - 'not null' => TRUE, - 'default' => '' - ), - 'data' => array( - 'type' => 'blob', - 'size' => 'big', - 'not null' => TRUE, - 'serialize' => TRUE, - ), - 'deleted' => array( - 'type' => 'int', - 'size' => 'tiny', - 'not null' => TRUE, - 'default' => 0, - ), - ), - 'primary key' => array('id'), - 'indexes' => array( - // Used by field_delete_instance(). - 'field_name_bundle' => array('field_name', 'entity_type', 'bundle'), - // Used by field_read_instances(). - 'deleted' => array('deleted'), - ), - ); + $schema['cache_field'] = drupal_get_schema_unprocessed('system', 'cache'); $schema['cache_field']['description'] = 'Cache table for the Field module to store already built field informations.'; @@ -172,7 +23,7 @@ function field_schema() { * * @ingroup update_api */ -function _update_7000_field_create_field(&$field) { +function _update_7000_field_create_field($field) { // Merge in default values.` $field += array( 'entity_types' => array(), @@ -229,12 +80,25 @@ function _update_7000_field_create_field(&$field) { 'deleted' => (int) $field['deleted'], ); // We don't use drupal_write_record() here because it depends on the schema. - $field['id'] = db_insert('field_config') + $record['id'] = db_insert('field_config') ->fields($record) ->execute(); - // Create storage for the field. - field_sql_storage_field_storage_create_field($field); + // Extra keys - @todo clean this up. + $record['settings'] = $data['settings']; + $record['columns'] = $field['columns']; + $record['indexes'] = isset($data['indexes']) ? $data['indexes'] : array(); + if (!isset($record['foreign_keys'])) { + $record['foreign_keys'] = array(); + } + if (isset($data['foreign keys'])) { + $record['foreign_keys'] += $data['foreign keys']; + } + $record['storage'] = $data['storage']; + unset($record['data']); + field_sql_storage_field_storage_create_field((object) $record); + + return $record; } /** @@ -271,7 +135,6 @@ function _update_7000_field_delete_field($field_name) { ->execute(); } - /** * Deletes an instance and all its data of a field stored in SQL Storage. * @@ -382,15 +245,14 @@ function _update_7000_field_create_instance($field, &$instance) { */ /** - * Reassign all list.module fields to be controlled by options.module. + * Implements hook_update_dependencies(). */ -function field_update_8001() { - db_update('field_config') - ->fields(array( - 'module' => 'options', - )) - ->condition('module', 'list') - ->execute(); +function field_update_dependencies() { + // Convert to config after SQL storage has been updated. + $dependencies['field_sql_storage'][8000] = array( + 'field' => 8002, + ); + return $dependencies; } /** @@ -398,7 +260,7 @@ function field_update_8001() { * * @ingroup config_upgrade */ -function field_update_8002() { +function field_update_8001() { $displays = array(); module_load_install('entity'); @@ -442,7 +304,7 @@ function field_update_8002() { // Migration of 'extra_fields' display settings. Avoid calling // entity_get_info() by fetching the relevant variables directly in the - // cariables table. + // variable table. $variables = array_map('unserialize', db_query("SELECT name, value FROM {variable} WHERE name LIKE '%field_bundle_settings_%'")->fetchAllKeyed()); foreach ($variables as $variable_name => $variable_value) { if (preg_match('/field_bundle_settings_(.*)__(.*)/', $variable_name, $matches)) { @@ -484,6 +346,122 @@ function field_update_8002() { } /** + * Convert fields and instances to config. + */ +function field_update_8002() { + $manifest_ids = array('fields' => array(), 'instances' => array()); + + $deleted_fields = state()->get('field.field.deleted') ?: array(); + $deleted_instances = state()->get('field.instance.deleted') ?: array(); + + $field_ids = array(); + $fields = db_query("SELECT * FROM {field_config}")->fetchAll(PDO::FETCH_ASSOC); + foreach ($fields as $field) { + $field['data'] = unserialize($field['data']); + + // Keep old id for the field. + $old_id = $field['id']; + $field['id'] = $field['field_name']; + $field['settings'] = $field['data']['settings']; + + // @todo clean this up. + $field['storage'] = $field['data']['storage']; + if (!isset($field['indexes'])) { + $field['indexes'] = array(); + } + $field['foreign_keys'] = array(); + if (isset($field['data']['foreign keys'])) { + $field['foreign_keys'] += $field['data']['foreign keys']; + } + $schema = (array) module_invoke($field['module'], 'field_schema', (object) $field); + $schema += array('columns' => array(), 'indexes' => array()); + // 'columns' are hardcoded in the field type. + $field['columns'] = $schema['columns']; + // 'indexes' can be both hardcoded in the field type, and specified in the + // incoming $field definition. + $field['indexes'] += $schema['indexes']; + + // Remove data key. + unset($field['data']); + + // Reassign all list.module fields to be controlled by options.module. + if ($field['module'] == 'list') { + $field['module'] = 'options'; + } + + if (!$field['deleted']) { + $uuid = new Uuid(); + $uuid->generate(); + $config = config('field.field.' . $field['field_name']); + foreach ($field as $key => $value) { + $config->set($key, $value); + } + $config->set('uuid', $uuid->generate()); + $config->save(); + $manifest_ids['fields'][] = $field['field_name']; + } + else { + // @todo we actually need to store the entity config object there + // or should we dump the array in deleted fields (and instances below) + // as well and call entity_create() during field_purge_batch(). + $deleted_fields[$e_field['uuid']] = $field; + } + $field_ids[$old_id] = array( + 'id' => $config->get('uuid'), + ); + } + + $instances = db_query("SELECT * FROM {field_config_instance}")->fetchAll(PDO::FETCH_ASSOC); + foreach ($instances as $instance) { + $instance += unserialize($instance['data']); + unset($instance['data']); + + $config_id = $instance['entity_type'] . '.' . $instance['bundle'] . '.' . $instance['field_name']; + $instance['id'] = $config_id; + + // Map old field id to new UUID. + $old_id = $instance['field_id']; + $instance['field_id'] = $field_ids[$old_id]['id']; + + + if (!$instance['deleted']) { + $instance['widget_settings'] = $instance['widget']; + unset($instance['widget']); + $uuid = new Uuid(); + $uuid->generate(); + $config = config('field.instance.' . $config_id); + $config->setData($instance); + $config->set('uuid', $uuid->generate()); + $config->save(); + + $manifest_ids['instances'][] = $config_id; + } + else { + // @todo we actually need to store the entity config object there + // or should we dump the array in deleted instances (and fields above) + // as well and call entity_create() during field_purge_batch(). + $deleted_instances[$instance['uuid']] = $instance; + } + + // Update file_usage table in case this instance has a default image. + if (!empty($instance['settings']['default_image'])) { + db_update('file_usage') + ->fields(array('id' => $instance['field_id'])) + ->condition('fid', $instance['settings']['default_image']) + ->execute(); + } + } + + // Create the manifest files. + update_config_manifest_add('field.field', $manifest_ids['fields']); + update_config_manifest_add('field.instance', $manifest_ids['instances']); + + // Save the deleted fields and instances in state. + state()->set('field.field.deleted', $deleted_fields); + state()->set('field.instance.deleted', $deleted_instances); +} + +/** * @} End of "addtogroup updates-7.x-to-8.x". * The next series of updates should start at 9000. */ diff --git a/core/modules/field/field.module b/core/modules/field/field.module index a52d917..15f267b 100644 --- a/core/modules/field/field.module +++ b/core/modules/field/field.module @@ -334,7 +334,8 @@ function field_cron() { * required if there are any active fields of that type. */ function field_system_info_alter(&$info, $file, $type) { - if ($type == 'module' && module_hook($file->name, 'field_info')) { + // It's not safe to call field_read_fields during maintenance mode. + if ($type == 'module' && module_hook($file->name, 'field_info') && !defined('MAINTENANCE_MODE')) { $fields = field_read_fields(array('module' => $file->name), array('include_deleted' => TRUE)); if ($fields) { $info['required'] = TRUE; @@ -443,7 +444,7 @@ function field_entity_field_info($entity_type) { 'label' => t('Field !name', array('!name' => $field_name)), 'type' => $field['type'] . '_field', 'configurable' => TRUE, - 'translatable' => !empty($field['translatable']) + 'translatable' => !empty($instance['translatable']) ); if ($optional) { @@ -536,23 +537,41 @@ function field_modules_disabled($modules) { } /** - * Refreshes the 'active' and 'storage_active' columns for fields. + * Refreshes the 'active' and 'storage_active' values for fields. */ function field_sync_field_status() { - // Refresh the 'active' and 'storage_active' columns according to the current + + $deleted_fields = state()->get('field.field.deleted') ?: array(); + $fields = field_read_fields(array(), array('include_deleted' => 1 ,'include_inactive' => 1)); + // Refresh the 'active' and 'storage_active' values according to the current // set of enabled modules. $modules = array_keys(drupal_container()->get('module_handler')->getModuleList()); foreach ($modules as $module_name) { - field_associate_fields($module_name); + $fields = field_associate_fields($module_name, $fields); + } + + foreach ($fields as $id => $field) { + if (!in_array($field['module'], $modules)) { + $fields[$id]->active = 0; + } + if (!in_array($field['storage_module'], $modules)) { + $fields[$id]['storage_active'] = 0; + } } - db_update('field_config') - ->fields(array('active' => 0)) - ->condition('module', $modules, 'NOT IN') - ->execute(); - db_update('field_config') - ->fields(array('storage_active' => 0)) - ->condition('storage_module', $modules, 'NOT IN') - ->execute(); + + foreach ($fields as $id => $field) { + if (!$field['deleted']) { + $field->save(); + } + else { + $deleted_fields[$field['uuid']] = $field; + } + } + + // Save the deleted fields. + state()->set('field.field.deleted', $deleted_fields); + + field_cache_clear(); } /** @@ -560,24 +579,37 @@ function field_sync_field_status() { * * @param $module * The name of the module to update on. + * @param $fields + * A collection of fields. */ -function field_associate_fields($module) { +function field_associate_fields($module, $fields) { + // Associate field types. $field_types = (array) module_invoke($module, 'field_info'); + if ($field_types) { - db_update('field_config') - ->fields(array('module' => $module, 'active' => 1)) - ->condition('type', array_keys($field_types)) - ->execute(); + $field_types = array_keys($field_types); + foreach ($fields as $id => $field) { + if (in_array($field['type'], $field_types)) { + $fields[$id]->module = $module; + $fields[$id]->active = TRUE; + } + } } + // Associate storage backends. $storage_types = (array) module_invoke($module, 'field_storage_info'); if ($storage_types) { - db_update('field_config') - ->fields(array('storage_module' => $module, 'storage_active' => 1)) - ->condition('storage_type', array_keys($storage_types)) - ->execute(); + $storage_types = array_keys($storage_types); + foreach ($fields as $id => $field) { + if (in_array($field['storage_type'], $storage_types)) { + $fields[$id]->storage_module = $module; + $fields[$id]->storage_active = TRUE; + } + } } + + return $fields; } /** @@ -1011,7 +1043,7 @@ function field_get_items(EntityInterface $entity, $field_name, $langcode = NULL) * TRUE if the field has data for any entity; FALSE otherwise. */ function field_has_data($field) { - $field = field_info_field_by_id($field['id']); + $field = field_info_field_by_id($field['uuid']); $columns = array_keys($field['columns']); $factory = drupal_container()->get('entity.query'); foreach ($field['bundles'] as $entity_type => $bundle) { diff --git a/core/modules/field/field.multilingual.inc b/core/modules/field/field.multilingual.inc index a9b33ac..1ba6986 100644 --- a/core/modules/field/field.multilingual.inc +++ b/core/modules/field/field.multilingual.inc @@ -28,7 +28,7 @@ * * The available language codes for a particular field are returned by * field_available_languages(). Whether a field is translatable is determined by - * calling field_is_translatable(), which checks the $field['translatable'] + * calling field_is_translatable(), which checks the $instance['translatable'] * property returned by field_info_field(), and whether there is at least one * translation handler available for the field. A translation handler is a * module registering itself via hook_entity_info_alter() to handle field @@ -208,7 +208,10 @@ function field_content_languages() { * TRUE if the field can be translated. */ function field_is_translatable($entity_type, $field) { - return $field['translatable'] && field_has_translation_handler($entity_type); + // See http://drupal.org/node/1862758#comment-7035586 + if (!empty($field)) { + return $field['translatable'] && field_has_translation_handler($entity_type); + } } /** diff --git a/core/modules/field/field.views.inc b/core/modules/field/field.views.inc index 6c769cd..1ba1126 100644 --- a/core/modules/field/field.views.inc +++ b/core/modules/field/field.views.inc @@ -72,8 +72,8 @@ function field_views_field_label($field_name) { foreach ($instances as $entity_name => $entity_type) { foreach ($entity_type as $bundle) { if (isset($bundle[$field_name])) { - $label_counter[$bundle[$field_name]['label']] = isset($label_counter[$bundle[$field_name]['label']]) ? ++$label_counter[$bundle[$field_name]['label']] : 1; - $all_labels[$entity_name][$bundle[$field_name]['label']] = TRUE; + $label_counter[$bundle[$field_name]->label] = isset($label_counter[$bundle[$field_name]->label]) ? ++$label_counter[$bundle[$field_name]->label] : 1; + $all_labels[$entity_name][$bundle[$field_name]->label] = TRUE; } } } @@ -401,7 +401,7 @@ function field_views_field_default_views_data($field) { } // Expose additional language column for translatable fields. - if (!empty($field['translatable'])) { + if (!empty($instance['translatable'])) { $title_language = t('@label (!name:language)', array('@label' => $label, '!name' => $field['field_name'])); $title_short_language = t('@label:language', array('@label' => $label)); diff --git a/core/modules/field/lib/Drupal/field/FieldInfo.php b/core/modules/field/lib/Drupal/field/FieldInfo.php index 7ff6850..289d900 100644 --- a/core/modules/field/lib/Drupal/field/FieldInfo.php +++ b/core/modules/field/lib/Drupal/field/FieldInfo.php @@ -142,17 +142,11 @@ public function getFieldMap() { $map = array(); - $query = db_select('field_config_instance', 'fci'); - $query->join('field_config', 'fc', 'fc.id = fci.field_id'); - $query->fields('fc', array('type')); - $query->fields('fci', array('field_name', 'entity_type', 'bundle')) - ->condition('fc.active', 1) - ->condition('fc.storage_active', 1) - ->condition('fc.deleted', 0) - ->condition('fci.deleted', 0); - foreach ($query->execute() as $row) { - $map[$row->field_name]['bundles'][$row->entity_type][] = $row->bundle; - $map[$row->field_name]['type'] = $row->type; + $instances = field_read_instances(); + foreach ($instances as $key => $instance) { + $map[$instance['field_name']]['bundles'][$instance['entity_type']][] = $instance['bundle']; + // @todo what is this type ?! + $map[$instance['field_name']]['type'] = $instance['type']; } // Save in "static" and persistent caches. @@ -181,7 +175,7 @@ public function getFields() { else { // Collect and prepare fields. foreach (field_read_fields(array(), array('include_deleted' => TRUE)) as $field) { - $this->fieldsById[$field['id']] = $this->prepareField($field); + $this->fieldsById[$field['uuid']] = $this->prepareField($field); } // Store in persistent cache. @@ -191,7 +185,7 @@ public function getFields() { // Fill the name/ID map. foreach ($this->fieldsById as $field) { if (!$field['deleted']) { - $this->fieldIdsByName[$field['field_name']] = $field['id']; + $this->fieldIdsByName[$field['field_name']] = $field['uuid']; } } @@ -229,7 +223,7 @@ public function getInstances($entity_type = NULL) { foreach (field_read_instances() as $instance) { $field = $this->getField($instance['field_name']); $instance = $this->prepareInstance($instance, $field['type']); - $this->bundleInstances[$instance['entity_type']][$instance['bundle']][$instance['field_name']] = new FieldInstance($instance); + $this->bundleInstances[$instance['entity_type']][$instance['bundle']][$instance['field_name']] = $instance; } // Store in persistent cache. @@ -275,8 +269,8 @@ public function getField($field_name) { $field = $this->prepareField($field); // Save in the "static" cache. - $this->fieldsById[$field['id']] = $field; - $this->fieldIdsByName[$field['field_name']] = $field['id']; + $this->fieldsById[$field['uuid']] = $field; + $this->fieldIdsByName[$field['field_name']] = $field['uuid']; return $field; } @@ -309,14 +303,14 @@ public function getFieldById($field_id) { // bundle. // Cache miss: read from definition. - if ($fields = field_read_fields(array('id' => $field_id), array('include_deleted' => TRUE))) { + if ($fields = field_read_fields(array('uuid' => $field_id), array('include_deleted' => TRUE))) { $field = current($fields); $field = $this->prepareField($field); // Store in the static cache. - $this->fieldsById[$field['id']] = $field; + $this->fieldsById[$field['uuid']] = $field; if (!$field['deleted']) { - $this->fieldIdsByName[$field['field_name']] = $field['id']; + $this->fieldIdsByName[$field['field_name']] = $field['uuid']; } return $field; @@ -355,10 +349,10 @@ public function getBundleInstances($entity_type, $bundle) { // Extract the field definitions and save them in the "static" cache. foreach ($info['fields'] as $field) { - if (!isset($this->fieldsById[$field['id']])) { - $this->fieldsById[$field['id']] = $field; + if (!isset($this->fieldsById[$field['uuid']])) { + $this->fieldsById[$field['uuid']] = $field; if (!$field['deleted']) { - $this->fieldIdsByName[$field['field_name']] = $field['id']; + $this->fieldIdsByName[$field['field_name']] = $field['uuid']; } } } @@ -382,7 +376,7 @@ public function getBundleInstances($entity_type, $bundle) { // Collect the fields in the bundle. $params = array('entity_type' => $entity_type, 'bundle' => $bundle); - $fields = field_read_fields($params); + $fields = field_read_fields(); // This iterates on non-deleted instances, so deleted fields are kept out of // the persistent caches. @@ -390,14 +384,14 @@ public function getBundleInstances($entity_type, $bundle) { $field = $fields[$instance['field_name']]; $instance = $this->prepareInstance($instance, $field['type']); - $instances[$field['field_name']] = new FieldInstance($instance); + $instances[$field['field_name']] = $instance; // If the field is not in our global "static" list yet, add it. - if (!isset($this->fieldsById[$field['id']])) { + if (!isset($this->fieldsById[$field['uuid']])) { $field = $this->prepareField($field); - $this->fieldsById[$field['id']] = $field; - $this->fieldIdsByName[$field['field_name']] = $field['id']; + $this->fieldsById[$field['uuid']] = $field; + $this->fieldIdsByName[$field['field_name']] = $field['uuid']; } } @@ -413,6 +407,7 @@ public function getBundleInstances($entity_type, $bundle) { // The persistent cache additionally contains the definitions of the fields // involved in the bundle. + uasort($instances, array($this, '_orderInstances')); $cache = array( 'instances' => $instances, 'fields' => array() @@ -553,4 +548,11 @@ public function prepareExtraFields($extra_fields, $entity_type, $bundle) { return $result; } + + /** + * Helper function to sort the instances on the widget weight. + */ + function _orderInstances($a, $b) { + return ($a->widget_settings['weight'] < $b->widget_settings['weight']) ? -1 : 1; + } } diff --git a/core/modules/field/lib/Drupal/field/FieldInstance.php b/core/modules/field/lib/Drupal/field/FieldInstance.php deleted file mode 100644 index ba6ea44..0000000 --- a/core/modules/field/lib/Drupal/field/FieldInstance.php +++ /dev/null @@ -1,135 +0,0 @@ -definition = $definition; - } - - /** - * Returns the Widget plugin for the instance. - * - * @return Drupal\field\Plugin\Type\Widget\WidgetInterface - * The Widget plugin to be used for the instance. - */ - public function getWidget() { - if (empty($this->widget)) { - $widget_properties = $this->definition['widget']; - - // Let modules alter the widget properties. - $context = array( - 'entity_type' => $this->definition['entity_type'], - 'bundle' => $this->definition['bundle'], - 'field' => field_info_field($this->definition['field_name']), - 'instance' => $this, - ); - drupal_alter(array('field_widget_properties', 'field_widget_properties_' . $this->definition['entity_type']), $widget_properties, $context); - - $options = array( - 'instance' => $this, - 'type' => $widget_properties['type'], - 'settings' => $widget_properties['settings'], - 'weight' => $widget_properties['weight'], - ); - $this->widget = drupal_container()->get('plugin.manager.field.widget')->getInstance($options); - } - - return $this->widget; - } - - /** - * Implements ArrayAccess::offsetExists(). - */ - public function offsetExists($offset) { - return isset($this->definition[$offset]) || array_key_exists($offset, $this->definition); - } - - /** - * Implements ArrayAccess::offsetGet(). - */ - public function &offsetGet($offset) { - return $this->definition[$offset]; - } - - /** - * Implements ArrayAccess::offsetSet(). - */ - public function offsetSet($offset, $value) { - if (!isset($offset)) { - // Do nothing; $array[] syntax is not supported by this temporary wrapper. - return; - } - $this->definition[$offset] = $value; - - // If the widget or formatter properties changed, the corrsponding plugins - // need to be re-instanciated. - if ($offset == 'widget') { - unset($this->widget); - } - } - - /** - * Implements ArrayAccess::offsetUnset(). - */ - public function offsetUnset($offset) { - unset($this->definition[$offset]); - - // If the widget or formatter properties changed, the corrsponding plugins - // need to be re-instanciated. - if ($offset == 'widget') { - unset($this->widget); - } - } - - /** - * Returns the instance definition as a regular array. - * - * This is used as a temporary BC layer. - * @todo Remove once the external APIs have been converted to use - * FieldInstance objects. - * - * @return array - * The instance definition as a regular array. - */ - public function getArray() { - return $this->definition; - } - - /** - * Handles serialization of Drupal\field\FieldInstance objects. - */ - public function __sleep() { - return array('definition'); - } - -} diff --git a/core/modules/field/lib/Drupal/field/FieldInstanceStorageController.php b/core/modules/field/lib/Drupal/field/FieldInstanceStorageController.php new file mode 100644 index 0000000..63d7505 --- /dev/null +++ b/core/modules/field/lib/Drupal/field/FieldInstanceStorageController.php @@ -0,0 +1,46 @@ +get(); + field_create_instance($config); + } + + /** + * Overrides \Drupal\Core\Config\Entity\ConfigStorageController::importChange(). + */ + public function importChange($name, Config $new_config, Config $old_config) { + $config = $new_config->get(); + field_update_instance($config); + } + + /** + * Overrides \Drupal\Core\Config\Entity\ConfigStorageController::importDelete(). + */ + public function importDelete($name, Config $new_config, Config $old_config) { + $config = $old_config->get(); + // In case the field has been deleted, + // the instance will be deleted by then already. + if (!empty($config)) { + field_delete_instance((object) $config); + } + } + +} diff --git a/core/modules/field/lib/Drupal/field/FieldStorageController.php b/core/modules/field/lib/Drupal/field/FieldStorageController.php new file mode 100644 index 0000000..a86c39c --- /dev/null +++ b/core/modules/field/lib/Drupal/field/FieldStorageController.php @@ -0,0 +1,39 @@ +get()); + } + + /** + * Overrides \Drupal\Core\Config\Entity\ConfigStorageController::importChange(). + */ + public function importChange($name, Config $new_config, Config $old_config) { + field_update_field($new_config->get()); + } + + /** + * Overrides \Drupal\Core\Config\Entity\ConfigStorageController::importDelete(). + */ + public function importDelete($name, Config $new_config, Config $old_config) { + field_delete_field($old_config->get('field_name')); + } + +} diff --git a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldEntity.php b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldEntity.php new file mode 100644 index 0000000..8348d88 --- /dev/null +++ b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldEntity.php @@ -0,0 +1,219 @@ +{$offset}); + } + + /** + * Implements ArrayAccess::offsetGet(). + */ + public function &offsetGet($offset) { + return $this->{$offset}; + } + + /** + * Implements ArrayAccess::offsetSet(). + */ + public function offsetSet($offset, $value) { + $this->{$offset} = $value; + } + + /** + * Implements ArrayAccess::offsetUnset(). + */ + public function offsetUnset($offset) { + unset($this->{$offset}); + } + + /** + * Generate an a table id for deleted fields. + * + * When a field is a deleted, the tables are renamed to {field_data_field_id} + * and {field_revision_field_id}. To make sure we don't end up with table + * names longer than 64 characters, we hash the uuid and return the first + * 6 characters so we end up with a short unique id. + */ + function generate_table_id() { + return substr(hash('sha256', $this->uuid), 0, 6); + } + +} diff --git a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php new file mode 100644 index 0000000..881a1ea --- /dev/null +++ b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php @@ -0,0 +1,196 @@ +widget)) { + $widget_properties = $this->widget_settings; + + // Let modules alter the widget properties. + $context = array( + 'entity_type' => $this->entity_type, + 'bundle' => $this->bundle, + 'field' => field_info_field($this->field_name), + 'instance' => $this, + ); + drupal_alter(array('field_widget_properties', 'field_widget_properties_' . $this->entity_type), $widget_properties, $context); + + $options = array( + 'instance' => $this, + 'type' => $widget_properties['type'], + 'settings' => $widget_properties['settings'], + 'weight' => $widget_properties['weight'], + ); + $this->widget = drupal_container()->get('plugin.manager.field.widget')->getInstance($options); + } + + return $this->widget; + } + + /** + * Implements ArrayAccess::offsetExists(). + */ + public function offsetExists($offset) { + return isset($this->{$offset}); + } + + /** + * Implements ArrayAccess::offsetGet(). + */ + public function &offsetGet($offset) { + return $this->{$offset}; + } + + /** + * Implements ArrayAccess::offsetSet(). + */ + public function offsetSet($offset, $value) { + $this->{$offset} = $value; + } + + /** + * Implements ArrayAccess::offsetUnset(). + */ + public function offsetUnset($offset) { + unset($this->{$offset}); + } + +} + diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php index 04a038d..83c6602 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php @@ -10,7 +10,7 @@ use Drupal\Component\Plugin\Discovery\DiscoveryInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\field\Plugin\PluginSettingsBase; -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; /** * Base class for 'Field formatter' plugin implementations. @@ -100,7 +100,7 @@ public function view(EntityInterface $entity, $langcode, array $items) { '#language' => $langcode, '#field_name' => $field['field_name'], '#field_type' => $field['type'], - '#field_translatable' => $field['translatable'], + '#field_translatable' => $instance['translatable'], '#entity_type' => $entity_type, '#bundle' => $entity->bundle(), '#object' => $entity, diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterInterface.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterInterface.php index 36693b0..4058810 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterInterface.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterInterface.php @@ -8,7 +8,7 @@ namespace Drupal\field\Plugin\Type\Formatter; use Drupal\Core\Entity\EntityInterface; -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; use Drupal\field\Plugin\PluginSettingsInterface; /** diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php index c935c44..363d29b 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php @@ -13,7 +13,7 @@ use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery; use Drupal\Core\Plugin\Discovery\AlterDecorator; use Drupal\field\Plugin\Type\Formatter\FormatterLegacyDiscoveryDecorator; -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; /** * Plugin type manager for field formatters. diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php index 12118f8..55ae495 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php @@ -11,7 +11,7 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Entity\EntityInterface; use Drupal\field\Plugin\PluginSettingsBase; -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; /** * Base class for 'Field widget' plugin implementations. @@ -107,7 +107,7 @@ public function form(EntityInterface $entity, $langcode, array $items, array &$f $delta = isset($get_delta) ? $get_delta : 0; $element = array( '#title' => check_plain($instance['label']), - '#description' => field_filter_xss(token_replace($instance['description'])), + '#description' => field_filter_xss(token_replace($instance->description)), ); $element = $this->formSingleElement($entity, $items, $delta, $langcode, $element, $form, $form_state); @@ -198,7 +198,7 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $ $wrapper_id = drupal_html_id($id_prefix . '-add-more-wrapper'); $title = check_plain($instance['label']); - $description = field_filter_xss(token_replace($instance['description'])); + $description = field_filter_xss(token_replace($instance->description)); $elements = array(); diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetInterface.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetInterface.php index c0ffc95..8711bbd 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetInterface.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetInterface.php @@ -8,7 +8,7 @@ namespace Drupal\field\Plugin\Type\Widget; use Drupal\Core\Entity\EntityInterface; -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; /** * Interface definition for field widget plugins. diff --git a/core/modules/field/lib/Drupal/field/Plugin/field/formatter/LegacyFormatter.php b/core/modules/field/lib/Drupal/field/Plugin/field/formatter/LegacyFormatter.php index 17c69fc..00857ef 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/field/formatter/LegacyFormatter.php +++ b/core/modules/field/lib/Drupal/field/Plugin/field/formatter/LegacyFormatter.php @@ -58,7 +58,7 @@ public function settingsSummary() { // properties directly from $instance. Put the actual properties we use // here. $instance = clone $this->instance; - $instance['display'][$this->viewMode] = array( + $instance->display[$this->viewMode] = array( 'type' => $this->getPluginId(), 'settings' => $this->getSettings(), 'label' => $this->label, diff --git a/core/modules/field/lib/Drupal/field/Plugin/field/widget/LegacyWidget.php b/core/modules/field/lib/Drupal/field/Plugin/field/widget/LegacyWidget.php index ee66f3f..bfbd01f 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/field/widget/LegacyWidget.php +++ b/core/modules/field/lib/Drupal/field/Plugin/field/widget/LegacyWidget.php @@ -51,8 +51,8 @@ public function formElement(array $items, $delta, array $element, $langcode, arr // from $instance. Put the actual properties we use here, which might have // been altered by hook_field_widget_property(). $instance = clone $this->instance; - $instance['widget']['type'] = $this->getPluginId(); - $instance['widget']['settings'] = $this->getSettings(); + $instance['widget_settings']['type'] = $this->getPluginId(); + $instance['widget_settings']['settings'] = $this->getSettings(); return $function($form, $form_state, $this->field, $instance, $langcode, $items, $delta, $element); } diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php index 30836a3..bf97ca6 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php +++ b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php @@ -428,7 +428,7 @@ function fakeFieldInstance($formatter, $formatter_settings) { $field_type = field_info_field_types($field['type']); - return array( + return entity_create('field_instance', array( // Build a fake entity type and bundle. 'field_name' => $field_name, 'entity_type' => 'views_fake', @@ -455,7 +455,7 @@ function fakeFieldInstance($formatter, $formatter_settings) { 'label' => $field_name, 'description' => '', 'deleted' => 0, - ); + )); } /** diff --git a/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php b/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php index c365961..1d46a83 100644 --- a/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php @@ -7,6 +7,8 @@ namespace Drupal\field\Tests; +use Drupal\field\Plugin\Core\Entity\FieldInstance; + /** * Unit test class for field bulk delete and batch purge functionality. */ @@ -171,9 +173,9 @@ function testDeleteFieldInstance() { field_delete_instance($instance); // The instance still exists, deleted. - $instances = field_read_instances(array('field_id' => $field['id'], 'deleted' => 1), array('include_deleted' => 1, 'include_inactive' => 1)); + $instances = field_read_instances(array('field_id' => $field['uuid'], 'deleted' => 1), array('include_deleted' => 1, 'include_inactive' => 1)); $this->assertEqual(count($instances), 1, 'There is one deleted instance'); - $this->assertEqual($instances[0]['bundle'], $bundle, 'The deleted instance is for the correct bundle'); + $this->assertEqual($instances[0]->bundle, $bundle, 'The deleted instance is for the correct bundle'); // There are 0 entities of this bundle with non-deleted data. $found = $factory->get('test_entity') @@ -198,7 +200,7 @@ function testDeleteFieldInstance() { $ids->entity_id = $entity_id; $entities[$entity_id] = _field_create_entity_from_ids($ids); } - field_attach_load($this->entity_type, $entities, FIELD_LOAD_CURRENT, array('field_id' => $field['id'], 'deleted' => 1)); + field_attach_load($this->entity_type, $entities, FIELD_LOAD_CURRENT, array('field_id' => $field['uuid'], 'deleted' => 1)); $this->assertEqual(count($found), 10, 'Correct number of entities found after deleting'); foreach ($entities as $id => $entity) { $this->assertEqual($this->entities[$id]->{$field['field_name']}, $entity->{$field['field_name']}, "Entity $id with deleted data loaded correctly"); @@ -254,19 +256,19 @@ function testPurgeInstance() { $this->checkHooksInvocations($hooks, $actual_hooks); // The instance still exists, deleted. - $instances = field_read_instances(array('field_id' => $field['id'], 'deleted' => 1), array('include_deleted' => 1, 'include_inactive' => 1)); + $instances = field_read_instances(array('field_id' => $field['uuid'], 'deleted' => 1), array('include_deleted' => 1, 'include_inactive' => 1)); $this->assertEqual(count($instances), 1, 'There is one deleted instance'); // Purge the instance. field_purge_batch($batch_size); // The instance is gone. - $instances = field_read_instances(array('field_id' => $field['id'], 'deleted' => 1), array('include_deleted' => 1, 'include_inactive' => 1)); + $instances = field_read_instances(array('field_id' => $field['uuid'], 'deleted' => 1), array('include_deleted' => 1, 'include_inactive' => 1)); $this->assertEqual(count($instances), 0, 'The instance is gone'); // The field still exists, not deleted, because it has a second instance. - $fields = field_read_fields(array('id' => $field['id']), array('include_deleted' => 1, 'include_inactive' => 1)); - $this->assertTrue(isset($fields[$field['id']]), 'The field exists and is not deleted'); + $fields = field_read_fields(array('uuid' => $field['uuid']), array('include_deleted' => 1, 'include_inactive' => 1)); + $this->assertTrue(isset($fields[$field['uuid']]), 'The field exists and is not deleted'); } /** @@ -307,8 +309,8 @@ function testPurgeField() { field_purge_batch(0); // The field still exists, not deleted. - $fields = field_read_fields(array('id' => $field['id']), array('include_deleted' => 1)); - $this->assertTrue(isset($fields[$field['id']]) && !$fields[$field['id']]['deleted'], 'The field exists and is not deleted'); + $fields = field_read_fields(array('uuid' => $field['uuid']), array('include_deleted' => 1)); + $this->assertTrue(isset($fields[$field['uuid']]) && !$fields[$field['uuid']]->deleted, 'The field exists and is not deleted'); // Delete the second instance. $bundle = next($this->bundles); @@ -331,14 +333,14 @@ function testPurgeField() { $this->checkHooksInvocations($hooks, $actual_hooks); // The field still exists, deleted. - $fields = field_read_fields(array('id' => $field['id']), array('include_deleted' => 1)); - $this->assertTrue(isset($fields[$field['id']]) && $fields[$field['id']]['deleted'], 'The field exists and is deleted'); + $fields = field_read_fields(array('uuid' => $field['uuid']), array('include_deleted' => 1)); + $this->assertTrue(isset($fields[$field['uuid']]) && $fields[$field['uuid']]->deleted, 'The field exists and is deleted'); // Purge again to purge the instance and the field. field_purge_batch(0); // The field is gone. - $fields = field_read_fields(array('id' => $field['id']), array('include_deleted' => 1, 'include_inactive' => 1)); + $fields = field_read_fields(array('uuid' => $field['uuid']), array('include_deleted' => 1, 'include_inactive' => 1)); $this->assertEqual(count($fields), 0, 'The field is purged.'); } } diff --git a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php index 1c539da..76d6c78 100644 --- a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php @@ -41,28 +41,27 @@ function testCreateField() { 'type' => 'test_field', ); field_test_memorize(); - $field_definition = field_create_field($field_definition); + $create_field = field_create_field($field_definition); $mem = field_test_memorize(); - $this->assertIdentical($mem['field_test_field_create_field'][0][0], $field_definition, 'hook_field_create_field() called with correct arguments.'); + $this->assertIdentical($mem['field_test_field_create_field'][0][0]->field_name, $field_definition['field_name'], 'hook_field_create_field() called with correct arguments.'); + $this->assertIdentical($mem['field_test_field_create_field'][0][0]->type, $field_definition['type'], 'hook_field_create_field() called with correct arguments.'); - // Read the raw record from the {field_config_instance} table. - $result = db_query('SELECT * FROM {field_config} WHERE field_name = :field_name', array(':field_name' => $field_definition['field_name'])); - $record = $result->fetchAssoc(); - $record['data'] = unserialize($record['data']); + // Read the configuration. + $record = entity_load('field_entity', $field_definition['field_name']); // Ensure that basic properties are preserved. - $this->assertEqual($record['field_name'], $field_definition['field_name'], 'The field name is properly saved.'); - $this->assertEqual($record['type'], $field_definition['type'], 'The field type is properly saved.'); + $this->assertEqual($record->field_name, $field_definition['field_name'], 'The field name is properly saved.'); + $this->assertEqual($record->type, $field_definition['type'], 'The field type is properly saved.'); // Ensure that cardinality defaults to 1. - $this->assertEqual($record['cardinality'], 1, 'Cardinality defaults to 1.'); + $this->assertEqual($record->cardinality, 1, 'Cardinality defaults to 1.'); // Ensure that default settings are present. $field_type = field_info_field_types($field_definition['type']); - $this->assertIdentical($record['data']['settings'], $field_type['settings'], 'Default field settings have been written.'); + $this->assertEqual($record->settings, $field_type['settings'], 'Default field settings have been written.'); // Ensure that default storage was set. - $this->assertEqual($record['storage_type'], variable_get('field_storage_default'), 'The field type is properly saved.'); + $this->assertEqual($record->storage_type, variable_get('field_storage_default'), 'The field type is properly saved.'); // Guarantee that the name is unique. try { @@ -157,11 +156,10 @@ function testCreateField() { function testCreateFieldFail() { $field_name = 'duplicate'; $field_definition = array('field_name' => $field_name, 'type' => 'test_field', 'storage' => array('type' => 'field_test_storage_failure')); - $query = db_select('field_config')->condition('field_name', $field_name)->countQuery(); + $field = entity_load('field_entity', $field_name); - // The field does not appear in field_config. - $count = $query->execute()->fetchField(); - $this->assertEqual($count, 0, 'A field_config row for the field does not exist.'); + // The field does not exist. + $this->assertFalse($field, 'The field does not exist.'); // Try to create the field. try { @@ -172,9 +170,10 @@ function testCreateFieldFail() { $this->assertTrue(TRUE, 'Field creation (correctly) fails.'); } - // The field does not appear in field_config. - $count = $query->execute()->fetchField(); - $this->assertEqual($count, 0, 'A field_config row for the field does not exist.'); + // The field does not exist. + // $field = config('field.field.' . $field_name)->get(); + $field = entity_load('field_entity', $field_name); + $this->assertFalse($field, 'The field does not exist.'); } /** @@ -221,10 +220,11 @@ function testReadFields() { field_create_instance($instance_definition); // Check that criteria spanning over the field_config_instance table work. - $fields = field_read_fields(array('entity_type' => $instance_definition['entity_type'], 'bundle' => $instance_definition['bundle'])); + // @todo do we still want to support this ? + /*$fields = field_read_fields(array('entity_type' => $instance_definition['entity_type'], 'bundle' => $instance_definition['bundle'])); $this->assertTrue(count($fields) == 1 && isset($fields[$field_definition['field_name']]), 'The field was properly read.'); $fields = field_read_fields(array('entity_type' => $instance_definition['entity_type'], 'field_name' => $instance_definition['field_name'])); - $this->assertTrue(count($fields) == 1 && isset($fields[$field_definition['field_name']]), 'The field was properly read.'); + $this->assertTrue(count($fields) == 1 && isset($fields[$field_definition['field_name']]), 'The field was properly read.');*/ } /** @@ -278,9 +278,9 @@ function testDeleteField() { // Create two fields (so we can test that only one is deleted). $this->field = array('field_name' => 'field_1', 'type' => 'test_field'); - field_create_field($this->field); + $this->field = field_create_field($this->field); $this->another_field = array('field_name' => 'field_2', 'type' => 'test_field'); - field_create_field($this->another_field); + $this->another_field = field_create_field($this->another_field); // Create instances for each. $this->instance_definition = array( @@ -303,8 +303,8 @@ function testDeleteField() { // Make sure that the field is marked as deleted when it is specifically // loaded. - $field = field_read_field($this->field['field_name'], array('include_deleted' => TRUE)); - $this->assertTrue(!empty($field['deleted']), 'A deleted field is marked for deletion.'); + $deleted_fields = state()->get('field.field.deleted'); + $this->assertTrue(isset($deleted_fields[$field['uuid']]), 'A deleted field is marked for deletion.'); // Make sure that this field's instance is marked as deleted when it is // specifically loaded. @@ -389,7 +389,7 @@ function testUpdateField() { 'type' => 'test_field', 'cardinality' => $cardinality, ); - $field_definition = field_create_field($field_definition); + field_create_field($field_definition); $instance = array( 'field_name' => 'field_update', 'entity_type' => 'test_entity', @@ -505,6 +505,6 @@ function _testActiveHelper($field_definition, $modules) { // Check that the field is active again after all modules have been // enabled. $field = field_read_field($field_name); - $this->assertTrue($field_definition <= $field, 'The field was was marked active.'); + $this->assertTrue($field_definition <= $field, 'The field was marked active.'); } } diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php index bc1a380..394e493 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldAccessTest.php @@ -37,11 +37,11 @@ function setUp() { $this->content_type_info = $this->drupalCreateContentType(); $this->content_type = $this->content_type_info->type; - $this->field = array( + $field = array( 'field_name' => 'test_view_field', 'type' => 'text', ); - field_create_field($this->field); + $this->field = field_create_field($field); $this->instance = array( 'field_name' => $this->field['field_name'], 'entity_type' => 'node', diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php index 89e07c6..8a9bcf6 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php @@ -35,7 +35,7 @@ function testFieldAttachView() { // Populate values to be displayed. $values = $this->_generateTestFieldValues($this->field['cardinality']); $entity_init->{$this->field_name}[$langcode] = $values; - $values_2 = $this->_generateTestFieldValues($this->field_2['cardinality']); + $values_2 = $this->_generateTestFieldValues($this->field_2->cardinality); $entity_init->{$this->field_name_2}[$langcode] = $values_2; // Simple formatter, label displayed. @@ -61,7 +61,7 @@ function testFieldAttachView() { 'test_formatter_setting' => $formatter_setting_2, ), ); - $display->setComponent($this->field_2['field_name'], $display_options_2); + $display->setComponent($this->field_2->field_name, $display_options_2); // View all fields. field_attach_prepare_view($entity_type, array($entity->ftid => $entity), $displays); @@ -73,7 +73,7 @@ function testFieldAttachView() { $this->content = $output; $this->assertRaw("$formatter_setting|{$value['value']}", "Value $delta is displayed, formatter settings are applied."); } - $this->assertRaw($this->instance_2['label'], "Second field's label is displayed."); + $this->assertRaw($this->instance_2->label, "Second field's label is displayed."); foreach ($values_2 as $delta => $value) { $this->content = $output; $this->assertRaw("$formatter_setting_2|{$value['value']}", "Value $delta is displayed, formatter settings are applied."); @@ -88,7 +88,7 @@ function testFieldAttachView() { $this->content = $output; $this->assertNoRaw("$formatter_setting|{$value['value']}", "Value $delta is displayed, formatter settings are applied."); } - $this->assertRaw($this->instance_2['label'], "Second field's label is displayed."); + $this->assertRaw($this->instance_2->label, "Second field's label is displayed."); foreach ($values_2 as $delta => $value) { $this->content = $output; $this->assertRaw("$formatter_setting_2|{$value['value']}", "Value $delta is displayed, formatter settings are applied."); @@ -187,7 +187,7 @@ function testFieldAttachPrepareViewMultiple() { field_test_create_bundle('test_bundle_2'); $formatter_setting = $this->randomName(); $this->instance2 = $this->instance; - $this->instance2['bundle'] = 'test_bundle_2'; + $this->instance2->bundle = 'test_bundle_2'; field_create_instance($this->instance2); $display_2 = entity_get_display('test_entity', 'test_bundle_2', 'full') @@ -348,7 +348,7 @@ function testFieldAttachValidate() { // Set up all values of the second field to generate errors. $values_2 = array(); - for ($delta = 0; $delta < $this->field_2['cardinality']; $delta++) { + for ($delta = 0; $delta < $this->field_2->cardinality; $delta++) { $values_2[$delta]['value'] = -1; } $entity->{$this->field_name_2}[$langcode] = $values_2; @@ -397,7 +397,7 @@ function testFieldAttachValidate() { $this->assertEqual(count($errors[$this->field_name_2][$langcode]), 0, 'No extraneous errors set for second field'); // Check that cardinality is validated. - $entity->{$this->field_name_2}[$langcode] = $this->_generateTestFieldValues($this->field_2['cardinality'] + 1); + $entity->{$this->field_name_2}[$langcode] = $this->_generateTestFieldValues($this->field_2->cardinality + 1); // When validating all fields. try { field_attach_validate($entity); @@ -435,12 +435,12 @@ function testFieldAttachForm() { field_attach_form($entity, $form, $form_state); $this->assertEqual($form[$this->field_name][$langcode]['#title'], $this->instance['label'], "First field's form title is {$this->instance['label']}"); - $this->assertEqual($form[$this->field_name_2][$langcode]['#title'], $this->instance_2['label'], "Second field's form title is {$this->instance_2['label']}"); + $this->assertEqual($form[$this->field_name_2][$langcode]['#title'], $this->instance_2->label, "Second field's form title is {$this->instance_2->label}"); for ($delta = 0; $delta < $this->field['cardinality']; $delta++) { // field_test_widget uses 'textfield' $this->assertEqual($form[$this->field_name][$langcode][$delta]['value']['#type'], 'textfield', "First field's form delta $delta widget is textfield"); } - for ($delta = 0; $delta < $this->field_2['cardinality']; $delta++) { + for ($delta = 0; $delta < $this->field_2->cardinality; $delta++) { // field_test_widget uses 'textfield' $this->assertEqual($form[$this->field_name_2][$langcode][$delta]['value']['#type'], 'textfield', "Second field's form delta $delta widget is textfield"); } @@ -452,8 +452,8 @@ function testFieldAttachForm() { field_attach_form($entity, $form, $form_state, NULL, $options); $this->assertFalse(isset($form[$this->field_name]), 'The first field does not exist in the form'); - $this->assertEqual($form[$this->field_name_2][$langcode]['#title'], $this->instance_2['label'], "Second field's form title is {$this->instance_2['label']}"); - for ($delta = 0; $delta < $this->field_2['cardinality']; $delta++) { + $this->assertEqual($form[$this->field_name_2][$langcode]['#title'], $this->instance_2->label, "Second field's form title is {$this->instance_2->label}"); + for ($delta = 0; $delta < $this->field_2->cardinality; $delta++) { // field_test_widget uses 'textfield' $this->assertEqual($form[$this->field_name_2][$langcode][$delta]['value']['#type'], 'textfield', "Second field's form delta $delta widget is textfield"); } @@ -492,11 +492,11 @@ function testFieldAttachExtractFormValues() { // Second field. $values_2 = array(); $weights_2 = array(); - for ($delta = 0; $delta < $this->field_2['cardinality']; $delta++) { + for ($delta = 0; $delta < $this->field_2->cardinality; $delta++) { $values_2[$delta]['value'] = mt_rand(1, 127); // Assign random weight. do { - $weight = mt_rand(0, $this->field_2['cardinality']); + $weight = mt_rand(0, $this->field_2->cardinality); } while (in_array($weight, $weights_2)); $weights_2[$delta] = $weight; $values_2[$delta]['_weight'] = $weight; diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php index 5ae3610..5d4c722 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php @@ -112,7 +112,7 @@ function testFieldAttachLoadMultiple() { $field_names[$i] = 'field_' . $i; $field = array('field_name' => $field_names[$i], 'type' => 'test_field'); $field = field_create_field($field); - $field_ids[$i] = $field['id']; + $field_ids[$i] = $field['uuid']; foreach ($field_bundles_map[$i] as $bundle) { $instance = array( 'field_name' => $field_names[$i], @@ -231,7 +231,7 @@ function testFieldStorageDetailsAlter() { 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', ); - field_create_instance($instance); + $instance = field_create_instance($instance); $field = field_info_field($instance['field_name']); $instance = field_info_instance($instance['entity_type'], $instance['field_name'], $instance['bundle']); @@ -248,7 +248,7 @@ function testFieldStorageDetailsAlter() { // Test current and revision storage details together because the columns // are the same. - foreach ((array) $field['columns'] as $column_name => $attributes) { + foreach ($field['columns'] as $column_name => $attributes) { $this->assertEqual($details[FIELD_LOAD_CURRENT]['moon'][$column_name], $column_name, format_string('Column name %value matches the definition in %bin.', array('%value' => $column_name, '%bin' => 'moon[FIELD_LOAD_CURRENT]'))); $this->assertEqual($details[FIELD_LOAD_REVISION]['mars'][$column_name], $column_name, format_string('Column name %value matches the definition in %bin.', array('%value' => $column_name, '%bin' => 'mars[FIELD_LOAD_REVISION]'))); } @@ -437,8 +437,8 @@ function testFieldAttachCreateRenameBundle() { field_test_create_bundle($new_bundle); // Add an instance to that bundle. - $this->instance['bundle'] = $new_bundle; - field_create_instance($this->instance); + $this->instance_definition['bundle'] = $new_bundle; + $this->instance = field_create_instance($this->instance_definition); // Save an entity with data in the field. $entity = field_test_create_entity(0, 0, $this->instance['bundle']); @@ -476,8 +476,8 @@ function testFieldAttachDeleteBundle() { field_test_create_bundle($new_bundle); // Add an instance to that bundle. - $this->instance['bundle'] = $new_bundle; - field_create_instance($this->instance); + $this->instance_definition['bundle'] = $new_bundle; + $this->instance = field_create_instance($this->instance_definition); // Create a second field for the test bundle $field_name = drupal_strtolower($this->randomName() . '_field_name'); @@ -491,10 +491,13 @@ function testFieldAttachDeleteBundle() { 'description' => $this->randomName() . '_description', 'weight' => mt_rand(0, 127), // test_field has no instance settings - 'widget' => array( + 'widget_settings' => array( 'type' => 'test_field_widget', 'settings' => array( - 'size' => mt_rand(0, 255)))); + 'size' => mt_rand(0, 255) + ) + ) + ); field_create_instance($instance); // Save an entity with data for both fields diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAttachTestBase.php b/core/modules/field/lib/Drupal/field/Tests/FieldAttachTestBase.php index 9d15ba2..9c3398a 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldAttachTestBase.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldAttachTestBase.php @@ -34,11 +34,12 @@ function createFieldWithInstance($suffix = '') { $field = 'field' . $suffix; $field_id = 'field_id' . $suffix; $instance = 'instance' . $suffix; + $instance_definition = 'instance_definition' . $suffix; $this->$field_name = drupal_strtolower($this->randomName() . '_field_name' . $suffix); $this->$field = array('field_name' => $this->$field_name, 'type' => 'test_field', 'cardinality' => 4); $this->$field = field_create_field($this->$field); - $this->$field_id = $this->{$field}['id']; + $this->$field_id = $this->{$field}->uuid; $this->$instance = array( 'field_name' => $this->$field_name, 'entity_type' => 'test_entity', @@ -49,7 +50,7 @@ function createFieldWithInstance($suffix = '') { 'settings' => array( 'test_instance_setting' => $this->randomName(), ), - 'widget' => array( + 'widget_settings' => array( 'type' => 'test_field_widget', 'label' => 'Test Field', 'settings' => array( @@ -57,6 +58,7 @@ function createFieldWithInstance($suffix = '') { ) ) ); - field_create_instance($this->$instance); + $this->$instance_definition = $this->$instance; + $this->$instance = field_create_instance($this->$instance); } } diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldImportChangeTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldImportChangeTest.php new file mode 100644 index 0000000..e161b5c --- /dev/null +++ b/core/modules/field/lib/Drupal/field/Tests/FieldImportChangeTest.php @@ -0,0 +1,69 @@ + 'Field config change tests', + 'description' => 'Update field and instances during config change method invocation.', + 'group' => 'Field API', + ); + } + + function setUp() { + parent::setUp(); + + $this->instance_manifest = 'manifest.field.instance'; + $this->instance_name = 'field.instance.node.test_import.field_test_import'; + $this->drupalCreateContentType(array('type' => 'test_import', 'name' => 'Test import')); + + $admin_user = $this->drupalCreateUser(array('access administration pages', 'access content overview', 'administer nodes', 'bypass node access')); + $this->drupalLogin($admin_user); + } + + /** + * Test importing changes. + */ + function testImportChange() { + + // Assert default test import. + $this->drupalGet('node/add/test_import'); + $this->assertRaw('Test import field'); + + // Change label. + $active = $this->container->get('config.storage'); + $staging = $this->container->get('config.storage.staging'); + $manifest = $active->read($this->instance_manifest); + $instance = $active->read($this->instance_name); + $instance['label'] = 'Test update import field'; + $staging->write($this->instance_name, $instance); + $staging->write($this->instance_manifest, $manifest); + + // Import. + config_import(); + + // Assert updated label. + $this->drupalGet('node/add/test_import'); + $this->assertText('Test update import field'); + } +} diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldImportCreateTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldImportCreateTest.php new file mode 100644 index 0000000..6bda93f --- /dev/null +++ b/core/modules/field/lib/Drupal/field/Tests/FieldImportCreateTest.php @@ -0,0 +1,87 @@ + 'Field config create tests', + 'description' => 'Create field and instances during config create method invocation.', + 'group' => 'Field API', + ); + } + + function setUp() { + parent::setUp(); + + $this->field_test_import_staging = 'field.field.field_test_import_staging'; + $this->instance_test_import_staging = 'field.instance.node.test_import.field_test_import_staging'; + $this->field_manifest = 'manifest.field.field'; + $this->instance_manifest = 'manifest.field.instance'; + $this->drupalCreateContentType(array('type' => 'test_import', 'name' => 'Test import')); + + $admin_user = $this->drupalCreateUser(array('access administration pages', 'access content overview', 'administer nodes', 'bypass node access')); + $this->drupalLogin($admin_user); + } + + /** + * Test importing new fields. + */ + function testImportCreate() { + + // Assert default test import. + $this->drupalGet('node/add/test_import'); + $this->assertNoText('Test import field'); + + // Enable field_test_config module and assert the test import + // field and instance is available on the Test content type. + // This tests creating fields and instances that are provided + // by a module. + module_enable(array('field_test_config')); + $this->drupalGet('node/add/test_import'); + $this->assertText('Test import field'); + $module_path = drupal_get_path('module', 'field_test_config'); + + // Copy another field and instance to the staging directory + // on the Test content type and run config_import() to test + // importing from the staging directory. + $active = $this->container->get('config.storage'); + $staging = $this->container->get('config.storage.staging'); + $field_manifest = $active->read($this->field_manifest); + $instance_manifest = $active->read($this->instance_manifest); + + // Copy the files. + $copied = file_unmanaged_copy($module_path .'/staging/' . $this->field_test_import_staging . '.yml', 'public://config_staging/' . $this->field_test_import_staging . '.yml'); + $this->assertTrue($copied); + $copied = file_unmanaged_copy($module_path .'/staging/' . $this->instance_test_import_staging . '.yml', 'public://config_staging/' . $this->instance_test_import_staging . '.yml'); + $this->assertTrue($copied); + + // Add to manifest. + $field_manifest['field_test_import_staging'] = array('name' => $this->field_test_import_staging); + $instance_manifest['node.test_import.field_test_import_staging'] = array('name' => $this->instance_test_import_staging); + + // Write to manifest and new config. + $staging->write($this->field_manifest, $field_manifest); + $staging->write($this->instance_manifest, $instance_manifest); + + // Import. + config_import(); + + // Assert the staging field is there. + $this->drupalGet('node/add/test_import'); + $this->assertText('Import from staging'); + } +} diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldImportDeleteTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldImportDeleteTest.php new file mode 100644 index 0000000..1a54deb --- /dev/null +++ b/core/modules/field/lib/Drupal/field/Tests/FieldImportDeleteTest.php @@ -0,0 +1,100 @@ + 'Field config delete tests', + 'description' => 'Delete field and instances during config delete method invocation.', + 'group' => 'Field API', + ); + } + + function setUp() { + parent::setUp(); + + $this->body_field_name = 'field.field.body'; + $this->test_import_field_name = 'field.field.test_import'; + $this->body_instance_name = 'field.instance.node.test_import.body'; + $this->test_import_instance_name = 'field.instance.node.test_import.field_test_import'; + $this->field_manifest = 'manifest.field.field'; + $this->instance_manifest = 'manifest.field.instance'; + $this->drupalCreateContentType(array('type' => 'test_import', 'name' => 'Test import')); + + $admin_user = $this->drupalCreateUser(array('access administration pages', 'access content overview', 'administer nodes', 'bypass node access')); + $this->drupalLogin($admin_user); + } + + /** + * Test importing deletions. + */ + function testImportDelete() { + + $body_field = field_info_field('body'); + $field_test_import = field_info_field('field_test_import'); + + // Assert default test import. + $this->drupalGet('node/add/test_import'); + $this->assertRaw('Test import field'); + $this->assertRaw('Body'); + + // Delete body field and instance, the test import instance + // from the manifest. + $active = $this->container->get('config.storage'); + $staging = $this->container->get('config.storage.staging'); + $field_manifest = $active->read($this->field_manifest); + $instance_manifest = $active->read($this->instance_manifest); + unset($field_manifest['body']); + unset($instance_manifest['node.test_import.body']); + unset($instance_manifest['node.test_import.field_test_import']); + $staging->write($this->field_manifest, $field_manifest); + $staging->write($this->instance_manifest, $instance_manifest); + + // Import. + config_import(); + + // Assert the field and instance are gone from the form. + $this->drupalGet('node/add/test_import'); + $this->assertNoText('Test import field'); + $this->assertNoText('Body'); + + // Check that body and import field are in state of deleted fields. + $deleted_fields = state()->get('field.field.deleted') ?: array(); + $this->assertTrue(isset($deleted_fields[$body_field['uuid']])); + $this->assertTrue(isset($deleted_fields[$field_test_import->uuid])); + + // Run purge_batch(). + field_purge_batch(10); + + // Check that the deleted fields are removed from state. + $deleted_fields = state()->get('field.field.deleted') ?: array(); + $this->assertTrue(empty($deleted_fields), 'Fields are deleted'); + + // Check all config files are gone. + $active = $this->container->get('config.storage'); + $this->assertIdentical($active->listAll($this->body_field_name), array()); + $this->assertIdentical($active->listAll($this->test_import_field_name), array()); + $this->assertIdentical($active->listAll($this->body_instance_name), array()); + $this->assertIdentical($active->listAll($this->test_import_instance_name), array()); + } +} diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php index 3115851..b7bc743 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php @@ -65,18 +65,18 @@ function testFieldInfo() { 'field_name' => drupal_strtolower($this->randomName()), 'type' => 'test_field', ); - field_create_field($field); + $field = field_create_field($field); $fields = field_info_fields(); $this->assertEqual(count($fields), count($core_fields) + 1, 'One new field exists'); - $this->assertEqual($fields[$field['field_name']]['field_name'], $field['field_name'], 'info fields contains field name'); - $this->assertEqual($fields[$field['field_name']]['type'], $field['type'], 'info fields contains field type'); - $this->assertEqual($fields[$field['field_name']]['module'], 'field_test', 'info fields contains field module'); + $this->assertEqual($fields[$field['field_name']]->field_name, $field['field_name'], 'info fields contains field name'); + $this->assertEqual($fields[$field['field_name']]->type, $field['type'], 'info fields contains field type'); + $this->assertEqual($fields[$field['field_name']]->module, 'field_test', 'info fields contains field module'); $settings = array('test_field_setting' => 'dummy test string'); foreach ($settings as $key => $val) { - $this->assertEqual($fields[$field['field_name']]['settings'][$key], $val, format_string('Field setting %key has correct default value %value', array('%key' => $key, '%value' => $val))); + $this->assertEqual($fields[$field['field_name']]->settings[$key], $val, format_string('Field setting %key has correct default value %value', array('%key' => $key, '%value' => $val))); } - $this->assertEqual($fields[$field['field_name']]['cardinality'], 1, 'info fields contains cardinality 1'); - $this->assertEqual($fields[$field['field_name']]['active'], 1, 'info fields contains active 1'); + $this->assertEqual($fields[$field['field_name']]->cardinality, 1, 'info fields contains cardinality 1'); + $this->assertEqual($fields[$field['field_name']]->active, 1, 'info fields contains active 1'); // Create an instance, verify that it shows up $instance = array( @@ -87,11 +87,14 @@ function testFieldInfo() { 'description' => $this->randomName(), 'weight' => mt_rand(0, 127), // test_field has no instance settings - 'widget' => array( + 'widget_settings' => array( 'type' => 'test_field_widget', 'settings' => array( - 'test_setting' => 999))); - field_create_instance($instance); + 'test_setting' => 999 + ) + ) + ); + $instance = field_create_instance($instance); $info = entity_get_info('test_entity'); $instances = field_info_instances('test_entity', $instance['bundle']); @@ -143,13 +146,9 @@ function testFieldPrepare() { // Simulate a stored field definition missing a field setting (e.g. a // third-party module adding a new field setting has been enabled, and // existing fields do not know the setting yet). - $data = db_query('SELECT data FROM {field_config} WHERE field_name = :field_name', array(':field_name' => $field_definition['field_name']))->fetchField(); - $data = unserialize($data); - $data['settings'] = array(); - db_update('field_config') - ->fields(array('data' => serialize($data))) - ->condition('field_name', $field_definition['field_name']) - ->execute(); + $field = entity_load('field_entity', $field_definition['field_name']); + $field['settings'] = array(); + field_update_field($field); field_cache_clear(); @@ -158,7 +157,7 @@ function testFieldPrepare() { // Check that all expected settings are in place. $field_type = field_info_field_types($field_definition['type']); - $this->assertIdentical($field['settings'], $field_type['settings'], 'All expected default field settings are present.'); + $this->assertEqual($field['settings'], $field_type['settings'], 'All expected default field settings are present.'); } /** @@ -180,25 +179,18 @@ function testInstancePrepare() { // Simulate a stored instance definition missing various settings (e.g. a // third-party module adding instance or widget settings has been enabled, // but existing instances do not know the new settings). - $data = db_query('SELECT data FROM {field_config_instance} WHERE field_name = :field_name AND bundle = :bundle', array(':field_name' => $instance_definition['field_name'], ':bundle' => $instance_definition['bundle']))->fetchField(); - $data = unserialize($data); - $data['settings'] = array(); - $data['widget']['settings'] = 'unavailable_widget'; - $data['widget']['settings'] = array(); - db_update('field_config_instance') - ->fields(array('data' => serialize($data))) - ->condition('field_name', $instance_definition['field_name']) - ->condition('bundle', $instance_definition['bundle']) - ->execute(); - - field_cache_clear(); + $instance = entity_load('field_instance', $instance_definition['entity_type'] . '.' . $instance_definition['bundle'] . '.' . $instance_definition['field_name']); + $instance['settings'] = array(); + $instance['widget_settings']['settings'] = 'unavailable_widget'; + $instance['widget_settings']['settings'] = array(); + field_update_instance($instance); // Read the instance back. $instance = field_info_instance($instance_definition['entity_type'], $instance_definition['field_name'], $instance_definition['bundle']); // Check that all expected instance settings are in place. $field_type = field_info_field_types($field_definition['type']); - $this->assertIdentical($instance['settings'], $field_type['instance_settings'] , 'All expected instance settings are present.'); + $this->assertEqual($instance['settings'], $field_type['instance_settings'] , 'All expected instance settings are present.'); // Check that the default widget is used and expected settings are in place. $widget = $instance->getWidget(); diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php index 90fcc05..718549a 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php @@ -8,6 +8,7 @@ namespace Drupal\field\Tests; use Drupal\field\FieldException; +use Drupal\field\Plugin\Core\Entity\FieldInstance; class FieldInstanceCrudTest extends FieldTestBase { @@ -35,7 +36,7 @@ function setUp() { 'field_name' => drupal_strtolower($this->randomName()), 'type' => 'test_field', ); - field_create_field($this->field); + $this->field = field_create_field($this->field); $this->instance_definition = array( 'field_name' => $this->field['field_name'], 'entity_type' => 'test_entity', @@ -55,26 +56,24 @@ function setUp() { function testCreateFieldInstance() { field_create_instance($this->instance_definition); - // Read the raw record from the {field_config_instance} table. - $result = db_query('SELECT * FROM {field_config_instance} WHERE field_name = :field_name AND bundle = :bundle', array(':field_name' => $this->instance_definition['field_name'], ':bundle' => $this->instance_definition['bundle'])); - $record = $result->fetchAssoc(); - $record['data'] = unserialize($record['data']); + // Read the configuration. + $instance = entity_load('field_instance', $this->instance_definition['entity_type'] . '.' . $this->instance_definition['bundle'] . '.' . $this->instance_definition['field_name']); $field_type = field_info_field_types($this->field['type']); $widget_type = field_info_widget_types($field_type['default_widget']); // Check that the ID key is filled in. - $this->assertIdentical($record['id'], $this->instance_definition['id'], 'The instance id is filled in'); + //$this->assertIdentical($record['id'], $this->instance_definition['id'], 'The instance id is filled in'); // Check that default values are set. - $this->assertIdentical($record['data']['required'], FALSE, 'Required defaults to false.'); - $this->assertIdentical($record['data']['label'], $this->instance_definition['field_name'], 'Label defaults to field name.'); - $this->assertIdentical($record['data']['description'], '', 'Description defaults to empty string.'); - $this->assertIdentical($record['data']['widget']['type'], $field_type['default_widget'], 'Default widget has been written.'); + $this->assertEqual($instance['required'], FALSE, 'Required defaults to false.'); + $this->assertIdentical($instance['label'], $this->instance_definition['field_name'], 'Label defaults to field name.'); + $this->assertIdentical($instance->description, '', 'Description defaults to empty string.'); + $this->assertIdentical($instance['widget_settings']['type'], $field_type['default_widget'], 'Default widget has been written.'); // Check that default settings are set. - $this->assertIdentical($record['data']['settings'], $field_type['instance_settings'] , 'Default instance settings have been written.'); - $this->assertIdentical($record['data']['widget']['settings'], $widget_type['settings'] , 'Default widget settings have been written.'); + $this->assertEqual($instance['settings'], $field_type['instance_settings'] , 'Default instance settings have been written.'); + $this->assertIdentical($instance['widget_settings']['settings'], $widget_type['settings'] , 'Default widget settings have been written.'); // Guarantee that the field/bundle combination is unique. try { @@ -139,7 +138,9 @@ function testReadFieldInstance() { // Read the instance back. $instance = field_read_instance('test_entity', $this->instance_definition['field_name'], $this->instance_definition['bundle']); - $this->assertTrue($this->instance_definition == $instance, 'The field was properly read.'); + $this->assertTrue($this->instance_definition['field_name'] == $instance['field_name'], 'The field was properly read.'); + $this->assertTrue($this->instance_definition['entity_type'] == $instance['entity_type'], 'The field was properly read.'); + $this->assertTrue($this->instance_definition['bundle'] == $instance['bundle'], 'The field was properly read.'); } /** @@ -152,28 +153,28 @@ function testUpdateFieldInstance() { $instance = field_read_instance('test_entity', $this->instance_definition['field_name'], $this->instance_definition['bundle']); $instance['required'] = !$instance['required']; $instance['label'] = $this->randomName(); - $instance['description'] = $this->randomName(); + $instance->description = $this->randomName(); $instance['settings']['test_instance_setting'] = $this->randomName(); - $instance['widget']['settings']['test_widget_setting'] =$this->randomName(); - $instance['widget']['weight']++; + $instance['widget_settings']['settings']['test_widget_setting'] =$this->randomName(); + $instance['widget_settings']['weight']++; field_update_instance($instance); $instance_new = field_read_instance('test_entity', $this->instance_definition['field_name'], $this->instance_definition['bundle']); - $this->assertEqual($instance['required'], $instance_new['required'], '"required" change is saved'); - $this->assertEqual($instance['label'], $instance_new['label'], '"label" change is saved'); - $this->assertEqual($instance['description'], $instance_new['description'], '"description" change is saved'); - $this->assertEqual($instance['widget']['settings']['test_widget_setting'], $instance_new['widget']['settings']['test_widget_setting'], 'Widget setting change is saved'); - $this->assertEqual($instance['widget']['weight'], $instance_new['widget']['weight'], 'Widget weight change is saved'); + $this->assertEqual($instance['required'], $instance_new->required, '"required" change is saved'); + $this->assertEqual($instance['label'], $instance_new->label, '"label" change is saved'); + $this->assertEqual($instance->description, $instance_new->description, '"description" change is saved'); + $this->assertEqual($instance['widget_settings']['settings']['test_widget_setting'], $instance_new->widget_settings['settings']['test_widget_setting'], 'Widget setting change is saved'); + $this->assertEqual($instance['widget_settings']['weight'], $instance_new->widget_settings['weight'], 'Widget weight change is saved'); // Check that changing the widget type updates the default settings. $instance = field_read_instance('test_entity', $this->instance_definition['field_name'], $this->instance_definition['bundle']); - $instance['widget']['type'] = 'test_field_widget_multiple'; + $instance['widget_settings']['type'] = 'test_field_widget_multiple'; field_update_instance($instance); $instance_new = field_read_instance('test_entity', $this->instance_definition['field_name'], $this->instance_definition['bundle']); - $this->assertEqual($instance['widget']['type'], $instance_new['widget']['type'] , 'Widget type change is saved.'); - $settings = field_info_widget_settings($instance_new['widget']['type']); - $this->assertIdentical($settings, array_intersect_key($instance_new['widget']['settings'], $settings) , 'Widget type change updates default settings.'); + $this->assertEqual($instance['widget_settings']['type'], $instance_new->widget_settings['type'] , 'Widget type change is saved.'); + $settings = field_info_widget_settings($instance_new->widget_settings['type']); + $this->assertIdentical($settings, array_intersect_key($instance_new->widget_settings['settings'], $settings) , 'Widget type change updates default settings.'); // TODO: test failures. } @@ -213,7 +214,9 @@ function testDeleteFieldInstance() { // Make sure the field is deleted when its last instance is deleted. field_delete_instance($another_instance); - $field = field_read_field($another_instance['field_name'], array('include_deleted' => TRUE)); - $this->assertTrue(!empty($field['deleted']), 'A deleted field is marked for deletion after all its instances have been marked for deletion.'); + $deleted_fields = state()->get('field.field.deleted'); + $this->assertTrue(isset($deleted_fields[$another_instance['field_id']]), 'A deleted field is marked for deletion.'); + $field = field_read_field(array('field_name' => $another_instance['field_name'])); + $this->assertFalse($field, 'The field marked to be deleted is not found anymore in the configuration.'); } } diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldItemUnitTestBase.php b/core/modules/field/lib/Drupal/field/Tests/FieldItemUnitTestBase.php index e201fb5..dd9b6a8 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldItemUnitTestBase.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldItemUnitTestBase.php @@ -24,8 +24,6 @@ class FieldItemUnitTestBase extends DrupalUnitTestBase { public function setUp() { parent::setUp(); $this->installSchema('system', 'sequences'); - $this->installSchema('field', 'field_config'); - $this->installSchema('field', 'field_config_instance'); $this->installSchema('entity_test', 'entity_test'); } diff --git a/core/modules/field/lib/Drupal/field/Tests/FormTest.php b/core/modules/field/lib/Drupal/field/Tests/FormTest.php index 2f5dbee..3827dd9 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FormTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FormTest.php @@ -43,7 +43,7 @@ function setUp() { 'settings' => array( 'test_instance_setting' => $this->randomName(), ), - 'widget' => array( + 'widget_settings' => array( 'type' => 'test_field_widget', 'label' => 'Test Field', 'settings' => array( @@ -57,7 +57,7 @@ function testFieldFormSingle() { $this->field = $this->field_single; $this->field_name = $this->field['field_name']; $this->instance['field_name'] = $this->field_name; - field_create_field($this->field); + $this->field = field_create_field($this->field); field_create_instance($this->instance); $langcode = LANGUAGE_NOT_SPECIFIED; @@ -123,7 +123,7 @@ function testFieldFormDefaultValue() { $this->instance['field_name'] = $this->field_name; $default = rand(1, 127); $this->instance['default_value'] = array(array('value' => $default)); - field_create_field($this->field); + $this->field = field_create_field($this->field); field_create_instance($this->instance); $langcode = LANGUAGE_NOT_SPECIFIED; @@ -147,7 +147,7 @@ function testFieldFormSingleRequired() { $this->field_name = $this->field['field_name']; $this->instance['field_name'] = $this->field_name; $this->instance['required'] = TRUE; - field_create_field($this->field); + $this->field = field_create_field($this->field); field_create_instance($this->instance); $langcode = LANGUAGE_NOT_SPECIFIED; @@ -185,7 +185,7 @@ function testFieldFormUnlimited() { $this->field = $this->field_unlimited; $this->field_name = $this->field['field_name']; $this->instance['field_name'] = $this->field_name; - field_create_field($this->field); + $this->field = field_create_field($this->field); field_create_instance($this->instance); $langcode = LANGUAGE_NOT_SPECIFIED; @@ -265,7 +265,7 @@ function testFieldFormMultivalueWithRequiredRadio() { $this->field = $this->field_unlimited; $this->field_name = $this->field['field_name']; $this->instance['field_name'] = $this->field_name; - field_create_field($this->field); + $this->field = field_create_field($this->field); field_create_instance($this->instance); $langcode = LANGUAGE_NOT_SPECIFIED; @@ -282,7 +282,7 @@ function testFieldFormMultivalueWithRequiredRadio() { 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', 'required' => TRUE, - 'widget' => array( + 'widget_settings' => array( 'type' => 'options_buttons', ), ); @@ -307,7 +307,7 @@ function testFieldFormJSAddMore() { $this->field = $this->field_unlimited; $this->field_name = $this->field['field_name']; $this->instance['field_name'] = $this->field_name; - field_create_field($this->field); + $this->field = field_create_field($this->field); field_create_instance($this->instance); $langcode = LANGUAGE_NOT_SPECIFIED; @@ -366,8 +366,8 @@ function testFieldFormMultipleWidget() { $this->field = $this->field_multiple; $this->field_name = $this->field['field_name']; $this->instance['field_name'] = $this->field_name; - $this->instance['widget']['type'] = 'test_field_widget_multiple'; - field_create_field($this->field); + $this->instance['widget_settings']['type'] = 'test_field_widget_multiple'; + $this->field = field_create_field($this->field); field_create_instance($this->instance); $langcode = LANGUAGE_NOT_SPECIFIED; @@ -406,7 +406,7 @@ function testFieldFormAccess() { $field_name = $field['field_name']; $instance = $this->instance; $instance['field_name'] = $field_name; - field_create_field($field); + $this->field = field_create_field($field); field_create_instance($instance); // Create a field with no edit access - see field_test_field_access(). diff --git a/core/modules/field/lib/Drupal/field/Tests/ShapeItemTest.php b/core/modules/field/lib/Drupal/field/Tests/ShapeItemTest.php index c5e52c1..232290d 100644 --- a/core/modules/field/lib/Drupal/field/Tests/ShapeItemTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/ShapeItemTest.php @@ -43,7 +43,7 @@ public function setUp() { 'entity_type' => 'entity_test', 'field_name' => 'field_shape', 'bundle' => 'entity_test', - 'widget' => array( + 'widget_settings' => array( 'type' => 'test_field_widget', ), ); diff --git a/core/modules/field/lib/Drupal/field/Tests/TestItemTest.php b/core/modules/field/lib/Drupal/field/Tests/TestItemTest.php index 4873eb7..5c2c46e 100644 --- a/core/modules/field/lib/Drupal/field/Tests/TestItemTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/TestItemTest.php @@ -43,7 +43,7 @@ public function setUp() { 'entity_type' => 'entity_test', 'field_name' => 'field_test', 'bundle' => 'entity_test', - 'widget' => array( + 'widget_settings' => array( 'type' => 'test_field_widget', ), ); diff --git a/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php b/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php index f2ada97..2622ff6 100644 --- a/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php @@ -47,6 +47,7 @@ function setUp() { ); field_create_field($field); $this->field = field_read_field($this->field_name); + $this->field_definition = $field; $instance = array( 'field_name' => $this->field_name, @@ -55,6 +56,7 @@ function setUp() { ); field_create_instance($instance); $this->instance = field_read_instance('test_entity', $this->field_name, 'test_bundle'); + $this->instance_definition = $instance; for ($i = 0; $i < 3; ++$i) { $language = new Language(array( @@ -71,7 +73,7 @@ function setUp() { function testFieldAvailableLanguages() { // Test 'translatable' fieldable info. field_test_entity_info_translatable('test_entity', FALSE); - $field = $this->field; + $field = clone($this->field); $field['field_name'] .= '_untranslatable'; // Enable field translations for the entity. @@ -90,7 +92,7 @@ function testFieldAvailableLanguages() { $this->assertFalse(in_array('en', $available_langcodes), format_string('%language was made unavailable.', array('%language' => 'en'))); // Test field_available_languages() behavior for untranslatable fields. - $this->field['translatable'] = FALSE; + $this->instance['translatable'] = FALSE; field_update_field($this->field); $available_langcodes = field_available_languages($this->entity_type, $this->field); $this->assertTrue(count($available_langcodes) == 1 && $available_langcodes[0] === LANGUAGE_NOT_SPECIFIED, 'For untranslatable fields only LANGUAGE_NOT_SPECIFIED is available.'); @@ -245,9 +247,9 @@ function testTranslatableFieldSaveLoad() { // Test default values. $field_name_default = drupal_strtolower($this->randomName() . '_field_name'); - $field = $this->field; + $field = $this->field_definition; $field['field_name'] = $field_name_default; - $instance = $this->instance; + $instance = $this->instance_definition; $instance['field_name'] = $field_name_default; $default = rand(1, 127); $instance['default_value'] = array(array('value' => $default)); @@ -312,7 +314,7 @@ function testFieldDisplayLanguage() { 'entity_type' => $entity_type, 'bundle' => 'test_bundle', ); - field_create_instance($instance); + $this->instance = field_create_instance($instance); $entity = field_test_create_entity(1, 1, $this->instance['bundle']); $instances = field_info_instances($entity_type, $this->instance['bundle']); diff --git a/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php b/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php index 1c8d3f5..80c06d9 100644 --- a/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/Views/HandlerFieldFieldTest.php @@ -62,10 +62,10 @@ protected function setUp() { $edit[$field['field_name']][LANGUAGE_NOT_SPECIFIED][0]['value'] = $this->randomName(8); } for ($j = 0; $j < 5; $j++) { - $edit[$this->fields[3]['field_name']][LANGUAGE_NOT_SPECIFIED][$j]['value'] = $this->randomName(8); + $edit[$this->fields[3]->field_name][LANGUAGE_NOT_SPECIFIED][$j]['value'] = $this->randomName(8); } // Set this field to be empty. - $edit[$this->fields[4]['field_name']] = array(LANGUAGE_NOT_SPECIFIED => array(0 => array('value' => NULL))); + $edit[$this->fields[4]->field_name] = array(LANGUAGE_NOT_SPECIFIED => array(0 => array('value' => NULL))); $this->nodes[$i] = $this->drupalCreateNode($edit); } @@ -114,8 +114,8 @@ public function _testSimpleFieldRender() { public function _testFormatterSimpleFieldRender() { $view = views_get_view('test_view_fieldapi'); $this->prepareView($view); - $view->displayHandlers->get('default')->options['fields'][$this->fields[0]['field_name']]['type'] = 'text_trimmed'; - $view->displayHandlers->get('default')->options['fields'][$this->fields[0]['field_name']]['settings'] = array( + $view->displayHandlers->get('default')->options['fields'][$this->fields[0]->field_name]['type'] = 'text_trimmed'; + $view->displayHandlers->get('default')->options['fields'][$this->fields[0]->field_name]['settings'] = array( 'trim_length' => 3, ); $this->executeView($view); @@ -123,14 +123,14 @@ public function _testFormatterSimpleFieldRender() { // Take sure that the formatter works as expected. // @TODO: actually there should be a specific formatter. for ($i = 0; $i < 2; $i++) { - $rendered_field = $view->style_plugin->get_field($i, $this->fields[0]['field_name']); + $rendered_field = $view->style_plugin->get_field($i, $this->fields[0]->field_name); $this->assertEqual(strlen($rendered_field), 3); } } public function _testMultipleFieldRender() { $view = views_get_view('test_view_fieldapi'); - $field_name = $this->fields[3]['field_name']; + $field_name = $this->fields[3]->field_name; // Test delta limit. $this->prepareView($view); @@ -150,7 +150,7 @@ public function _testMultipleFieldRender() { } // Test that an empty field is rendered without error. - $rendered_field = $view->style_plugin->get_field(4, $this->fields[4]['field_name']); + $rendered_field = $view->style_plugin->get_field(4, $this->fields[4]->field_name); $view->destroy(); diff --git a/core/modules/field/tests/modules/field_test/field_test.field.inc b/core/modules/field/tests/modules/field_test/field_test.field.inc index 7166f4b..28f2b55 100644 --- a/core/modules/field/tests/modules/field_test/field_test.field.inc +++ b/core/modules/field/tests/modules/field_test/field_test.field.inc @@ -77,7 +77,7 @@ function field_test_field_load($entity_type, $entities, $field, $instances, $lan foreach ($items as $id => $item) { // To keep the test non-intrusive, only act for instances with the // test_hook_field_load setting explicitly set to TRUE. - if (!empty($instances[$id]['settings']['test_hook_field_load'])) { + if (!empty($instances[$id]->settings['test_hook_field_load'])) { foreach ($item as $delta => $value) { // Don't add anything on empty values. if ($value) { diff --git a/core/modules/field/tests/modules/field_test/field_test.module b/core/modules/field/tests/modules/field_test/field_test.module index 03094dd..82661ed 100644 --- a/core/modules/field/tests/modules/field_test/field_test.module +++ b/core/modules/field/tests/modules/field_test/field_test.module @@ -96,7 +96,7 @@ function field_test_field_test_op_multiple($entity_type, $entities, $field, $ins // language. To verify this we try to access all the passed data structures // by entity id. If they are grouped correctly, one entity, one instance and // one array of items should be available for each entity id. - $field_name = $instances[$id]['field_name']; + $field_name = $instances[$id]->field_name; $result[$id] = array($langcode => hash('sha256', serialize(array($entity_type, $entity, $field_name, $langcode, $items[$id])))); } return $result; @@ -217,7 +217,7 @@ function field_test_field_attach_view_alter(&$output, $context) { */ function field_test_field_widget_properties_alter(&$widget, $context) { // Make the alter_test_text field 42 characters for nodes and comments. - if (in_array($context['entity_type'], array('node', 'comment')) && ($context['field']['field_name'] == 'alter_test_text')) { + if (in_array($context['entity_type'], array('node', 'comment')) && ($context['field']->field_name == 'alter_test_text')) { $widget['settings']['size'] = 42; } } @@ -227,7 +227,7 @@ function field_test_field_widget_properties_alter(&$widget, $context) { */ function field_test_field_widget_properties_user_alter(&$widget, $context) { // Always use buttons for the alter_test_options field on user forms. - if ($context['field']['field_name'] == 'alter_test_options') { + if ($context['field']->field_name == 'alter_test_options') { $widget['type'] = 'options_buttons'; } } @@ -236,7 +236,7 @@ function field_test_field_widget_properties_user_alter(&$widget, $context) { * Implements hook_field_widget_form_alter(). */ function field_test_field_widget_form_alter(&$element, &$form_state, $context) { - switch ($context['field']['field_name']) { + switch ($context['field']->field_name) { case 'alter_test_text': drupal_set_message('Field size: ' . $context['instance']->getWidget()->getSetting('size')); break; diff --git a/core/modules/field/tests/modules/field_test/field_test.storage.inc b/core/modules/field/tests/modules/field_test/field_test.storage.inc index a53b941..067e07d 100644 --- a/core/modules/field/tests/modules/field_test/field_test.storage.inc +++ b/core/modules/field/tests/modules/field_test/field_test.storage.inc @@ -89,7 +89,7 @@ function field_test_field_storage_load($entity_type, $entities, $age, $fields, $ foreach ($fields as $field_id => $ids) { $field = field_info_field_by_id($field_id); $field_name = $field['field_name']; - $field_data = $data[$field['id']]; + $field_data = $data[$field['uuid']]; $sub_table = $load_current ? 'current' : 'revisions'; $delta_count = array(); foreach ($field_data[$sub_table] as $row) { @@ -206,7 +206,7 @@ function field_test_field_storage_delete(EntityInterface $entity, $fields) { function field_test_field_storage_purge(EntityInterface $entity, $field, $instance) { $data = _field_test_storage_data(); - $field_data = &$data[$field['id']]; + $field_data = &$data[$field['uuid']]; foreach (array('current', 'revisions') as $sub_table) { foreach ($field_data[$sub_table] as $key => $row) { if ($row->type == $entity->entityType() && $row->entity_id == $entity->id()) { @@ -249,7 +249,7 @@ function field_test_field_storage_query($field_id, $conditions, $count, &$cursor $field = field_info_field_by_id($field_id); $field_columns = array_keys($field['columns']); - $field_data = $data[$field['id']]; + $field_data = $data[$field['uuid']]; $sub_table = $load_current ? 'current' : 'revisions'; // We need to sort records by entity type and entity id. usort($field_data[$sub_table], '_field_test_field_storage_query_sort_helper'); @@ -267,7 +267,7 @@ function field_test_field_storage_query($field_id, $conditions, $count, &$cursor break; } - if ($row->field_id == $field['id']) { + if ($row->field_id == $field['uuid']) { $match = TRUE; $condition_deleted = FALSE; // Add conditions. @@ -372,7 +372,7 @@ function field_test_field_storage_create_field($field) { $data = _field_test_storage_data(); - $data[$field['id']] = array( + $data[$field['uuid']] = array( 'current' => array(), 'revisions' => array(), ); @@ -386,7 +386,7 @@ function field_test_field_storage_create_field($field) { function field_test_field_storage_delete_field($field) { $data = _field_test_storage_data(); - $field_data = &$data[$field['id']]; + $field_data = &$data[$field['uuid']]; foreach (array('current', 'revisions') as $sub_table) { foreach ($field_data[$sub_table] as &$row) { $row->deleted = TRUE; @@ -403,7 +403,7 @@ function field_test_field_storage_delete_instance($instance) { $data = _field_test_storage_data(); $field = field_info_field($instance['field_name']); - $field_data = &$data[$field['id']]; + $field_data = &$data[$field['uuid']]; foreach (array('current', 'revisions') as $sub_table) { foreach ($field_data[$sub_table] as &$row) { if ($row->bundle == $instance['bundle']) { @@ -431,9 +431,9 @@ function field_test_field_attach_rename_bundle($bundle_old, $bundle_new) { // We need to account for deleted or inactive fields and instances. $instances = field_read_instances(array('bundle' => $bundle_new), array('include_deleted' => TRUE, 'include_inactive' => TRUE)); foreach ($instances as $field_name => $instance) { - $field = field_info_field_by_id($instance['field_id']); - if ($field['storage']['type'] == 'field_test_storage') { - $field_data = &$data[$field['id']]; + $field = field_info_field_by_id($instance['uuid']); + if ($field && $field['storage']['type'] == 'field_test_storage') { + $field_data = &$data[$field['uuid']]; foreach (array('current', 'revisions') as $sub_table) { foreach ($field_data[$sub_table] as &$row) { if ($row->bundle == $bundle_old) { @@ -454,9 +454,9 @@ function field_test_field_attach_delete_bundle($entity_type, $bundle, $instances $data = _field_test_storage_data(); foreach ($instances as $field_name => $instance) { - $field = field_info_field($field_name); - if ($field['storage']['type'] == 'field_test_storage') { - $field_data = &$data[$field['id']]; + $field = field_info_field($instance['field_name']); + if ($field && $field['storage']['type'] == 'field_test_storage') { + $field_data = &$data[$field['uuid']]; foreach (array('current', 'revisions') as $sub_table) { foreach ($field_data[$sub_table] as &$row) { if ($row->bundle == $bundle_old) { diff --git a/core/modules/field/tests/modules/field_test_config/config/field.field.field_test_import.yml b/core/modules/field/tests/modules/field_test_config/config/field.field.field_test_import.yml new file mode 100644 index 0000000..45afef5 --- /dev/null +++ b/core/modules/field/tests/modules/field_test_config/config/field.field.field_test_import.yml @@ -0,0 +1,49 @@ +id: field_test_import +uuid: fb38277f-1fd4-49d5-8d09-9d7037fdcce9 +field_name: field_test_import +type: text +translatable: false +entity_types: { } +cardinality: '1' +locked: false +settings: + max_length: '255' +module: text +active: 1 +deleted: 0 +storage_type: field_sql_storage +storage_module: field_sql_storage +storage_active: 1 +storage: + type: field_sql_storage + settings: { } + module: field_sql_storage + active: 1 + details: + sql: + FIELD_LOAD_CURRENT: + field_data_field_test_import: + value: field_test_import_value + format: field_test_import_format + FIELD_LOAD_REVISION: + field_revision_field_test_import: + value: field_test_import_value + format: field_test_import_format +columns: + value: + type: varchar + length: '255' + 'not null': false + format: + type: varchar + length: 255 + 'not null': false +'foreign_keys': + format: + table: filter_format + columns: + format: format +indexes: + format: + - format +langcode: und diff --git a/core/modules/field/tests/modules/field_test_config/config/field.instance.node.test_import.field_test_import.yml b/core/modules/field/tests/modules/field_test_config/config/field.instance.node.test_import.field_test_import.yml new file mode 100644 index 0000000..b125b8a --- /dev/null +++ b/core/modules/field/tests/modules/field_test_config/config/field.instance.node.test_import.field_test_import.yml @@ -0,0 +1,22 @@ +id: node.test_import.field_test_import +uuid: 392b4e9d-6157-412e-9603-3d622512f498 +field_name: field_test_import +entity_type: node +bundle: test_import +label: 'Test import field' +widget_settings: + weight: '-2' + type: text_textfield + module: text + active: 0 + settings: + size: '60' +field_id: fb38277f-1fd4-49d5-8d09-9d7037fdcce9 +settings: + text_processing: '0' + user_register_form: false +required: 0 +description: '' +deleted: 0 +default_value: null +langcode: und diff --git a/core/modules/field/tests/modules/field_test_config/field_test_config.info b/core/modules/field/tests/modules/field_test_config/field_test_config.info new file mode 100644 index 0000000..49b0509 --- /dev/null +++ b/core/modules/field/tests/modules/field_test_config/field_test_config.info @@ -0,0 +1,6 @@ +name = "Field API configuration tests" +description = "Support module for the Field API configuration tests." +core = 8.x +package = Testing +version = VERSION +hidden = TRUE diff --git a/core/modules/field/tests/modules/field_test_config/field_test_config.module b/core/modules/field/tests/modules/field_test_config/field_test_config.module new file mode 100644 index 0000000..e208464 --- /dev/null +++ b/core/modules/field/tests/modules/field_test_config/field_test_config.module @@ -0,0 +1,6 @@ + TRUE, 'include_inactive' => TRUE)); - drupal_load('module', 'field_sql_storage'); + // It's not safe to call field_read_fields() during maintenance mode. + if (!defined('MAINTENANCE_MODE')) { + $fields = entity_load_multiple('field_entity'); foreach ($fields as $field) { if ($field['storage']['type'] == 'field_sql_storage') { - $schema += _field_sql_storage_schema($field); + $schema += _field_sql_storage_schema((object) $field); } } } + return $schema; } @@ -113,8 +114,8 @@ function field_sql_storage_update_8000(&$sandbox) { // Update schema. foreach ($fields as $field) { - $data_table = _field_sql_storage_tablename($field); - $revision_table = _field_sql_storage_revision_tablename($field); + $data_table = _field_sql_storage_tablename((object) $field); + $revision_table = _field_sql_storage_revision_tablename((object) $field); $table_info = array($data_table => $primary_key_data, $revision_table => $primary_key_revision); foreach ($table_info as $table => $primary_key) { diff --git a/core/modules/field_sql_storage/field_sql_storage.module b/core/modules/field_sql_storage/field_sql_storage.module index accca35..29bfcf3 100644 --- a/core/modules/field_sql_storage/field_sql_storage.module +++ b/core/modules/field_sql_storage/field_sql_storage.module @@ -45,7 +45,7 @@ function field_sql_storage_field_storage_info() { */ function _field_sql_storage_tablename($field) { if ($field['deleted']) { - return "field_deleted_data_{$field['id']}"; + return "field_deleted_data_" . $field->generate_table_id(); } else { return "field_data_{$field['field_name']}"; @@ -63,7 +63,7 @@ function _field_sql_storage_tablename($field) { */ function _field_sql_storage_revision_tablename($field) { if ($field['deleted']) { - return "field_deleted_revision_{$field['id']}"; + return "field_deleted_revision_" . $field->generate_table_id(); } else { return "field_revision_{$field['field_name']}"; @@ -178,7 +178,13 @@ function _field_sql_storage_schema($field) { ), ); - $field += array('columns' => array(), 'indexes' => array(), 'foreign keys' => array()); + $schema_properties = array('columns' => array(), 'indexes' => array(), 'foreign keys' => array()); + foreach ($schema_properties as $key => $value) { + if (!isset($field->data[$key])) { + $field->data[$key] = $value; + } + } + // Add field columns. foreach ($field['columns'] as $column_name => $attributes) { $real_name = _field_sql_storage_columnname($field['field_name'], $column_name); @@ -204,7 +210,7 @@ function _field_sql_storage_schema($field) { } // Add foreign keys. - foreach ($field['foreign keys'] as $specifier => $specification) { + foreach ($field['foreign_keys'] as $specifier => $specification) { $real_name = _field_sql_storage_indexname($field['field_name'], $specifier); $current['foreign keys'][$real_name]['table'] = $specification['table']; foreach ($specification['columns'] as $column => $referenced) { diff --git a/core/modules/field_sql_storage/lib/Drupal/field_sql_storage/Tests/FieldSqlStorageTest.php b/core/modules/field_sql_storage/lib/Drupal/field_sql_storage/Tests/FieldSqlStorageTest.php index e79757e..0707bfc 100644 --- a/core/modules/field_sql_storage/lib/Drupal/field_sql_storage/Tests/FieldSqlStorageTest.php +++ b/core/modules/field_sql_storage/lib/Drupal/field_sql_storage/Tests/FieldSqlStorageTest.php @@ -413,7 +413,7 @@ function testFieldStorageDetails() { // Test current and revision storage details together because the columns // are the same. - foreach ((array) $this->field['columns'] as $column_name => $attributes) { + foreach ($this->field['columns'] as $column_name => $attributes) { $storage_column_name = _field_sql_storage_columnname($this->field['field_name'], $column_name); $this->assertEqual($details[FIELD_LOAD_CURRENT][$current][$column_name], $storage_column_name, t('Column name %value matches the definition in %bin.', array('%value' => $column_name, '%bin' => $current))); $this->assertEqual($details[FIELD_LOAD_REVISION][$revision][$column_name], $storage_column_name, t('Column name %value matches the definition in %bin.', array('%value' => $column_name, '%bin' => $revision))); @@ -431,8 +431,8 @@ function testFieldSqlStorageForeignKeys() { // Retrieve the field and instance with field_info and verify the foreign // keys are in place. $field = field_info_field($field_name); - $this->assertEqual($field['foreign keys']['format']['table'], 'filter_format', 'Foreign key table name preserved through CRUD'); - $this->assertEqual($field['foreign keys']['format']['columns']['format'], 'format', 'Foreign key column name preserved through CRUD'); + $this->assertEqual($field['foreign_keys']['format']['table'], 'filter_format', 'Foreign key table name preserved through CRUD'); + $this->assertEqual($field['foreign_keys']['format']['columns']['format'], 'format', 'Foreign key column name preserved through CRUD'); // Now grab the SQL schema and verify that too. $schema = drupal_get_schema(_field_sql_storage_tablename($field)); $this->assertEqual(count($schema['foreign keys']), 1, t("There is 1 foreign key in the schema")); diff --git a/core/modules/field_ui/field_ui.admin.inc b/core/modules/field_ui/field_ui.admin.inc index 566959b..8799386 100644 --- a/core/modules/field_ui/field_ui.admin.inc +++ b/core/modules/field_ui/field_ui.admin.inc @@ -5,7 +5,7 @@ * Administrative interface for custom field type creation. */ -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldInstance; use Drupal\field_ui\FieldOverview; use Drupal\field_ui\DisplayOverview; @@ -73,8 +73,8 @@ function field_ui_inactive_message($entity_type, $bundle) { $list[] = t('%field (@field_name) field requires the %widget_type widget provided by %widget_module module', array( '%field' => $instance['label'], '@field_name' => $instance['field_name'], - '%widget_type' => isset($widget_types[$instance['widget']['type']]) ? $widget_types[$instance['widget']['type']]['label'] : $instance['widget']['type'], - '%widget_module' => $instance['widget']['module'], + '%widget_type' => isset($widget_types[$instance['widget_settings']['type']]) ? $widget_types[$instance['widget_settings']['type']]['label'] : $instance['widget_settings']['type'], + '%widget_module' => $instance['widget_settings']['module'], )); } drupal_set_message(t('Inactive fields are not shown unless their providing modules are enabled. The following fields are not enabled: !list', array('!list' => theme('item_list', array('items' => $list)))), 'error'); @@ -477,7 +477,7 @@ function field_ui_existing_field_options($entity_type, $bundle) { 'type_label' => $field_types[$field['type']]['label'], 'field' => $field['field_name'], 'label' => $instance['label'], - 'widget_type' => $instance['widget']['type'], + 'widget_type' => $instance['widget_settings']['type'], ); } } @@ -615,7 +615,9 @@ function field_ui_field_settings_form_submit($form, &$form_state) { $instance = field_info_instance($entity_type, $field['field_name'], $bundle); // Update the field. - $field = array_merge($field, $field_values); + foreach ($field_values as $key => $value) { + $field->{$key} = $value; + } try { field_update_field($field); @@ -685,8 +687,8 @@ function field_ui_widget_type_form_submit($form, &$form_state) { $widget_type = field_info_widget_types($form_values['widget_type']); $widget_module = $widget_type['module']; - $instance['widget']['type'] = $form_values['widget_type']; - $instance['widget']['module'] = $widget_module; + $instance['widget_settings']['type'] = $form_values['widget_type']; + $instance['widget_settings']['module'] = $widget_module; try { field_update_instance($instance); @@ -804,7 +806,7 @@ function field_ui_field_edit_form($form, &$form_state, $instance) { return $form; } - $widget_type = field_info_widget_types($instance['widget']['type']); + $widget_type = field_info_widget_types($instance['widget_settings']['type']); // Create a form structure for the instance values. $form['instance'] = array( @@ -824,9 +826,9 @@ function field_ui_field_edit_form($form, &$form_state, $instance) { '#type' => 'value', '#value' => $bundle, ); - $form['instance']['widget']['weight'] = array( + $form['instance']['widget_settings']['weight'] = array( '#type' => 'value', - '#value' => !empty($instance['widget']['weight']) ? $instance['widget']['weight'] : 0, + '#value' => !empty($instance['widget_settings']['weight']) ? $instance['widget_settings']['weight'] : 0, ); // Build the configurable instance values. @@ -841,7 +843,7 @@ function field_ui_field_edit_form($form, &$form_state, $instance) { $form['instance']['description'] = array( '#type' => 'textarea', '#title' => t('Help text'), - '#default_value' => !empty($instance['description']) ? $instance['description'] : '', + '#default_value' => !empty($instance->description) ? $instance->description : '', '#rows' => 5, '#description' => t('Instructions to present to the user below this field on the editing form.
Allowed HTML tags: @tags', array('@tags' => _field_filter_xss_display_allowed_tags())) . '
' . t('This field supports tokens.'), '#weight' => -10, @@ -855,17 +857,17 @@ function field_ui_field_edit_form($form, &$form_state, $instance) { ); // Build the widget component of the instance. - $form['instance']['widget']['type'] = array( + $form['instance']['widget_settings']['type'] = array( '#type' => 'value', - '#value' => $instance['widget']['type'], + '#value' => $instance['widget_settings']['type'], ); - $form['instance']['widget']['module'] = array( + $form['instance']['widget_settings']['module'] = array( '#type' => 'value', '#value' => $widget_type['module'], ); - $form['instance']['widget']['active'] = array( + $form['instance']['widget_settings']['active'] = array( '#type' => 'value', - '#value' => !empty($field['instance']['widget']['active']) ? 1 : 0, + '#value' => !empty($instance['widget_settings']['active']) ? 1 : 0, // straight bug ? ); // Add additional field instance settings from the field module. @@ -877,8 +879,8 @@ function field_ui_field_edit_form($form, &$form_state, $instance) { // Add widget settings for the widget type. $additions = $instance->getWidget()->settingsForm($form, $form_state); - $form['instance']['widget']['settings'] = $additions ? $additions : array('#type' => 'value', '#value' => array()); - $form['instance']['widget']['#weight'] = 20; + $form['instance']['widget_settings']['settings'] = $additions ? $additions : array('#type' => 'value', '#value' => array()); + $form['instance']['widget_settings']['#weight'] = 20; // Add handling for default value if not provided by any other module. if (field_behaviors_widget('default_value', $instance) == FIELD_BEHAVIOR_DEFAULT && empty($instance['default_value_function'])) { @@ -932,11 +934,14 @@ function field_ui_default_value_widget($field, $instance, &$form, &$form_state) // Adjust the instance definition used for the form element. We want a // non-required input and no description. $instance['required'] = FALSE; - $instance['description'] = ''; + $instance->description = ''; // Insert the widget. Since we do not use the "official" instance definition, // the whole flow cannot use field_invoke_method(). - $items = (array) $instance['default_value']; + $items = array(); + if (!empty($instance['default_value'])) { + $items = (array) $instance['default_value']; + } $element += $instance->getWidget()->form($entity, LANGUAGE_NOT_SPECIFIED, $items, $element, $form_state); return $element; @@ -1007,7 +1012,7 @@ function field_ui_field_edit_form_submit($form, &$form_state) { // Merge incoming values into the instance. foreach ($form_state['values']['instance'] as $key => $value) { - $instance[$key] = $value; + $instance->$key = $value; } field_update_instance($instance); diff --git a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php index 925caef..7c37adb 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php @@ -106,7 +106,7 @@ public function buildForm(array $form, array &$form_state) { '#type' => 'textfield', '#title' => t('Weight for @title', array('@title' => $instance['label'])), '#title_display' => 'invisible', - '#default_value' => $instance['widget']['weight'], + '#default_value' => $instance['widget_settings']['weight'], '#size' => 3, '#attributes' => array('class' => array('field-weight')), ), @@ -137,7 +137,7 @@ public function buildForm(array $form, array &$form_state) { ), 'widget_type' => array( '#type' => 'link', - '#title' => t($widget_types[$instance['widget']['type']]['label']), + '#title' => t($widget_types[$instance['widget_settings']['type']]['label']), '#href' => $admin_field_path . '/widget-type', '#options' => array('attributes' => array('title' => t('Change widget type.'))), ), @@ -159,7 +159,7 @@ public function buildForm(array $form, array &$form_state) { '#links' => $links, ); - if (!empty($instance['locked'])) { + if (!empty($instance->locked)) { $table[$name]['operations'] = array('#value' => t('Locked')); $table[$name]['#attributes']['class'][] = 'menu-disabled'; } @@ -535,7 +535,7 @@ public function submitForm(array &$form, array &$form_state) { foreach ($form_values as $key => $values) { if (in_array($key, $form['#fields'])) { $instance = field_read_instance($this->entity_type, $key, $this->bundle); - $instance['widget']['weight'] = $values['weight']; + $instance['widget_settings']['weight'] = $values['weight']; field_update_instance($instance); } elseif (in_array($key, $form['#extra'])) { @@ -570,7 +570,7 @@ public function submitForm(array &$form, array &$form_state) { // Create the field and instance. try { - field_create_field($field); + $field = field_create_field($field); field_create_instance($instance); // Make sure the field is displayed in the 'default' view mode (using @@ -606,7 +606,7 @@ public function submitForm(array &$form, array &$form_state) { 'entity_type' => $this->entity_type, 'bundle' => $this->bundle, 'label' => $values['label'], - 'widget' => array( + 'widget_settings' => array( 'type' => $values['widget_type'], 'weight' => $values['weight'], ), diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/AlterTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/AlterTest.php index 016b9d0..83fc15c 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/AlterTest.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/AlterTest.php @@ -58,7 +58,7 @@ function testDefaultWidgetPropertiesAlter() { 'field_name' => 'alter_test_text', 'entity_type' => 'node', 'bundle' => 'article', - 'widget' => array( + 'widget_settings' => array( 'type' => 'text_textfield', 'size' => 60, ), @@ -84,7 +84,7 @@ function testDefaultWidgetPropertiesAlter() { 'field_name' => 'alter_test_options', 'entity_type' => 'user', 'bundle' => 'user', - 'widget' => array( + 'widget_settings' => array( 'type' => 'options_select', ) ); @@ -93,7 +93,7 @@ function testDefaultWidgetPropertiesAlter() { 'field_name' => 'alter_test_options', 'entity_type' => 'node', 'bundle' => 'page', - 'widget' => array( + 'widget_settings' => array( 'type' => 'options_select', ) ); diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php index 45de66e..ee421d6 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php @@ -180,7 +180,7 @@ function testNonInitializedFields() { // Check that no settings have been set for the 'teaser' mode. $instance = field_info_instance('node', 'field_test', $this->type); - $this->assertFalse(isset($instance['display']['teaser'])); + $this->assertFalse(isset($instance->display['teaser'])); // Check that the field appears as 'hidden' on the 'Manage display' page // for the 'teaser' mode. diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php index cbc132f..b14eb3a 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php @@ -137,7 +137,7 @@ function updateField() { $this->drupalGet('admin/structure/types/manage/' . $this->type . '/fields/' . $this->field_name); $edit = array( 'instance[settings][test_instance_setting]' => $string, - 'instance[widget][settings][test_widget_setting]' => $string, + 'instance[widget_settings][settings][test_widget_setting]' => $string, ); $this->drupalPost(NULL, $edit, t('Save settings')); @@ -234,7 +234,7 @@ function assertFieldSettings($bundle, $field_name, $string = 'dummy test string' // Assert instance and widget settings. $instance = field_info_instance($entity_type, $field_name, $bundle); $this->assertTrue($instance['settings']['test_instance_setting'] == $string, 'Field instance settings were found.'); - $this->assertTrue($instance['widget']['settings']['test_widget_setting'] == $string, 'Field widget settings were found.'); + $this->assertTrue($instance['widget_settings']['settings']['test_widget_setting'] == $string, 'Field widget settings were found.'); } /** @@ -287,7 +287,7 @@ function testDefaultValue() { $this->assertEqual($instance['default_value'], NULL, 'The default value was correctly saved.'); // Change the widget to TestFieldWidgetNoDefault. - $instance['widget']['type'] = 'test_field_widget_no_default'; + $instance['widget_settings']['type'] = 'test_field_widget_no_default'; field_update_instance($instance); $this->drupalGet($admin_path); @@ -358,7 +358,7 @@ function testHiddenFields() { 'bundle' => $this->type, 'entity_type' => 'node', 'label' => t('Hidden field'), - 'widget' => array('type' => 'test_field_widget'), + 'widget_settings' => array('type' => 'test_field_widget'), ); field_create_instance($instance); $this->assertTrue(field_read_instance('node', $field_name, $this->type), format_string('An instance of the field %field was created programmatically.', array('%field' => $field_name))); @@ -417,7 +417,7 @@ function testWidgetChange() { // Check that the field_tags field currently uses the 'options_select' // widget. $instance = field_info_instance('node', 'field_tags', 'article'); - $this->assertEqual($instance['widget']['type'], 'options_select'); + $this->assertEqual($instance['widget_settings']['type'], 'options_select'); // Check that the "Manage fields" page shows the correct widget type. $this->drupalGet($url_fields); @@ -442,7 +442,7 @@ function testWidgetChange() { // Check that the field uses the newly set widget. field_cache_clear(); $instance = field_info_instance('node', 'field_tags', 'article'); - $this->assertEqual($instance['widget']['type'], 'options_buttons'); + $this->assertEqual($instance['widget_settings']['type'], 'options_buttons'); // Go to the 'Widget type' form and check that the correct widget is // selected. diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc index e3a7d7c..e61ff72 100644 --- a/core/modules/file/file.field.inc +++ b/core/modules/file/file.field.inc @@ -409,7 +409,7 @@ function file_field_widget_process($element, &$form_state, $form) { $field = field_widget_field($element, $form_state); $instance = field_widget_instance($element, $form_state); - $settings = $instance['widget']['settings']; + $settings = $instance['widget_settings']['settings']; $element['#theme'] = 'file_widget'; @@ -768,7 +768,7 @@ function theme_file_upload_help($variables) { * fid, FALSE if it doesn't. */ function file_field_find_file_reference_column($field) { - foreach ($field['foreign keys'] as $data) { + foreach ($field['foreign_keys'] as $data) { if ($data['table'] == 'file_managed') { foreach ($data['columns'] as $field_column => $column) { if ($column == 'fid') { diff --git a/core/modules/file/file.install b/core/modules/file/file.install index 27a2438..472f7e5 100644 --- a/core/modules/file/file.install +++ b/core/modules/file/file.install @@ -125,8 +125,8 @@ function file_schema() { ), 'id' => array( 'description' => 'The primary key of the object using the file.', - 'type' => 'int', - 'unsigned' => TRUE, + 'type' => 'varchar', + 'length' => 64, 'not null' => TRUE, 'default' => 0, ), @@ -234,6 +234,21 @@ function file_requirements($phase) { } /** + * Implements hook_update_dependencies(). + */ +function file_update_dependencies() { + // The update hook to convert the id column in the column table needs to be + // the first one because user update hooks will be called during system + // update hooks due to other dependencies and the user picture conversion + // might need to save a default image and the field it's stored in, does + // not have an integer id anymore. + $dependencies['system'][8001] = array( + 'file' => 8001, + ); + return $dependencies; +} + +/** * Converts default_file_main variable to config. * * @ingroup config_upgrade @@ -245,3 +260,17 @@ function file_update_8000() { 'file_icon_directory'=>'icon.directory', )); } + +/** + * Convert the id column in file_usage to store UUID's. + */ +function file_update_8001() { + $spec = array( + 'description' => 'The primary key of the object using the file.', + 'type' => 'varchar', + 'length' => 64, + 'not null' => TRUE, + 'default' => '', + ); + db_change_field('file_usage', 'id', 'id', $spec); +} diff --git a/core/modules/file/lib/Drupal/file/Plugin/field/widget/FileWidget.php b/core/modules/file/lib/Drupal/file/Plugin/field/widget/FileWidget.php index 98a7a96..fc34592 100644 --- a/core/modules/file/lib/Drupal/file/Plugin/field/widget/FileWidget.php +++ b/core/modules/file/lib/Drupal/file/Plugin/field/widget/FileWidget.php @@ -86,7 +86,7 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $ $wrapper_id = drupal_html_id($id_prefix . '-add-more-wrapper'); $title = check_plain($instance['label']); - $description = field_filter_xss($instance['description']); + $description = field_filter_xss($instance->description); $elements = array(); diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php index 52df6f2..369c552 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php @@ -101,13 +101,13 @@ function attachFileField($name, $entity_type, $bundle, $instance_settings = arra 'bundle' => $bundle, 'required' => !empty($instance_settings['required']), 'settings' => array(), - 'widget' => array( + 'widget_settings' => array( 'type' => 'file_generic', 'settings' => array(), ), ); $instance['settings'] = array_merge($instance['settings'], $instance_settings); - $instance['widget']['settings'] = array_merge($instance['widget']['settings'], $widget_settings); + $instance['widget_settings']['settings'] = array_merge($instance['widget_settings']['settings'], $widget_settings); field_create_instance($instance); } @@ -117,7 +117,7 @@ function attachFileField($name, $entity_type, $bundle, $instance_settings = arra function updateFileField($name, $type_name, $instance_settings = array(), $widget_settings = array()) { $instance = field_info_instance('node', $name, $type_name); $instance['settings'] = array_merge($instance['settings'], $instance_settings); - $instance['widget']['settings'] = array_merge($instance['widget']['settings'], $widget_settings); + $instance['widget_settings']['settings'] = array_merge($instance['widget_settings']['settings'], $widget_settings); field_update_instance($instance); } diff --git a/core/modules/forum/forum.install b/core/modules/forum/forum.install index b1e63de..3173cfb 100644 --- a/core/modules/forum/forum.install +++ b/core/modules/forum/forum.install @@ -22,10 +22,6 @@ function forum_install() { * Implements hook_enable(). */ function forum_enable() { - // If we enable forum at the same time as taxonomy we need to call - // field_associate_fields() as otherwise the field won't be enabled until - // hook modules_enabled is called which takes place after hook_enable events. - field_associate_fields('taxonomy'); // Create the forum vocabulary if it does not exist. // @todo Change Forum module so forum.settings can contain the vocabulary's @@ -55,7 +51,7 @@ function forum_enable() { } // Create the 'taxonomy_forums' field if it doesn't already exist. - if (!field_info_field('taxonomy_forums')) { + if (!field_read_field('taxonomy_forums', array('include_inactive' => TRUE))) { $field = array( 'field_name' => 'taxonomy_forums', 'type' => 'taxonomy_term_reference', diff --git a/core/modules/image/image.field.inc b/core/modules/image/image.field.inc index 11152ae..16f8d21 100644 --- a/core/modules/image/image.field.inc +++ b/core/modules/image/image.field.inc @@ -232,8 +232,8 @@ function image_field_prepare_view($entity_type, $entities, $field, $instances, $ if (empty($items[$id])) { $fid = 0; // Use the default for the instance if one is available. - if (!empty($instances[$id]['settings']['default_image'])) { - $fid = $instances[$id]['settings']['default_image']; + if (!empty($instances[$id]->settings['default_image'])) { + $fid = $instances[$id]->settings['default_image']; } // Otherwise, use the default for the field. elseif (!empty($field['settings']['default_image'])) { diff --git a/core/modules/image/image.module b/core/modules/image/image.module index d7b02d0..b0586b8 100644 --- a/core/modules/image/image.module +++ b/core/modules/image/image.module @@ -351,7 +351,7 @@ function image_image_style_update(ImageStyle $style) { $instances = field_read_instances(); // Loop through all fields searching for image fields. foreach ($instances as $instance) { - if ($instance['widget']['module'] == 'image') { + if ($instance['widget_settings']['module'] == 'image') { $view_modes = entity_get_view_modes($instance['entity_type']); $view_modes = array('default') + array_keys($view_modes); foreach ($view_modes as $view_mode) { @@ -367,8 +367,8 @@ function image_image_style_update(ImageStyle $style) { ->save(); } } - if ($instance['widget']['settings']['preview_image_style'] == $style->getOriginalID()) { - $instance['widget']['settings']['preview_image_style'] = $style->id(); + if ($instance['widget_settings']['settings']['preview_image_style'] == $style->getOriginalID()) { + $instance['widget_settings']['settings']['preview_image_style'] = $style->id(); field_update_instance($instance); } } @@ -427,12 +427,12 @@ function image_field_update_field($field, $prior_field, $has_data) { if ($file_new) { $file_new->status = FILE_STATUS_PERMANENT; $file_new->save(); - file_usage()->add($file_new, 'image', 'default_image', $field['id']); + file_usage()->add($file_new, 'image', 'default_image', $field['uuid']); } // Is there an old file? if ($fid_old && ($file_old = file_load($fid_old))) { - file_usage()->delete($file_old, 'image', 'default_image', $field['id']); + file_usage()->delete($file_old, 'image', 'default_image', $field['uuid']); } } @@ -495,11 +495,11 @@ function image_field_update_instance($instance, $prior_instance) { if ($file_new) { $file_new->status = FILE_STATUS_PERMANENT; $file_new->save(); - file_usage()->add($file_new, 'image', 'default_image', $instance['id']); + file_usage()->add($file_new, 'image', 'default_image', $instance['uuid']); } // Delete the old file, if present. if ($fid_old && ($file_old = file_load($fid_old))) { - file_usage()->delete($file_old, 'image', 'default_image', $instance['id']); + file_usage()->delete($file_old, 'image', 'default_image', $instance['uuid']); } } diff --git a/core/modules/image/lib/Drupal/image/Plugin/field/widget/ImageWidget.php b/core/modules/image/lib/Drupal/image/Plugin/field/widget/ImageWidget.php index 35cb3fa..078bc10 100644 --- a/core/modules/image/lib/Drupal/image/Plugin/field/widget/ImageWidget.php +++ b/core/modules/image/lib/Drupal/image/Plugin/field/widget/ImageWidget.php @@ -62,7 +62,7 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $ if ($this->field['cardinality'] == 1) { // If there's only one field, return it as delta 0. if (empty($elements[0]['#default_value']['fid'])) { - $elements[0]['#description'] = theme('file_upload_help', array('description' => $this->instance['description'], 'upload_validators' => $elements[0]['#upload_validators'])); + $elements[0]['#description'] = theme('file_upload_help', array('description' => $this->instance->description, 'upload_validators' => $elements[0]['#upload_validators'])); } } else { diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php index 01fa5f4..47348e7 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDefaultImagesTest.php @@ -65,7 +65,7 @@ function testDefaultImages() { 'settings' => array( 'default_image' => $default_images['instance2']->fid, ), - 'widget' => $instance['widget'], + 'widget_settings' => $instance['widget_settings'], ); field_create_instance($instance2); $instance2 = field_info_instance('node', $field_name, 'page'); diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php index 7c42a5b..a361ca7 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php @@ -146,8 +146,8 @@ function testImageFieldSettings() { $widget_settings = array( 'preview_image_style' => 'medium', ); - $field = $this->createImageField($field_name, 'article', array(), $instance_settings, $widget_settings); - $field['deleted'] = 0; + $this->createImageField($field_name, 'article', array(), $instance_settings, $widget_settings); + $field = field_info_field($field_name); $table = _field_sql_storage_tablename($field); $schema = drupal_get_schema($table, TRUE); $instance = field_info_instance('node', $field_name, 'article'); diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php index 5a4e20e..26d44b2 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php @@ -85,13 +85,13 @@ function createImageField($name, $type_name, $field_settings = array(), $instanc 'required' => !empty($instance_settings['required']), 'description' => !empty($instance_settings['description']) ? $instance_settings['description'] : '', 'settings' => array(), - 'widget' => array( + 'widget_settings' => array( 'type' => 'image_image', 'settings' => array(), ), ); $instance['settings'] = array_merge($instance['settings'], $instance_settings); - $instance['widget']['settings'] = array_merge($instance['widget']['settings'], $widget_settings); + $instance['widget_settings']['settings'] = array_merge($instance['widget_settings']['settings'], $widget_settings); $field_instance = field_create_instance($instance); diff --git a/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php b/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php index a608873..4707251 100644 --- a/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php +++ b/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php @@ -48,7 +48,7 @@ function testURLValidation() { 'field_name' => drupal_strtolower($this->randomName()), 'type' => 'link', ); - field_create_field($this->field); + $this->field = field_create_field($this->field); $this->instance = array( 'field_name' => $this->field['field_name'], 'entity_type' => 'test_entity', @@ -56,14 +56,14 @@ function testURLValidation() { 'settings' => array( 'title' => DRUPAL_DISABLED, ), - 'widget' => array( + 'widget_settings' => array( 'type' => 'link_default', 'settings' => array( 'placeholder_url' => 'http://example.com', ), ), ); - field_create_instance($this->instance); + $this->instance = field_create_instance($this->instance); entity_get_display('test_entity', 'test_bundle', 'full') ->setComponent($this->field['field_name'], array( 'type' => 'link', @@ -116,7 +116,7 @@ function testLinkTitle() { 'field_name' => drupal_strtolower($this->randomName()), 'type' => 'link', ); - field_create_field($this->field); + $this->field = field_create_field($this->field); $this->instance = array( 'field_name' => $this->field['field_name'], 'entity_type' => 'test_entity', @@ -124,7 +124,7 @@ function testLinkTitle() { 'settings' => array( 'title' => DRUPAL_OPTIONAL, ), - 'widget' => array( + 'widget_settings' => array( 'type' => 'link_default', 'settings' => array( 'placeholder_url' => 'http://example.com', @@ -132,7 +132,7 @@ function testLinkTitle() { ), ), ); - field_create_instance($this->instance); + $this->instance = field_create_instance($this->instance); entity_get_display('test_entity', 'test_bundle', 'full') ->setComponent($this->field['field_name'], array( 'type' => 'link', @@ -226,7 +226,7 @@ function testLinkFormatter() { 'type' => 'link', 'cardinality' => 2, ); - field_create_field($this->field); + $this->field = field_create_field($this->field); $this->instance = array( 'field_name' => $this->field['field_name'], 'entity_type' => 'test_entity', @@ -234,7 +234,7 @@ function testLinkFormatter() { 'settings' => array( 'title' => DRUPAL_OPTIONAL, ), - 'widget' => array( + 'widget_settings' => array( 'type' => 'link_default', ), ); @@ -362,7 +362,7 @@ function testLinkSeparateFormatter() { 'type' => 'link', 'cardinality' => 2, ); - field_create_field($this->field); + $this->field = field_create_field($this->field); $this->instance = array( 'field_name' => $this->field['field_name'], 'entity_type' => 'test_entity', @@ -370,7 +370,7 @@ function testLinkSeparateFormatter() { 'settings' => array( 'title' => DRUPAL_OPTIONAL, ), - 'widget' => array( + 'widget_settings' => array( 'type' => 'link_default', ), ); diff --git a/core/modules/link/link.module b/core/modules/link/link.module index f8ee409..8b28bed 100644 --- a/core/modules/link/link.module +++ b/core/modules/link/link.module @@ -111,7 +111,7 @@ function link_field_widget_info() { * Implements hook_field_widget_settings_form(). */ function link_field_widget_settings_form($field, $instance) { - $widget = $instance['widget']; + $widget = $instance['widget_settings']; $settings = $widget['settings']; $form['placeholder_url'] = array( @@ -140,7 +140,7 @@ function link_field_widget_settings_form($field, $instance) { */ function link_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { $settings = $instance['settings']; - $widget_settings = $instance['widget']['settings']; + $widget_settings = $instance['widget_settings']['settings']; $element['url'] = array( '#type' => 'url', @@ -289,7 +289,7 @@ function link_field_formatter_settings_form($field, $instance, $view_mode, $form * Implements hook_field_formatter_settings_form(). */ function link_field_formatter_settings_summary($field, $instance, $view_mode) { - $display = $instance['display'][$view_mode]; + $display = $instance->display[$view_mode]; $settings = $display['settings']; $summary = array(); diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php index a7f4f88..d6461e3 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php +++ b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php @@ -280,7 +280,7 @@ protected function build_filters(&$form, &$form_state) { foreach (field_info_instances($this->entity_type, $bundle) as $instance) { // We define "tag-like" taxonomy fields as ones that use the // "Autocomplete term widget (tagging)" widget. - if ($instance['widget']['type'] == 'taxonomy_autocomplete') { + if ($instance['widget_settings']['type'] == 'taxonomy_autocomplete') { $tag_fields[] = $instance['field_name']; } } diff --git a/core/modules/node/lib/Drupal/node/Tests/Condition/NodeConditionTest.php b/core/modules/node/lib/Drupal/node/Tests/Condition/NodeConditionTest.php index addc5c0..24b8b8b 100644 --- a/core/modules/node/lib/Drupal/node/Tests/Condition/NodeConditionTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/Condition/NodeConditionTest.php @@ -30,8 +30,6 @@ protected function setUp() { $this->installSchema('node', 'node_type'); $this->installSchema('node', 'node'); $this->installSchema('node', 'node_revision'); - $this->installSchema('field', 'field_config'); - $this->installSchema('field', 'field_config_instance'); } /** diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php index 6ea519a..0edf92f 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php @@ -60,7 +60,7 @@ function setUp() { // Make node body translatable. $field = field_info_field('body'); - $field['translatable'] = TRUE; + $instance['translatable'] = TRUE; field_update_field($field); } diff --git a/core/modules/node/node.module b/core/modules/node/node.module index ad79f6d..8b972bd 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -588,7 +588,7 @@ function node_add_body_field($type, $label = 'Body') { 'entity_type' => 'node', 'bundle' => $type->type, 'label' => $label, - 'widget' => array('type' => 'text_textarea_with_summary'), + 'widget_settings' => array('type' => 'text_textarea_with_summary'), 'settings' => array('display_summary' => TRUE), ); $instance = field_create_instance($instance); diff --git a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php index 925828c..aae61e9 100644 --- a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php +++ b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php @@ -52,22 +52,17 @@ function testNumberDecimalField() { 'precision' => 8, 'scale' => 4, 'decimal_separator' => '.', ) ); - field_create_field($this->field); + $this->field = field_create_field($this->field); $this->instance = array( 'field_name' => $this->field['field_name'], 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( + 'widget_settings' => array( 'type' => 'number', 'settings' => array( 'placeholder' => '0.00' ), ), - 'display' => array( - 'default' => array( - 'type' => 'number_decimal', - ), - ), ); field_create_instance($this->instance); entity_get_display('test_entity', 'test_bundle', 'default') diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldTest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldTest.php index e715f55..01be302 100644 --- a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldTest.php +++ b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldTest.php @@ -46,13 +46,14 @@ function setUp() { 'allowed_values' => array(1 => 'One', 2 => 'Two', 3 => 'Three'), ), ); + $this->field_definition = $this->field; $this->field = field_create_field($this->field); $this->instance = array( 'field_name' => $this->field_name, 'entity_type' => 'entity_test', 'bundle' => 'entity_test', - 'widget' => array( + 'widget_settings' => array( 'type' => 'options_buttons', ), ); @@ -110,18 +111,16 @@ function testUpdateAllowedValues() { // Options are reset when a new field with the same name is created. field_delete_field($this->field_name); - unset($this->field['id']); - $this->field['settings']['allowed_values'] = array(1 => 'One', 2 => 'Two', 3 => 'Three'); - $this->field = field_create_field($this->field); + $field = field_create_field($this->field_definition); $this->instance = array( - 'field_name' => $this->field_name, + 'field_name' => $field['field_name'], 'entity_type' => 'entity_test', 'bundle' => 'entity_test', - 'widget' => array( + 'widget_settings' => array( 'type' => 'options_buttons', ), ); - $this->instance = field_create_instance($this->instance); + field_create_instance($this->instance); $entity = entity_create('entity_test', array()); $form = entity_get_form($entity); $this->assertTrue(!empty($form[$this->field_name][$langcode][1]), 'Option 1 exists'); diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php index 023f012..eadd0c8 100644 --- a/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php +++ b/core/modules/options/lib/Drupal/options/Tests/OptionsWidgetsTest.php @@ -79,10 +79,10 @@ function setUp() { function testRadioButtons() { // Create an instance of the 'single value' field. $instance = array( - 'field_name' => $this->card_1['field_name'], + 'field_name' => $this->card_1->field_name, 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( + 'widget_settings' => array( 'type' => 'options_buttons', ), ); @@ -119,7 +119,7 @@ function testRadioButtons() { $this->assertFieldValues($entity_init, 'card_1', $langcode, array()); // Check that required radios with one option is auto-selected. - $this->card_1['settings']['allowed_values'] = array(99 => 'Only allowed value'); + $this->card_1->settings['allowed_values'] = array(99 => 'Only allowed value'); field_update_field($this->card_1); $instance['required'] = TRUE; field_update_instance($instance); @@ -133,10 +133,10 @@ function testRadioButtons() { function testCheckBoxes() { // Create an instance of the 'multiple values' field. $instance = array( - 'field_name' => $this->card_2['field_name'], + 'field_name' => $this->card_2->field_name, 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( + 'widget_settings' => array( 'type' => 'options_buttons', ), ); @@ -206,7 +206,7 @@ function testCheckBoxes() { $this->assertFieldValues($entity_init, 'card_2', $langcode, array()); // Required checkbox with one option is auto-selected. - $this->card_2['settings']['allowed_values'] = array(99 => 'Only allowed value'); + $this->card_2->settings['allowed_values'] = array(99 => 'Only allowed value'); field_update_field($this->card_2); $instance['required'] = TRUE; field_update_instance($instance); @@ -220,11 +220,11 @@ function testCheckBoxes() { function testSelectListSingle() { // Create an instance of the 'single value' field. $instance = array( - 'field_name' => $this->card_1['field_name'], + 'field_name' => $this->card_1->field_name, 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', 'required' => TRUE, - 'widget' => array( + 'widget_settings' => array( 'type' => 'options_select', ), ); @@ -282,8 +282,8 @@ function testSelectListSingle() { // Test optgroups. - $this->card_1['settings']['allowed_values'] = array(); - $this->card_1['settings']['allowed_values_function'] = 'options_test_allowed_values_callback'; + $this->card_1->settings['allowed_values'] = array(); + $this->card_1->settings['allowed_values_function'] = 'options_test_allowed_values_callback'; field_update_field($this->card_1); // Display form: with no field data, nothing is selected @@ -317,10 +317,10 @@ function testSelectListSingle() { function testSelectListMultiple() { // Create an instance of the 'multiple values' field. $instance = array( - 'field_name' => $this->card_2['field_name'], + 'field_name' => $this->card_2->field_name, 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( + 'widget_settings' => array( 'type' => 'options_select', ), ); @@ -397,8 +397,8 @@ function testSelectListMultiple() { // Test optgroups. // Use a callback function defining optgroups. - $this->card_2['settings']['allowed_values'] = array(); - $this->card_2['settings']['allowed_values_function'] = 'options_test_allowed_values_callback'; + $this->card_2->settings['allowed_values'] = array(); + $this->card_2->settings['allowed_values_function'] = 'options_test_allowed_values_callback'; field_update_field($this->card_2); $instance['required'] = FALSE; field_update_instance($instance); @@ -434,10 +434,10 @@ function testSelectListMultiple() { function testOnOffCheckbox() { // Create an instance of the 'boolean' field. $instance = array( - 'field_name' => $this->bool['field_name'], + 'field_name' => $this->bool->field_name, 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', - 'widget' => array( + 'widget_settings' => array( 'type' => 'options_onoff', ), ); @@ -482,13 +482,13 @@ function testOnOffCheckbox() { // Create a test field instance. $fieldUpdate = $this->bool; - $fieldUpdate['settings']['allowed_values'] = array(0 => 0, 1 => 'MyOnValue'); + $fieldUpdate->settings['allowed_values'] = array(0 => 0, 1 => 'MyOnValue'); field_update_field($fieldUpdate); $instance = array( - 'field_name' => $this->bool['field_name'], + 'field_name' => $this->bool->field_name, 'entity_type' => 'node', 'bundle' => 'page', - 'widget' => array( + 'widget_settings' => array( 'type' => 'options_onoff', 'module' => 'options', ), @@ -505,13 +505,13 @@ function testOnOffCheckbox() { ); $this->assertFieldByXPath( - '*//label[@for="edit-' . $this->bool['field_name'] . '-und" and text()="MyOnValue"]', + '*//label[@for="edit-' . $this->bool->field_name . '-und" and text()="MyOnValue"]', TRUE, t('Default case shows "On value"') ); // Enable setting - $edit = array('instance[widget][settings][display_label]' => 1); + $edit = array('instance[widget_settings][settings][display_label]' => 1); // Save the new Settings $this->drupalPost($fieldEditUrl, $edit, t('Save settings')); @@ -523,11 +523,11 @@ function testOnOffCheckbox() { t('Display setting checkbox is available') ); $this->assertFieldChecked( - 'edit-instance-widget-settings-display-label', + 'edit-instance-widget-settings-settings-display-label', t('Display settings checkbox checked') ); $this->assertFieldByXPath( - '*//label[@for="edit-' . $this->bool['field_name'] . '-und" and text()="' . $this->bool['field_name'] . '"]', + '*//label[@for="edit-' . $this->bool->field_name . '-und" and text()="' . $this->bool->field_name . '"]', TRUE, t('Display label changes label of the checkbox') ); diff --git a/core/modules/options/options.module b/core/modules/options/options.module index 793b07e..00f85ae 100644 --- a/core/modules/options/options.module +++ b/core/modules/options/options.module @@ -151,10 +151,10 @@ function options_field_settings_form($field, $instance, $has_data) { } // Alter the description for allowed values depending on the widget type. - if ($instance['widget']['type'] == 'options_onoff') { + if ($instance['widget_settings']['type'] == 'options_onoff') { $form['allowed_values']['#description'] .= '

' . t("For a 'single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the Allowed values section. Note that the checkbox will be labeled with the label of the 'on' value.") . '

'; } - elseif ($instance['widget']['type'] == 'options_buttons') { + elseif ($instance['widget_settings']['type'] == 'options_buttons') { $form['allowed_values']['#description'] .= '

' . t("The 'checkboxes/radio buttons' widget will display checkboxes if the Number of values option is greater than 1 for this field, otherwise radios will be displayed.") . '

'; } $form['allowed_values']['#description'] .= '

' . t('Allowed HTML tags in labels: @tags', array('@tags' => _field_filter_xss_display_allowed_tags())) . '

'; @@ -252,7 +252,7 @@ function options_field_update_field($field, $prior_field, $has_data) { function options_allowed_values($field, $instance = NULL, EntityInterface $entity = NULL) { $allowed_values = &drupal_static(__FUNCTION__, array()); - if (!isset($allowed_values[$field['id']])) { + if (!isset($allowed_values[$field['uuid']])) { $function = $field['settings']['allowed_values_function']; // If $cacheable is FALSE, then the allowed values are not statically // cached. See options_test_dynamic_values_callback() for an example of @@ -266,14 +266,14 @@ function options_allowed_values($field, $instance = NULL, EntityInterface $entit } if ($cacheable) { - $allowed_values[$field['id']] = $values; + $allowed_values[$field['uuid']] = $values; } else { return $values; } } - return $allowed_values[$field['id']]; + return $allowed_values[$field['uuid']]; } /** @@ -388,7 +388,7 @@ function options_field_update_forbid($field, $prior_field, $has_data) { */ function _options_values_in_use($field, $values) { if ($values) { - $field = field_info_field_by_id($field['id']); + $field = field_info_field_by_id($field['uuid']); $factory = drupal_container()->get('entity.query'); foreach ($field['bundles'] as $entity_type => $bundle) { $result = $factory->get($entity_type) @@ -477,9 +477,12 @@ function options_field_widget_info() { function options_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { // Abstract over the actual field columns, to allow different field types to // reuse those widgets. + + // Reset internal pointer since we're dealing with objects now. + reset($field['columns']); $value_key = key($field['columns']); - $type = str_replace('options_', '', $instance['widget']['type']); + $type = str_replace('options_', '', $instance['widget_settings']['type']); $multiple = $field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED; $required = $element['#required']; $has_value = isset($items[0][$value_key]); @@ -540,7 +543,7 @@ function options_field_widget_form(&$form, &$form_state, $field, $instance, $lan // Override the title from the incoming $element. $element['#title'] = isset($options[$on_value]) ? $options[$on_value] : ''; - if ($instance['widget']['settings']['display_label']) { + if ($instance['widget_settings']['settings']['display_label']) { $element['#title'] = $instance['label']; } break; @@ -560,11 +563,11 @@ function options_field_widget_form(&$form, &$form_state, $field, $instance, $lan */ function options_field_widget_settings_form($field, $instance) { $form = array(); - if ($instance['widget']['type'] == 'options_onoff') { + if ($instance['widget_settings']['type'] == 'options_onoff') { $form['display_label'] = array( '#type' => 'checkbox', '#title' => t('Use field label instead of the "On value" as label'), - '#default_value' => $instance['widget']['settings']['display_label'], + '#default_value' => $instance['widget_settings']['settings']['display_label'], '#weight' => -1, ); } @@ -851,7 +854,7 @@ function theme_options_none($variables) { $option = $variables['option']; $output = ''; - switch ($instance['widget']['type']) { + switch ($instance['widget_settings']['type']) { case 'options_buttons': $output = t('N/A'); break; diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php index e534971..b429b8b 100644 --- a/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php +++ b/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php @@ -49,7 +49,7 @@ function setUp() { // Make the body field translatable. // The parent class has already created the article and page content types. $field = field_info_field('body'); - $field['translatable'] = TRUE; + $instance['translatable'] = TRUE; field_update_field($field); // Create a few page nodes with multilingual body values. diff --git a/core/modules/serialization/lib/Drupal/serialization/Tests/EntitySerializationTest.php b/core/modules/serialization/lib/Drupal/serialization/Tests/EntitySerializationTest.php index fb7019e..0be84c0 100644 --- a/core/modules/serialization/lib/Drupal/serialization/Tests/EntitySerializationTest.php +++ b/core/modules/serialization/lib/Drupal/serialization/Tests/EntitySerializationTest.php @@ -57,7 +57,6 @@ public static function getInfo() { protected function setUp() { parent::setUp(); - $this->installSchema('field', array('field_config', 'field_config_instance')); $this->installSchema('entity_test', array('entity_test_mulrev', 'entity_test_mulrev_property_revision', 'entity_test_mulrev_property_data')); // Auto-create a field for testing. @@ -72,7 +71,7 @@ protected function setUp() { 'field_name' => 'field_test_text', 'bundle' => 'entity_test_mulrev', 'label' => 'Test text-field', - 'widget' => array( + 'widget_settings' => array( 'type' => 'text_textfield', 'weight' => 0, ), diff --git a/core/modules/simpletest/lib/Drupal/simpletest/Tests/DrupalUnitTestBaseTest.php b/core/modules/simpletest/lib/Drupal/simpletest/Tests/DrupalUnitTestBaseTest.php index 3aeab60..c4efde8 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/Tests/DrupalUnitTestBaseTest.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/Tests/DrupalUnitTestBaseTest.php @@ -108,10 +108,7 @@ function testEnableModulesInstall() { */ function testEnableModulesInstallContainer() { // Install Node module. - // @todo field_sql_storage and field should technically not be necessary - // for an entity query. $this->enableModules(array('field_sql_storage', 'field', 'node')); - $this->installSchema('field', array('field_config', 'field_config_instance')); $this->installSchema('node', array('node_type', 'node')); // Perform an entity query against node. diff --git a/core/modules/system/lib/Drupal/system/Tests/Database/SelectComplexTest.php b/core/modules/system/lib/Drupal/system/Tests/Database/SelectComplexTest.php index c0f181a..a997a34 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Database/SelectComplexTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Database/SelectComplexTest.php @@ -27,11 +27,6 @@ public static function getInfo() { ); } - function setUp() { - parent::setUp(); - $this->installSchema('field', array('field_config', 'field_config_instance')); - } - /** * Tests simple JOIN statements. */ diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryAggregateTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryAggregateTest.php index b957675..d18321a 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryAggregateTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryAggregateTest.php @@ -58,8 +58,6 @@ protected function setUp() { parent::setUp(); $this->installSchema('user', 'users'); $this->installSchema('system', 'sequences'); - $this->installSchema('field', 'field_config'); - $this->installSchema('field', 'field_config_instance'); $this->installSchema('entity_test', 'entity_test'); $this->entityStorageController = $this->container->get('plugin.manager.entity')->getStorageController('entity_test'); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php index 8163628..0d9a55b 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php @@ -107,10 +107,10 @@ function testEntityFormLanguage() { // Make body translatable. $field = field_info_field('body'); - $field['translatable'] = TRUE; + $instance['translatable'] = TRUE; field_update_field($field); $field = field_info_field('body'); - $this->assertTrue($field['translatable'], 'Field body is translatable.'); + $this->assertTrue($instance['translatable'], 'Field body is translatable.'); // Create a body translation and check the form language. $langcode2 = $this->langcodes[1]; diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUriTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUriTest.php index 487fc43..6845a7d 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUriTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUriTest.php @@ -33,7 +33,6 @@ protected function setUp() { parent::setUp(); $this->installSchema('system', array('variable', 'url_alias')); - $this->installSchema('field', array('field_config', 'field_config_instance')); $this->installSchema('entity_test', array('entity_test')); } diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php index c0de21b..b57bf65 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php @@ -71,7 +71,7 @@ public function testEntityDisplayUpgrade() { // Check that the display key in the instance data was removed. $body_instance = field_info_instance('node', 'body', 'article'); - $this->assertTrue(!isset($body_instance['display'])); + $this->assertTrue(!isset($body_instance->display)); // Check that the 'language' extra field is configured as expected. $expected = array( @@ -87,4 +87,16 @@ public function testEntityDisplayUpgrade() { $this->assertEqual($displays['teaser']['content']['language'], $expected['teaser']); } + /** + * Tests upgrade of fields and instances to config. + */ + function testFieldUpgradeToConfig() { + $this->assertTrue($this->performUpgrade(), t('The upgrade was completed successfully.')); + + // Assert the body field and instance on the article are converted. + $body_field = field_info_field('body'); + $this->assertNotNull($body_field, 'The body field has been found.'); + $body_field_instance = field_info_instance('node', 'body', 'article'); + $this->assertNotNull($body_field_instance, 'The body field instance on the article content type has been found.'); + } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPictureUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPictureUpgradePathTest.php index 04070c9..1671a5c 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPictureUpgradePathTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPictureUpgradePathTest.php @@ -51,11 +51,11 @@ public function testUserPictureUpgrade() { // Check file usage for the default image. $usage = file_usage()->listUsage($file); $field = field_info_field('user_picture'); - $this->assertEqual(1, $usage['image']['default_image'][$field['id']]); + $this->assertTrue(isset($usage['image']['default_image'][$field['uuid']])); $this->assertEqual($instance['settings']['max_resolution'], '800x800', 'User picture maximum resolution has been migrated.'); $this->assertEqual($instance['settings']['max_filesize'], '700 KB', 'User picture maximum filesize has been migrated.'); - $this->assertEqual($instance['description'], 'These are user picture guidelines.', 'User picture guidelines are now the user picture field description.'); + $this->assertEqual($instance->description, 'These are user picture guidelines.', 'User picture guidelines are now the user picture field description.'); $this->assertEqual($instance['settings']['file_directory'], 'user_pictures_dir', 'User picture directory path has been migrated.'); $display_options = entity_get_display('user', 'user', 'default')->getComponent('user_picture'); diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php index 3d28ec0..382a766 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php @@ -53,11 +53,11 @@ function setUp() { 'field_name' => 'taxonomy_' . $this->vocabulary->id(), 'bundle' => 'article', 'entity_type' => 'node', - 'widget' => array( + 'widget_settings' => array( 'type' => 'options_select', ), ); - field_create_instance($this->instance); + $this->instance = field_create_instance($this->instance); entity_get_display('node', 'article', 'default') ->setComponent('taxonomy_' . $this->vocabulary->id(), array( 'type' => 'taxonomy_term_reference_link', diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php index 8c5571c..aab02ff 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php @@ -123,7 +123,7 @@ function testTaxonomyTermFieldMultipleVocabularies() { // Verify that field and instance settings are correct. $field_info = field_info_field($this->field_name); - $this->assertEqual(count($field_info['settings']['allowed_values']), 1, 'Only one vocabulary is allowed for the field.'); + $this->assertEqual(count($field_info->settings['allowed_values']), 1, 'Only one vocabulary is allowed for the field.'); // The widget should still be displayed. $this->drupalGet('test-entity/add/test_bundle'); diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php index d5de5fa..ff4e250 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php @@ -53,7 +53,7 @@ function setUp() { ), ) ); - field_create_field($this->field); + $this->field = field_create_field($this->field); $this->instance = array( 'field_name' => $this->field_name, 'entity_type' => 'test_entity', @@ -62,7 +62,7 @@ function setUp() { 'type' => 'options_select', ), ); - field_create_instance($this->instance); + $this->instance = field_create_instance($this->instance); entity_get_display('test_entity', 'test_bundle', 'full') ->setComponent($this->field_name, array( 'type' => 'taxonomy_term_reference_link', diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php index 93cc8d4..84387a5 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php @@ -45,11 +45,11 @@ function setUp() { 'field_name' => 'taxonomy_' . $this->vocabulary->id(), 'bundle' => 'article', 'entity_type' => 'node', - 'widget' => array( + 'widget_settings' => array( 'type' => 'options_select', ), ); - field_create_instance($this->instance); + $this->instance = field_create_instance($this->instance); entity_get_display('node', 'article', 'default') ->setComponent($this->instance['field_name'], array( 'type' => 'taxonomy_term_reference_link', @@ -142,7 +142,7 @@ function testTaxonomyNode() { function testNodeTermCreationAndDeletion() { // Enable tags in the vocabulary. $instance = $this->instance; - $instance['widget'] = array( + $instance['widget_settings'] = array( 'type' => 'taxonomy_autocomplete', 'settings' => array( 'placeholder' => 'Start typing here.', @@ -506,7 +506,7 @@ function testTaxonomyGetTermByName() { function testReSavingTags() { // Enable tags in the vocabulary. $instance = $this->instance; - $instance['widget'] = array('type' => 'taxonomy_autocomplete'); + $instance['widget_settings'] = array('type' => 'taxonomy_autocomplete'); field_update_instance($instance); // Create a term and a node using it. diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php index ea73152..c1098c7 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php @@ -50,7 +50,7 @@ function setUp() { 'type' => 'options_select', ), ); - field_create_instance($this->instance); + $this->instance = field_create_instance($this->instance); entity_get_display('node', 'article', 'default') ->setComponent('taxonomy_' . $this->vocabulary->id(), array( 'type' => 'taxonomy_term_reference_link', diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyUnitTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyUnitTest.php index d73302b..e969c15 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyUnitTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyUnitTest.php @@ -176,7 +176,7 @@ function testUninstallReinstall() { // removed when the module is uninstalled. $this->field_name = drupal_strtolower($this->randomName() . '_field_name'); $this->field = array('field_name' => $this->field_name, 'type' => 'text', 'cardinality' => 4); - $this->field = field_create_field($this->field); + field_create_field($this->field); $this->instance = array( 'field_name' => $this->field_name, 'entity_type' => 'taxonomy_term', @@ -196,7 +196,6 @@ function testUninstallReinstall() { // an instance of this field on the same bundle name should be successful. $this->vocabulary->enforceIsNew(); taxonomy_vocabulary_save($this->vocabulary); - unset($this->field['id']); field_create_field($this->field); field_create_instance($this->instance); } diff --git a/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php b/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php index f8c585b..8c859e0 100644 --- a/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php +++ b/core/modules/text/lib/Drupal/text/Tests/TextFieldTest.php @@ -57,7 +57,7 @@ function testTextFieldValidation() { 'max_length' => $max_length, ) ); - field_create_field($this->field); + $this->field = field_create_field($this->field); $this->instance = array( 'field_name' => $this->field['field_name'], 'entity_type' => 'test_entity', @@ -102,7 +102,7 @@ function _testTextfieldWidgets($field_type, $widget_type) { $entity_type = 'test_entity'; $this->field_name = drupal_strtolower($this->randomName()); $this->field = array('field_name' => $this->field_name, 'type' => $field_type); - field_create_field($this->field); + $this->field = field_create_field($this->field); $this->instance = array( 'field_name' => $this->field_name, 'entity_type' => 'test_entity', @@ -111,7 +111,7 @@ function _testTextfieldWidgets($field_type, $widget_type) { 'settings' => array( 'text_processing' => TRUE, ), - 'widget' => array( + 'widget_settings' => array( 'type' => $widget_type, 'settings' => array( 'placeholder' => 'A placeholder on ' . $widget_type, @@ -165,7 +165,7 @@ function _testTextfieldWidgetsFormatted($field_type, $widget_type) { $entity_type = 'test_entity'; $this->field_name = drupal_strtolower($this->randomName()); $this->field = array('field_name' => $this->field_name, 'type' => $field_type); - field_create_field($this->field); + $this->field = field_create_field($this->field); $this->instance = array( 'field_name' => $this->field_name, 'entity_type' => 'test_entity', diff --git a/core/modules/text/text.module b/core/modules/text/text.module index 07c962e..15a1395 100644 --- a/core/modules/text/text.module +++ b/core/modules/text/text.module @@ -178,7 +178,7 @@ function text_field_load($entity_type, $entities, $field, $instances, $langcode, foreach ($items[$id] as $delta => $item) { // Only process items with a cacheable format, the rest will be handled // by formatters if needed. - if (empty($instances[$id]['settings']['text_processing']) || filter_format_allowcache($item['format'])) { + if (empty($instances[$id]->settings['text_processing']) || filter_format_allowcache($item['format'])) { $items[$id][$delta]['safe_value'] = isset($item['value']) ? _text_sanitize($instances[$id], $langcode, $item, 'value') : ''; if ($field['type'] == 'text_with_summary') { $items[$id][$delta]['safe_summary'] = isset($item['summary']) ? _text_sanitize($instances[$id], $langcode, $item, 'summary') : ''; diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php b/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php index ce9d3a0..9ede2d9 100644 --- a/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php +++ b/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php @@ -51,7 +51,7 @@ public function removeTranslation(EntityInterface $entity, $langcode) { foreach (field_info_instances($entity->entityType(), $entity->bundle()) as $instance) { $field_name = $instance['field_name']; $field = field_info_field($field_name); - if ($field['translatable']) { + if ($instance['translatable']) { $entity->{$field_name}[$langcode] = array(); } } diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSettingsTest.php b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSettingsTest.php index 41600ac..7fca012 100644 --- a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSettingsTest.php +++ b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSettingsTest.php @@ -88,7 +88,7 @@ function testSettingsUI() { ); $this->assertSettings('comment', 'comment_node_article', TRUE, $edit); $field = field_info_field('comment_body'); - $this->assertTrue($field['translatable'], 'Comment body is translatable.'); + $this->assertTrue($instance['translatable'], 'Comment body is translatable.'); // Test that language settings are correctly stored. $language_configuration = language_get_default_configuration('comment', 'comment_node_article'); diff --git a/core/modules/translation_entity/translation_entity.admin.inc b/core/modules/translation_entity/translation_entity.admin.inc index 0e2316b..3685421 100644 --- a/core/modules/translation_entity/translation_entity.admin.inc +++ b/core/modules/translation_entity/translation_entity.admin.inc @@ -6,7 +6,8 @@ */ use Drupal\Core\Entity\EntityInterface; -use Drupal\field\FieldInstance; +use Drupal\field\Plugin\Core\Entity\FieldEntity; +use Drupal\field\Plugin\Core\Entity\FieldInstance; /** * Returns a form element to configure field synchronization. @@ -19,7 +20,7 @@ * @return array * A form element to configure field synchronization. */ -function translation_entity_field_sync_widget(array $field, FieldInstance $instance) { +function translation_entity_field_sync_widget(FieldEntity $field, FieldInstance $instance) { $element = array(); if (!empty($field['settings']['column_groups']) && count($field['settings']['column_groups']) > 1) { @@ -79,7 +80,7 @@ function _translation_entity_form_language_content_settings_form_alter(array &$f $form['settings'][$entity_type][$bundle]['fields'][$field_name] = array( '#label' => $instance['label'], '#type' => 'checkbox', - '#default_value' => $field['translatable'], + '#default_value' => $instance['translatable'], ); $column_element = translation_entity_field_sync_widget($field, $instance); if ($column_element) { @@ -298,7 +299,7 @@ function _translation_entity_update_field_translatability($settings) { $operations = array(); foreach ($fields as $field_name => $translatable) { $field = field_info_field($field_name); - if ($field['translatable'] != $translatable) { + if ($instance['translatable'] != $translatable) { // If a field is untranslatable, it can have no data except under // LANGUAGE_NOT_SPECIFIED. Thus we need a field to be translatable before // we convert data to the entity language. Conversely we need to switch @@ -335,7 +336,7 @@ function translation_entity_translatable_form(array $form, array &$form_state, $ $t_args = array('%name' => $field_name); $warning = t('By submitting this form these changes will apply to the %name field everywhere it is used.', $t_args); - if ($field['translatable']) { + if ($instance['translatable']) { $title = t('Are you sure you want to disable translation for the %name field?', $t_args); $warning .= "
" . t("All the existing translations of this field will be deleted.
This action cannot be undone."); } @@ -350,7 +351,7 @@ function translation_entity_translatable_form(array $form, array &$form_state, $ // submits from toggling translatability. $form['translatable'] = array( '#type' => 'hidden', - '#default_value' => $field['translatable'], + '#default_value' => $instance['translatable'], ); return confirm_form($form, $title, '', $warning); @@ -374,7 +375,7 @@ function translation_entity_translatable_form_submit(array $form, array $form_st $field_name = $form_state['field']['field_name']; $field = field_info_field($field_name); - if ($field['translatable'] !== $translatable) { + if ($instance['translatable'] !== $translatable) { // Field translatability has changed since form creation, abort. $t_args = array('%field_name'); $msg = $translatable ? @@ -421,8 +422,8 @@ function translation_entity_translatable_form_submit(array $form, array $form_st */ function translation_entity_translatable_switch($translatable, $field_name) { $field = field_info_field($field_name); - if ($field['translatable'] !== $translatable) { - $field['translatable'] = $translatable; + if ($instance['translatable'] !== $translatable) { + $instance['translatable'] = $translatable; field_update_field($field); } } diff --git a/core/modules/translation_entity/translation_entity.module b/core/modules/translation_entity/translation_entity.module index ac00322..94918d2 100644 --- a/core/modules/translation_entity/translation_entity.module +++ b/core/modules/translation_entity/translation_entity.module @@ -625,7 +625,7 @@ function translation_entity_form_alter(array &$form, array &$form_state) { foreach (field_info_instances($entity->entityType(), $entity->bundle()) as $instance) { $field_name = $instance['field_name']; $field = field_info_field($field_name); - $form[$field_name]['#multilingual'] = !empty($field['translatable']); + $form[$field_name]['#multilingual'] = !empty($instance['translatable']); } } } @@ -808,7 +808,7 @@ function translation_entity_field_extra_fields() { function translation_entity_form_field_ui_field_settings_form_alter(array &$form, array &$form_state, $form_id) { $field = $form['#field']; $field_name = $field['field_name']; - $translatable = $field['translatable']; + $translatable = $instance['translatable']; $label = t('Field translation'); if (field_has_data($field)) { diff --git a/core/modules/translation_entity/translation_entity.pages.inc b/core/modules/translation_entity/translation_entity.pages.inc index f0c3027..728c2a1 100644 --- a/core/modules/translation_entity/translation_entity.pages.inc +++ b/core/modules/translation_entity/translation_entity.pages.inc @@ -41,7 +41,7 @@ function translation_entity_overview(EntityInterface $entity) { foreach (field_info_instances($entity->entityType(), $entity->bundle()) as $instance) { $field_name = $instance['field_name']; $field = field_info_field($field_name); - if ($field['translatable']) { + if ($instance['translatable']) { $translatable = TRUE; break; } @@ -251,7 +251,7 @@ function translation_entity_prepare_translation(EntityInterface $entity, Languag else { foreach ($instances as $field_name => $instance) { $field = field_info_field($field_name); - if (!empty($field['translatable'])) { + if (!empty($instance['translatable'])) { $value = $entity->get($field_name); $value[$target->langcode] = isset($value[$source->langcode]) ? $value[$source->langcode] : array(); $entity->set($field_name, $value); diff --git a/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php b/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php index 38ca376..9d24e34 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php @@ -199,7 +199,7 @@ function testRegistrationWithUserFields() { 'field_name' => 'test_user_field', 'cardinality' => 1, ); - field_create_field($field); + $field = field_create_field($field); $instance = array( 'field_name' => 'test_user_field', 'entity_type' => 'user', @@ -208,7 +208,7 @@ function testRegistrationWithUserFields() { 'required' => TRUE, 'settings' => array('user_register_form' => FALSE), ); - field_create_instance($instance); + $instance = field_create_instance($instance); // Check that the field does not appear on the registration form. $this->drupalGet('user/register'); diff --git a/core/modules/user/user.install b/core/modules/user/user.install index 10e429c..45edc81 100644 --- a/core/modules/user/user.install +++ b/core/modules/user/user.install @@ -315,10 +315,6 @@ function user_install_picture_field() { 'uri_scheme' => 'public', 'default_image' => FALSE, ), - 'storage' => array( - 'type' => 'field_sql_storage', - 'settings' => array(), - ), ); $field = field_create_field($field); @@ -717,7 +713,7 @@ function user_update_8011() { 'settings' => array(), ), ); - _update_7000_field_create_field($field); + $field = _update_7000_field_create_field($field); $instance = array( 'field_name' => 'user_picture', diff --git a/core/modules/views/lib/Drupal/views/Tests/Plugin/RelationshipJoinTestBase.php b/core/modules/views/lib/Drupal/views/Tests/Plugin/RelationshipJoinTestBase.php index 5d2b524..172678d 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Plugin/RelationshipJoinTestBase.php +++ b/core/modules/views/lib/Drupal/views/Tests/Plugin/RelationshipJoinTestBase.php @@ -27,7 +27,6 @@ */ protected function setUpFixtures() { $this->installSchema('user', array('users', 'users_roles', 'role_permission')); - $this->installSchema('field', array('field_config', 'field_config_instance')); $this->installConfig(array('user')); parent::setUpFixtures(); diff --git a/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php b/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php index 6416193..a89d555 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php @@ -66,7 +66,7 @@ function setUp() { ), ), ); - field_create_field($this->tag_field); + $this->tag_field = field_create_field($this->tag_field); // Create an instance of the tag field on one of the content types, and // configure it to display an autocomplete widget. @@ -74,7 +74,7 @@ function setUp() { 'field_name' => 'field_views_testing_tags', 'entity_type' => 'node', 'bundle' => $this->node_type_with_tags->type, - 'widget' => array( + 'widget_settings' => array( 'type' => 'taxonomy_autocomplete', ), ); diff --git a/core/profiles/standard/standard.install b/core/profiles/standard/standard.install index 85c818c..84f1ffb 100644 --- a/core/profiles/standard/standard.install +++ b/core/profiles/standard/standard.install @@ -125,7 +125,7 @@ function standard_install() { 'label' => 'Tags', 'bundle' => 'article', 'description' => $vocabulary->help, - 'widget' => array( + 'widget_settings' => array( 'type' => 'taxonomy_autocomplete', 'weight' => -4, ), @@ -155,11 +155,11 @@ function standard_install() { 'type' => 'image', 'cardinality' => 1, 'locked' => FALSE, - 'indexes' => array('fid' => array('fid')), 'settings' => array( 'uri_scheme' => 'public', 'default_image' => FALSE, ), + 'indexes' => array('fid' => array('fid')), 'storage' => array( 'type' => 'field_sql_storage', 'settings' => array(), @@ -188,7 +188,7 @@ function standard_install() { 'title_field' => '', ), - 'widget' => array( + 'widget_settings' => array( 'type' => 'image_image', 'settings' => array( 'progress_indicator' => 'throbber',