diff --git a/core/includes/entity.inc b/core/includes/entity.inc index e91eda7..91cbc1e 100644 --- a/core/includes/entity.inc +++ b/core/includes/entity.inc @@ -708,6 +708,14 @@ function entity_get_render_display(EntityInterface $entity, $view_mode) { $display = entity_get_display($entity_type, $bundle, $render_view_mode); $display->originalMode = $view_mode; + // Let modules alter the display. + $display_context = array( + 'entity_type' => $entity_type, + 'bundle' => $bundle, + 'view_mode' => $view_mode, + ); + drupal_alter('entity_display', $display, $display_context); + return $display; } @@ -808,6 +816,14 @@ function entity_get_render_form_display(EntityInterface $entity, $form_mode) { $form_display = entity_get_form_display($entity_type, $bundle, $render_form_mode); $form_display->originalMode = $form_mode; + // Let modules alter the form display. + $form_display_context = array( + 'entity_type' => $entity_type, + 'bundle' => $bundle, + 'form_mode' => $form_mode, + ); + drupal_alter('entity_form_display', $form_display, $form_display_context); + return $form_display; } diff --git a/core/lib/Drupal/Core/Entity/EntityFormController.php b/core/lib/Drupal/Core/Entity/EntityFormController.php index 1e75646..17743ec 100644 --- a/core/lib/Drupal/Core/Entity/EntityFormController.php +++ b/core/lib/Drupal/Core/Entity/EntityFormController.php @@ -125,15 +125,6 @@ protected function init(array &$form_state) { $this->prepareEntity(); $form_display = entity_get_render_form_display($this->entity, $this->getOperation()); - - // Let modules alter the form display. - $form_display_context = array( - 'entity_type' => $this->entity->entityType(), - 'bundle' => $this->entity->bundle(), - 'form_mode' => $this->getOperation(), - ); - $this->moduleHandler->alter('entity_form_display', $form_display, $form_display_context); - $this->setFormDisplay($form_display, $form_state); // Invoke the prepare form hooks. diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php index fabd5a5..178d9c4 100644 --- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php +++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php @@ -208,20 +208,9 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la // Store entities for rendering by view_mode. $view_modes[$entity_view_mode][$entity->id()] = $entity; - // Load the corresponding display settings if not stored yet. + // Get the corresponding display settings. if (!isset($displays[$entity_view_mode][$bundle])) { - // Get the display object for this bundle and view mode. - $display = entity_get_render_display($entity, $entity_view_mode); - - // Let modules alter the display. - $display_context = array( - 'entity_type' => $this->entityType, - 'bundle' => $bundle, - 'view_mode' => $entity_view_mode, - ); - drupal_alter('entity_display', $display, $display_context); - - $displays[$entity_view_mode][$bundle] = $display; + $displays[$entity_view_mode][$bundle] = entity_get_render_display($entity, $entity_view_mode); } } diff --git a/core/lib/Drupal/Core/Field/WidgetBase.php b/core/lib/Drupal/Core/Field/WidgetBase.php index b371008..879f8e7 100644 --- a/core/lib/Drupal/Core/Field/WidgetBase.php +++ b/core/lib/Drupal/Core/Field/WidgetBase.php @@ -328,9 +328,24 @@ public function flagErrors(FieldItemListInterface $items, array $form, array &$f $field_state = field_form_get_state($form['#parents'], $field_name, $form_state); if (!empty($field_state['constraint_violations'])) { + $form_builder = \Drupal::formBuilder(); + // Locate the correct element in the the form. $element = NestedArray::getValue($form_state['complete_form'], $field_state['array_parents']); + // Do not report entity-level validation errors if Form API errors have + // already been reported for the field. + // @todo Field validation should not be run on fields with FAPI errors to + // begin with. See https://drupal.org/node/2070429. + $element_path = implode('][', $element['#parents']); + if ($reported_errors = $form_builder->getErrors($form_state)) { + foreach (array_keys($reported_errors) as $error_path) { + if (strpos($error_path, $element_path) === 0) { + return; + } + } + } + // Only set errors if the element is accessible. if (!isset($element['#access']) || $element['#access']) { $definition = $this->getPluginDefinition(); @@ -341,16 +356,22 @@ public function flagErrors(FieldItemListInterface $items, array $form, array &$f // Separate violations by delta. $property_path = explode('.', $violation->getPropertyPath()); $delta = array_shift($property_path); - $violation->arrayPropertyPath = $property_path; + // Violations at the ItemList level are not associated to any delta, + // we file them under $delta NULL. + $delta = is_numeric($delta) ? $delta : NULL; + $violations_by_delta[$delta][] = $violation; + $violation->arrayPropertyPath = $property_path; } foreach ($violations_by_delta as $delta => $delta_violations) { - // For a multiple-value widget, pass all errors to the main widget. - // For single-value widgets, pass errors by delta. - if ($is_multiple) { + // Pass violations to the main element: + // - if this is a multiple-value widget, + // - or if the violations are at the ItemList level. + if ($is_multiple || $delta === NULL) { $delta_element = $element; } + // Otherwise, pass errors by delta to the corresponding sub-element. else { $original_delta = $field_state['original_deltas'][$delta]; $delta_element = $element[$original_delta]; @@ -359,7 +380,7 @@ public function flagErrors(FieldItemListInterface $items, array $form, array &$f // @todo: Pass $violation->arrayPropertyPath as property path. $error_element = $this->errorElement($delta_element, $violation, $form, $form_state); if ($error_element !== FALSE) { - form_error($error_element, $form_state, $violation->getMessage()); + $form_builder->setError($error_element, $form_state, $violation->getMessage()); } } } diff --git a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/AllowedValuesConstraintValidator.php b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/AllowedValuesConstraintValidator.php index 7ad2cfd..32178bf 100644 --- a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/AllowedValuesConstraintValidator.php +++ b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/AllowedValuesConstraintValidator.php @@ -20,6 +20,9 @@ class AllowedValuesConstraintValidator extends ChoiceValidator { * {@inheritdoc} */ public function validate($value, Constraint $constraint) { + if (!isset($value)) { + return; + } if ($this->context->getMetadata()->getTypedData() instanceof AllowedValuesInterface) { $account = \Drupal::currentUser(); $allowed_values = $this->context->getMetadata()->getTypedData()->getSettableValues($account); diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorTestBase.php b/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorTestBase.php index 7fb55b6..ed810fd 100644 --- a/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorTestBase.php +++ b/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorTestBase.php @@ -359,7 +359,7 @@ function createSampleNodes($count = 5) { // Post $count article nodes. for ($i = 0; $i < $count; $i++) { $edit = array(); - $edit['title'] = $this->randomName(); + $edit['title[0][value]'] = $this->randomName(); $edit['body[0][value]'] = $this->randomName(); $this->drupalPostForm('node/add/article', $edit, t('Save')); } diff --git a/core/modules/book/lib/Drupal/book/Tests/BookTest.php b/core/modules/book/lib/Drupal/book/Tests/BookTest.php index 5ea8b8d..4e96673 100644 --- a/core/modules/book/lib/Drupal/book/Tests/BookTest.php +++ b/core/modules/book/lib/Drupal/book/Tests/BookTest.php @@ -243,7 +243,7 @@ function createBookNode($book_nid, $parent = NULL) { static $number = 0; // Used to ensure that when sorted nodes stay in same order. $edit = array(); - $edit["title"] = $number . ' - SimpleTest test node ' . $this->randomName(10); + $edit['title[0][value]'] = $number . ' - SimpleTest test node ' . $this->randomName(10); $edit['body[0][value]'] = 'SimpleTest test body ' . $this->randomName(32) . ' ' . $this->randomName(32); $edit['book[bid]'] = $book_nid; @@ -258,7 +258,7 @@ function createBookNode($book_nid, $parent = NULL) { } // Check to make sure the book node was created. - $node = $this->drupalGetNodeByTitle($edit['title']); + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); $this->assertNotNull(($node === FALSE ? NULL : $node), 'Book node found in database.'); $number++; diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php index 8b885fe..9255b34 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php @@ -95,7 +95,7 @@ function testCommentLanguage() { // Create "Article" content. $title = $this->randomName(); $edit = array( - 'title' => $title, + 'title[0][value]' => $title, 'body[0][value]' => $this->randomName(), 'langcode' => $node_langcode, 'comment[0][status]' => COMMENT_OPEN, diff --git a/core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php b/core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php index 7fea145..c845b78 100644 --- a/core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php +++ b/core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php @@ -309,7 +309,7 @@ private function doNode($type) { // Create a node using the form in order to generate an add content event // (which is not triggered by drupalCreateNode). $edit = $this->getContent($type); - $title = $edit["title"]; + $title = $edit['title[0][value]']; $this->drupalPostForm('node/add/' . $type, $edit, t('Save')); $this->assertResponse(200); // Retrieve the node object. @@ -369,7 +369,7 @@ private function getContent($type) { switch ($type) { case 'forum': $content = array( - 'title' => $this->randomName(8), + 'title[0][value]' => $this->randomName(8), 'taxonomy_forums' => array(1), 'body[0][value]' => $this->randomName(32), ); @@ -377,7 +377,7 @@ private function getContent($type) { default: $content = array( - 'title' => $this->randomName(8), + 'title[0][value]' => $this->randomName(8), 'body[0][value]' => $this->randomName(32), ); break; diff --git a/core/modules/edit/edit.services.yml b/core/modules/edit/edit.services.yml index d71a196..73f7f25 100644 --- a/core/modules/edit/edit.services.yml +++ b/core/modules/edit/edit.services.yml @@ -4,7 +4,7 @@ services: arguments: ['@container.namespaces'] access_check.edit.entity_field: class: Drupal\edit\Access\EditEntityFieldAccessCheck - arguments: ['@entity.manager', '@field.info'] + arguments: ['@entity.manager'] tags: - { name: access_check } access_check.edit.entity: diff --git a/core/modules/edit/js/editors/plainTextEditor.js b/core/modules/edit/js/editors/plainTextEditor.js index f2095d7..82a5c3e 100644 --- a/core/modules/edit/js/editors/plainTextEditor.js +++ b/core/modules/edit/js/editors/plainTextEditor.js @@ -21,7 +21,13 @@ Drupal.edit.editors.plain_text = Drupal.edit.EditorView.extend({ var fieldModel = this.fieldModel; // Store the original value of this field. Necessary for reverting changes. - var $textElement = this.$textElement = this.$el.find('.field-item:first'); + var $textElement; + if (this.$el.is(':has(.field-item)')) { + $textElement = this.$textElement = this.$el.find('.field-item:first'); + } + else { + $textElement = this.$textElement = this.$el; + } editorModel.set('originalValue', $.trim(this.$textElement.text())); // Sets the state to 'changed' whenever the value changes diff --git a/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php b/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php index 413e9aa..2c5dd92 100644 --- a/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php +++ b/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php @@ -15,7 +15,6 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Drupal\Core\Entity\EntityInterface; -use Drupal\field\FieldInfo; /** * Access check for editing entity fields. @@ -30,23 +29,13 @@ class EditEntityFieldAccessCheck implements StaticAccessCheckInterface, EditEnti protected $entityManager; /** - * The field info. - * - * @var \Drupal\field\FieldInfo - */ - protected $fieldInfo; - - /** * Constructs a EditEntityFieldAccessCheck object. * * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. - * @param \Drupal\field\FieldInfo $field_info - * The field info. */ - public function __construct(EntityManagerInterface $entity_manager, FieldInfo $field_info) { + public function __construct(EntityManagerInterface $entity_manager) { $this->entityManager = $entity_manager; - $this->fieldInfo = $field_info; } /** @@ -95,7 +84,7 @@ protected function validateAndUpcastRequestAttributes(Request $request) { // Validate the field name and language. $field_name = $request->attributes->get('field_name'); - if (!$field_name || !$this->fieldInfo->getInstance($entity->entityType(), $entity->bundle(), $field_name)) { + if (!$field_name || !$entity->hasField($field_name)) { throw new NotFoundHttpException(); } $langcode = $request->attributes->get('langcode'); diff --git a/core/modules/edit/lib/Drupal/edit/EditController.php b/core/modules/edit/lib/Drupal/edit/EditController.php index 39ced93..0313ce8 100644 --- a/core/modules/edit/lib/Drupal/edit/EditController.php +++ b/core/modules/edit/lib/Drupal/edit/EditController.php @@ -145,7 +145,7 @@ public function metadata(Request $request) { } // Validate the field name and language. - if (!$field_name || !($instance = $this->fieldInfo->getInstance($entity->entityType(), $entity->bundle(), $field_name))) { + if (!$field_name || !$entity->hasField($field_name)) { throw new NotFoundHttpException(); } if (!$langcode || (field_valid_language($langcode) !== $langcode)) { @@ -158,7 +158,8 @@ public function metadata(Request $request) { $metadata[$entity_id] = $this->metadataGenerator->generateEntity($entity, $langcode); } - $metadata[$field] = $this->metadataGenerator->generateField($entity, $instance, $langcode, $view_mode); + $field_definition = $entity->get($field_name)->getFieldDefinition(); + $metadata[$field] = $this->metadataGenerator->generateField($entity, $field_definition, $langcode, $view_mode); } return new JsonResponse($metadata); diff --git a/core/modules/edit/lib/Drupal/edit/Form/EditFieldForm.php b/core/modules/edit/lib/Drupal/edit/Form/EditFieldForm.php index ad9410d..7be4f58 100644 --- a/core/modules/edit/lib/Drupal/edit/Form/EditFieldForm.php +++ b/core/modules/edit/lib/Drupal/edit/Form/EditFieldForm.php @@ -128,18 +128,8 @@ protected function init(array &$form_state, EntityInterface $entity, $field_name $form_state['field_name'] = $field_name; // @todo Allow the usage of different form modes by exposing a hook and the - // UI for them. - $form_display = entity_get_render_form_display($entity, 'default'); - - // Let modules alter the form display. - $form_display_context = array( - 'entity_type' => $entity->entityType(), - 'bundle' => $entity->bundle(), - 'form_mode' => 'default', - ); - $this->moduleHandler->alter('entity_form_display', $form_display, $form_display_context); - - $form_state['form_display'] = $form_display; + // UI for them. + $form_state['form_display'] = entity_get_render_form_display($entity, 'default'); } /** @@ -180,14 +170,14 @@ public function submitForm(array &$form, array &$form_state) { */ protected function buildEntity(array $form, array &$form_state) { $entity = clone $form_state['entity']; + $field_name = $form_state['field_name']; - field_attach_extract_form_values($entity, $form, $form_state, array('field_name' => $form_state['field_name'])); + field_attach_extract_form_values($entity, $form, $form_state, array('field_name' => $field_name)); // @todo Refine automated log messages and abstract them to all entity // types: http://drupal.org/node/1678002. if ($entity->entityType() == 'node' && $entity->isNewRevision() && !isset($entity->log)) { - $instance = field_info_instance($entity->entityType(), $form_state['field_name'], $entity->bundle()); - $entity->log = t('Updated the %field-name field through in-place editing.', array('%field-name' => $instance->getFieldLabel())); + $entity->log = t('Updated the %field-name field through in-place editing.', array('%field-name' => $entity->get($field_name)->getFieldDefinition()->getFieldLabel())); } return $entity; diff --git a/core/modules/edit/tests/Drupal/edit/Tests/Access/EditEntityFieldAccessCheckTest.php b/core/modules/edit/tests/Drupal/edit/Tests/Access/EditEntityFieldAccessCheckTest.php index 228b4b0..a745148 100644 --- a/core/modules/edit/tests/Drupal/edit/Tests/Access/EditEntityFieldAccessCheckTest.php +++ b/core/modules/edit/tests/Drupal/edit/Tests/Access/EditEntityFieldAccessCheckTest.php @@ -41,13 +41,6 @@ class EditEntityFieldAccessCheckTest extends UnitTestCase { protected $entityManager; /** - * The mocked field info. - * - * @var \Drupal\field\FieldInfo|\PHPUnit_Framework_MockObject_MockObject - */ - protected $fieldInfo; - - /** * The mocked entity storage controller. * * @var \Drupal\Core\Entity\EntityStorageControllerInterface|\PHPUnit_Framework_MockObject_MockObject @@ -71,11 +64,7 @@ protected function setUp() { ->method('getStorageController') ->will($this->returnValue($this->entityStorageController)); - $this->fieldInfo = $this->getMockBuilder('Drupal\field\FieldInfo') - ->disableOriginalConstructor() - ->getMock(); - - $this->editAccessCheck = new EditEntityFieldAccessCheck($this->entityManager, $this->fieldInfo); + $this->editAccessCheck = new EditEntityFieldAccessCheck($this->entityManager); } /** @@ -91,16 +80,12 @@ public function testAppliesTo() { * @see \Drupal\edit\Tests\edit\Access\EditEntityFieldAccessCheckTest::testAccess() */ public function providerTestAccess() { - $editable_entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest') - ->disableOriginalConstructor() - ->getMock(); + $editable_entity = $this->createMockEntity(); $editable_entity->expects($this->any()) ->method('access') ->will($this->returnValue(TRUE)); - $non_editable_entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest') - ->disableOriginalConstructor() - ->getMock(); + $non_editable_entity = $this->createMockEntity(); $non_editable_entity->expects($this->any()) ->method('access') ->will($this->returnValue(FALSE)); @@ -146,22 +131,15 @@ public function testAccess(EntityInterface $entity, FieldInterface $field = NULL $entity_with_field = clone $entity; $entity_with_field->expects($this->any()) ->method('get') + ->with('valid') ->will($this->returnValue($field)); // Prepare the request to be valid. - $request->attributes->set('entity', $entity_with_field); $request->attributes->set('entity_type', 'test_entity'); - $request->attributes->set('field_name', 'example'); + $request->attributes->set('entity', $entity_with_field); + $request->attributes->set('field_name', 'valid'); $request->attributes->set('langcode', Language::LANGCODE_NOT_SPECIFIED); - $this->fieldInfo->expects($this->any()) - ->method('getInstance') - ->will($this->returnValue(array( - 'example' => array( - 'field_name' => 'example', - ) - ))); - $account = $this->getMock('Drupal\Core\Session\AccountInterface'); $access = $this->editAccessCheck->access($route, $request, $account); $this->assertSame($expected_result, $access); @@ -220,12 +198,7 @@ public function testAccessWithNotPassedFieldName() { $route = new Route('/edit/form/test_entity/1/body/und/full', array(), array('_access_edit_entity_field' => 'TRUE')); $request = new Request(); $request->attributes->set('entity_type', 'entity_test'); - - $entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest') - ->disableOriginalConstructor() - ->getMock(); - - $request->attributes->set('entity', $entity); + $request->attributes->set('entity', $this->createMockEntity()); $account = $this->getMock('Drupal\Core\Session\AccountInterface'); $this->editAccessCheck->access($route, $request, $account); @@ -240,25 +213,9 @@ public function testAccessWithNonExistingField() { $route = new Route('/edit/form/test_entity/1/body/und/full', array(), array('_access_edit_entity_field' => 'TRUE')); $request = new Request(); $request->attributes->set('entity_type', 'entity_test'); - - $entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest') - ->disableOriginalConstructor() - ->getMock(); - $entity->expects($this->any()) - ->method('entityType') - ->will($this->returnValue('entity_test')); - $entity->expects($this->any()) - ->method('bundle') - ->will($this->returnValue('test_bundle')); - - $request->attributes->set('entity', $entity); + $request->attributes->set('entity', $this->createMockEntity()); $request->attributes->set('field_name', 'not_valid'); - $this->fieldInfo->expects($this->once()) - ->method('getInstance') - ->with('entity_test', 'test_bundle', 'not_valid') - ->will($this->returnValue(NULL)); - $account = $this->getMock('Drupal\Core\Session\AccountInterface'); $this->editAccessCheck->access($route, $request, $account); } @@ -272,22 +229,9 @@ public function testAccessWithNotPassedLanguage() { $route = new Route('/edit/form/test_entity/1/body/und/full', array(), array('_access_edit_entity_field' => 'TRUE')); $request = new Request(); $request->attributes->set('entity_type', 'entity_test'); - - $entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest') - ->disableOriginalConstructor() - ->getMock(); - $request->attributes->set('entity', $entity); - + $request->attributes->set('entity', $this->createMockEntity()); $request->attributes->set('field_name', 'valid'); - $field = $this->getMockBuilder('Drupal\field\Entity\Field') - ->disableOriginalConstructor() - ->getMock(); - - $this->fieldInfo->expects($this->once()) - ->method('getInstance') - ->will($this->returnValue($field)); - $account = $this->getMock('Drupal\Core\Session\AccountInterface'); $this->editAccessCheck->access($route, $request, $account); } @@ -301,25 +245,30 @@ public function testAccessWithInvalidLanguage() { $route = new Route('/edit/form/test_entity/1/body/und/full', array(), array('_access_edit_entity_field' => 'TRUE')); $request = new Request(); $request->attributes->set('entity_type', 'entity_test'); - - $entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest') - ->disableOriginalConstructor() - ->getMock(); - $request->attributes->set('entity', $entity); - + $request->attributes->set('entity', $this->createMockEntity()); $request->attributes->set('field_name', 'valid'); $request->attributes->set('langcode', 'xx-lolspeak'); - $field = $this->getMockBuilder('Drupal\field\Entity\Field') + $account = $this->getMock('Drupal\Core\Session\AccountInterface'); + $this->editAccessCheck->access($route, $request, $account); + } + + /** + * Returns a mock entity. + */ + protected function createMockEntity() { + $entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest') ->disableOriginalConstructor() ->getMock(); - $this->fieldInfo->expects($this->once()) - ->method('getInstance') - ->will($this->returnValue($field)); + $entity->expects($this->any()) + ->method('hasField') + ->will($this->returnValueMap(array( + array('valid', TRUE), + array('not_valid', FALSE), + ))); - $account = $this->getMock('Drupal\Core\Session\AccountInterface'); - $this->editAccessCheck->access($route, $request, $account); + return $entity; } } diff --git a/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php b/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php index e684a59..3fe0743 100644 --- a/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php +++ b/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php @@ -51,10 +51,9 @@ public function getRenderer($field_name) { } // Instantiate the formatter object from the stored display properties. - if ($configuration = $this->getComponent($field_name)) { - $instance = field_info_instance($this->targetEntityType, $field_name, $this->bundle); + if (($configuration = $this->getComponent($field_name)) && isset($configuration['type']) && ($definition = $this->getFieldDefinition($field_name))) { $formatter = $this->pluginManager->getInstance(array( - 'field_definition' => $instance, + 'field_definition' => $definition, 'view_mode' => $this->originalMode, // No need to prepare, defaults have been merged in setComponent(). 'prepare' => FALSE, diff --git a/core/modules/entity/lib/Drupal/entity/Entity/EntityFormDisplay.php b/core/modules/entity/lib/Drupal/entity/Entity/EntityFormDisplay.php index 461f7ce..c4637f7 100644 --- a/core/modules/entity/lib/Drupal/entity/Entity/EntityFormDisplay.php +++ b/core/modules/entity/lib/Drupal/entity/Entity/EntityFormDisplay.php @@ -51,10 +51,9 @@ public function getRenderer($field_name) { } // Instantiate the widget object from the stored display properties. - if ($configuration = $this->getComponent($field_name)) { - $instance = field_info_instance($this->targetEntityType, $field_name, $this->bundle); + if (($configuration = $this->getComponent($field_name)) && isset($configuration['type']) && ($definition = $this->getFieldDefinition($field_name))) { $widget = $this->pluginManager->getInstance(array( - 'field_definition' => $instance, + 'field_definition' => $definition, 'form_mode' => $this->originalMode, // No need to prepare, defaults have been merged in setComponent(). 'prepare' => FALSE, diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php index 0278c58..68fa682 100644 --- a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php +++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php @@ -8,6 +8,7 @@ namespace Drupal\entity; use Drupal\Core\Config\Entity\ConfigEntityBase; +use Drupal\Core\Entity\ContentEntityInterface; /** * Base class for config entity types that store configuration for entity forms @@ -44,6 +45,17 @@ public $bundle; /** + * A partial entity, created via _field_create_entity_from_ids() from + * $targetEntityType and $bundle. + * + * @var \Drupal\Core\Entity\EntityInterface + * + * @todo Remove when getFieldDefinition() is fixed to not need it. + * https://drupal.org/node/2114707 + */ + private $targetEntity; + + /** * View or form mode to be displayed. * * @var string @@ -187,9 +199,22 @@ public function getComponents() { * {@inheritdoc} */ public function getComponent($name) { - // We always store 'extra fields', whether they are visible or hidden. + // Until https://drupal.org/node/2144919 allows base fields to be configured + // in the UI, many base fields are also still registered as "extra fields" + // to keep appearing in the "Manage (form) display" screens. + // - Field UI still treats them as "base fields", saving only the weight + // and visibility flag in the EntityDisplay. + // - For some of them (e.g. node title), the custom rendering code has been + // removed in favor of regular widgets/formatters. Their display options + // are "upgraded" to those of a field (widget/formatter + settings) at + // runtime using hook_entity_display_alter(). + // The getComponent() / setComponent() methods handle this by treating + // components as "extra fields" if they are registered as such, *and* if + // their display options contain no 'type' entry specifying a widget or + // formatter. + // @todo Cleanup after https://drupal.org/node/2144919 is fixed. $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, $this->displayContext); - if (isset($extra_fields[$name])) { + if (isset($extra_fields[$name]) && !isset($this->content[$name]['type'])) { // If we have explicit settings, return an array or NULL depending on // visibility. if (isset($this->content[$name])) { @@ -215,8 +240,7 @@ public function getComponent($name) { return NULL; } } - - if (isset($this->content[$name])) { + elseif (isset($this->content[$name])) { return $this->content[$name]; } } @@ -231,18 +255,18 @@ public function setComponent($name, array $options = array()) { $options['weight'] = isset($max) ? $max + 1 : 0; } - if ($instance = field_info_instance($this->targetEntityType, $name, $this->bundle)) { - $options = $this->pluginManager->prepareConfiguration($instance->getFieldType(), $options); - - // Clear the persisted plugin, if any. - unset($this->plugins[$name]); - } - - // We always store 'extra fields', whether they are visible or hidden. + // See remark in getComponent(). + // @todo Cleanup after https://drupal.org/node/2144919 is fixed. $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, $this->displayContext); - if (isset($extra_fields[$name])) { + if (isset($extra_fields[$name]) && !isset($options['type'])) { $options['visible'] = TRUE; } + elseif ($field_definition = $this->getFieldDefinition($name)) { + $options = $this->pluginManager->prepareConfiguration($field_definition->getFieldType(), $options); + } + + // Clear the persisted plugin, if any. + unset($this->plugins[$name]); $this->content[$name] = $options; @@ -253,8 +277,10 @@ public function setComponent($name, array $options = array()) { * {@inheritdoc} */ public function removeComponent($name) { + // See remark in getComponent(). + // @todo Cleanup after https://drupal.org/node/2144919 is fixed. $extra_fields = field_info_extra_fields($this->targetEntityType, $this->bundle, $this->displayContext); - if (isset($extra_fields[$name])) { + if (isset($extra_fields[$name]) && !isset($this->content[$name]['type'])) { // 'Extra fields' are exposed in hooks and can appear at any given time. // Therefore we store extra fields that are explicitly being hidden, so // that we can differenciate with those that are simply not configured @@ -265,9 +291,10 @@ public function removeComponent($name) { } else { unset($this->content[$name]); - unset($this->plugins[$name]); } + unset($this->plugins[$name]); + return $this; } @@ -290,4 +317,18 @@ public function getHighestWeight() { return $weights ? max($weights) : NULL; } + /** + * Returns the field definition of a field. + */ + protected function getFieldDefinition($field_name) { + // @todo Replace this entire implementation with + // \Drupal::entityManager()->getFieldDefinition() when it can hand the + // $instance objects - https://drupal.org/node/2114707 + if (!isset($this->targetEntity)) { + $this->targetEntity = _field_create_entity_from_ids((object) array('entity_type' => $this->targetEntityType, 'bundle' => $this->bundle, 'entity_id' => NULL)); + } + if (($this->targetEntity instanceof ContentEntityInterface) && $this->targetEntity->hasField($field_name)) { + return $this->targetEntity->get($field_name)->getFieldDefinition(); + } + } } diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php index b2879dc..2e0ad2d 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php @@ -100,7 +100,7 @@ public function testAutoCreate() { $this->assertFalse($result, 'Referenced node does not exist yet.'); $edit = array( - 'title' => $this->randomName(), + 'title[0][value]' => $this->randomName(), 'test_field[0][target_id]' => $new_title, ); $this->drupalPostForm("node/add/$this->referencing_type", $edit, 'Save'); diff --git a/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc index 5567afd..70f197b 100644 --- a/core/modules/field/field.attach.inc +++ b/core/modules/field/field.attach.inc @@ -6,6 +6,7 @@ */ use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\entity\Entity\EntityFormDisplay; /** @@ -63,8 +64,8 @@ * @param string $method * The name of the method to invoke. * @param callable $target_function - * A function that receives an $instance object and returns the object on - * which the method should be invoked. + * A function that receives a FieldDefinitionInterface object and returns the + * object on which the method should be invoked. * @param \Drupal\Core\Entity\EntityInterface $entity * The fully formed $entity_type entity. * @param mixed $a @@ -76,66 +77,38 @@ * keys: * - field_name: The name of the field whose operation should be invoked. By * default, the operation is invoked on all the fields in the entity's - * bundle. NOTE: This option is not compatible with the 'deleted' option; - * the 'field_id' option should be used instead. - * - field_id: The ID of the field whose operation should be invoked. By - * default, the operation is invoked on all the fields in the entity's' - * bundles. - * - deleted: If TRUE, the function will operate on deleted fields as well - * as non-deleted fields. If unset or FALSE, only non-deleted fields are - * operated on. - * - langcode: A language code or an array of language codes keyed by field - * name. It will be used to narrow down to a single value the available - * languages to act on. + * bundle. * * @return array * An array of returned values. */ function field_invoke_method($method, $target_function, EntityInterface $entity, &$a = NULL, &$b = NULL, array $options = array()) { - // Merge default options. - $default_options = array( - 'deleted' => FALSE, - 'langcode' => NULL, - ); - $options += $default_options; - $entity_type = $entity->entityType(); - // Determine the list of instances to iterate on. - $instances = _field_invoke_get_instances($entity_type, $entity->bundle(), $options); - // Iterate through the instances and collect results. - $return = array(); - foreach ($instances as $instance) { + // Determine the list of fields to iterate on. + $field_definitions = _field_invoke_get_field_definitions($entity_type, $entity->bundle(), $options); + // Iterate through the fields and collect results. + $return = array(); + foreach ($field_definitions as $field_definition) { // Let the function determine the target object on which the method should be // called. - $target = call_user_func($target_function, $instance); + $target = call_user_func($target_function, $field_definition); if (method_exists($target, $method)) { - $field = $instance->getField(); - $field_name = $field->getFieldName(); - - // Determine the list of languages to iterate on. - $available_langcodes = field_available_languages($entity_type, $field); - $langcodes = _field_language_suggestion($available_langcodes, $options['langcode'], $field_name); + $items = $entity->get($field_definition->getFieldName()); + $items->filterEmptyValues(); - foreach ($langcodes as $langcode) { - if ($entity->hasTranslation($langcode)) { - $items = $entity->getTranslation($langcode)->get($field_name); - $items->filterEmptyValues(); + $result = $target->$method($items, $a, $b); - $result = $target->$method($items, $a, $b); - - if (isset($result)) { - // For methods with array results, we merge results together. - // For methods with scalar results, we collect results in an array. - if (is_array($result)) { - $return = array_merge($return, $result); - } - else { - $return[] = $result; - } - } + if (isset($result)) { + // For methods with array results, we merge results together. + // For methods with scalar results, we collect results in an array. + if (is_array($result)) { + $return = array_merge($return, $result); + } + else { + $return[] = $result; } } } @@ -150,8 +123,8 @@ function field_invoke_method($method, $target_function, EntityInterface $entity, * @param string $method * The name of the method to invoke. * @param callable $target_function - * A function that receives an $instance object and returns the object on - * which the method should be invoked. + * A function that receives a FieldDefinitionInterface object and a bundle + * name and returns the object on which the method should be invoked. * @param array $entities * An array of entities, keyed by entity ID. * @param mixed $a @@ -163,17 +136,7 @@ function field_invoke_method($method, $target_function, EntityInterface $entity, * keys: * - field_name: The name of the field whose operation should be invoked. By * default, the operation is invoked on all the fields in the entity's - * bundle. NOTE: This option is not compatible with the 'deleted' option; - * the 'field_id' option should be used instead. - * - field_id: The ID of the field whose operation should be invoked. By - * default, the operation is invoked on all the fields in the entity's' - * bundles. - * - deleted: If TRUE, the function will operate on deleted fields as well - * as non-deleted fields. If unset or FALSE, only non-deleted fields are - * operated on. - * - langcode: A language code or an array of language codes keyed by field - * name. It will be used to narrow down to a single value the available - * languages to act on. + * bundle. * * @return array * An array of returned values keyed by entity ID. @@ -181,14 +144,6 @@ function field_invoke_method($method, $target_function, EntityInterface $entity, * @see field_invoke_method() */ function field_invoke_method_multiple($method, $target_function, array $entities, &$a = NULL, &$b = NULL, array $options = array()) { - // Merge default options. - $default_options = array( - 'deleted' => FALSE, - 'langcode' => NULL, - ); - $options += $default_options; - - $instances = array(); $grouped_items = array(); $grouped_targets = array(); $return = array(); @@ -196,65 +151,54 @@ function field_invoke_method_multiple($method, $target_function, array $entities // Go through the entities and collect the instances on which the method // should be called. foreach ($entities as $entity) { - $id = $entity->id(); $entity_type = $entity->entityType(); + $bundle = $entity->bundle(); + $id = $entity->id(); - // Determine the list of instances to iterate on. - $entity_instances = _field_invoke_get_instances($entity_type, $entity->bundle(), $options); + // Determine the list of fields to iterate on. + $field_definitions = _field_invoke_get_field_definitions($entity_type, $bundle, $options); - foreach ($entity_instances as $instance) { - $instance_uuid = $instance->uuid(); - $field_name = $instance->getFieldName(); + foreach ($field_definitions as $field_definition) { + $field_name = $field_definition->getFieldName(); + $group_key = "$bundle:$field_name"; // Let the closure determine the target object on which the method should // be called. - if (empty($grouped_targets[$instance_uuid])) { - $grouped_targets[$instance_uuid] = call_user_func($target_function, $instance); - } - - if (method_exists($grouped_targets[$instance_uuid], $method)) { - // Add the instance to the list of instances to invoke the hook on. - if (!isset($instances[$instance_uuid])) { - $instances[$instance_uuid] = $instance; + if (empty($grouped_targets[$group_key])) { + $target = call_user_func($target_function, $field_definition, $bundle); + if (method_exists($target, $method)) { + $grouped_targets[$group_key] = $target; } - - // Unless a language code suggestion is provided we iterate on all the - // available language codes. - $field = $instance->getField(); - $available_langcodes = field_available_languages($entity_type, $field); - $langcode = !empty($options['langcode'][$id]) ? $options['langcode'][$id] : $options['langcode']; - $langcodes = _field_language_suggestion($available_langcodes, $langcode, $field_name); - foreach ($langcodes as $langcode) { - if ($entity->hasTranslation($langcode)) { - // Group the items corresponding to the current field. - $items = $entity->getTranslation($langcode)->get($field_name); - $items->filterEmptyValues(); - $grouped_items[$instance_uuid][$langcode][$id] = $items; - } + else { + $grouped_targets[$group_key] = FALSE; } } + + // If there is a target, group the field items. + if ($grouped_targets[$group_key]) { + $items = $entity->get($field_name); + $items->filterEmptyValues(); + $grouped_items[$group_key][$id] = $items; + } } // Initialize the return value for each entity. $return[$id] = array(); } - // For each instance, invoke the method and collect results. - foreach ($instances as $instance_uuid => $instance) { - // Iterate over all the field translations. - foreach ($grouped_items[$instance_uuid] as $items) { - $results = $grouped_targets[$instance_uuid]->$method($items, $a, $b); + // For each field, invoke the method and collect results. + foreach ($grouped_items as $key => $entities_items) { + $results = $grouped_targets[$key]->$method($entities_items, $a, $b); - if (isset($results)) { - // Collect results by entity. - // For hooks with array results, we merge results together. - // For hooks with scalar results, we collect results in an array. - foreach ($results as $id => $result) { - if (is_array($result)) { - $return[$id] = array_merge($return[$id], $result); - } - else { - $return[$id][] = $result; - } + if (isset($results)) { + // Collect results by entity. + // For hooks with array results, we merge results together. + // For hooks with scalar results, we collect results in an array. + foreach ($results as $id => $result) { + if (is_array($result)) { + $return[$id] = array_merge($return[$id], $result); + } + else { + $return[$id][] = $result; } } } @@ -264,7 +208,7 @@ function field_invoke_method_multiple($method, $target_function, array $entities } /** - * Retrieves a list of instances to operate on. + * Retrieves a list of field definitions to operate on. * * Helper for field_invoke_method(). * @@ -281,47 +225,31 @@ function field_invoke_method_multiple($method, $target_function, array $entities * See field_invoke_method() for details. * * @return - * The array of selected instance definitions. + * The array of selected field definitions. */ -function _field_invoke_get_instances($entity_type, $bundle, $options) { - if ($options['deleted']) { - // Deleted fields are not included in field_info_instances(), and need to - // be fetched from the database with field_read_instances(). - $params = array('entity_type' => $entity_type, 'bundle' => $bundle); - if (isset($options['field_id'])) { - // Single-field mode by field id: field_read_instances() does the filtering. - // Single-field mode by field name is not compatible with the 'deleted' - // option. - $params['field_id'] = $options['field_id']; +function _field_invoke_get_field_definitions($entity_type, $bundle, $options) { + // @todo Replace with \Drupal::entityManager()->getFieldDefinition() after + // [#2047229] lands. + $entity = _field_create_entity_from_ids((object) array('entity_type' => $entity_type, 'bundle' => $bundle, 'entity_id' => NULL)); + $field_definitions = array(); + if (isset($options['field_name'])) { + if ($entity->hasField($options['field_name'])) { + $field_definitions[] = $entity->get($options['field_name'])->getFieldDefinition(); } - $instances = field_read_instances($params, array('include_deleted' => TRUE)); - } - elseif (isset($options['field_name'])) { - // Single-field mode by field name: field_info_instance() does the - // filtering. - $instances = array(field_info_instance($entity_type, $options['field_name'], $bundle)); } else { - $instances = field_info_instances($entity_type, $bundle); - if (isset($options['field_id'])) { - // Single-field mode by field id: we need to loop on each instance to - // find the right one. - foreach ($instances as $instance) { - if ($instance->getField()->uuid() == $options['field_id']) { - $instances = array($instance); - break; - } - } + foreach ($entity as $items) { + $field_definitions[] = $items->getFieldDefinition(); } } - return $instances; + return $field_definitions; } /** * Defines a 'target function' for field_invoke_method(). * - * Used to invoke methods on an instance's widget. + * Used to invoke methods on a field's widget. * * @param \Drupal\entity\Entity\EntityFormDisplay $form_display * An EntityFormDisplay object. @@ -330,8 +258,8 @@ function _field_invoke_get_instances($entity_type, $bundle, $options) { * A 'target function' for field_invoke_method(). */ function _field_invoke_widget_target($form_display) { - return function ($instance) use ($form_display) { - return $form_display->getRenderer($instance->getFieldName()); + return function (FieldDefinitionInterface $field_definition) use ($form_display) { + return $form_display->getRenderer($field_definition->getFieldName()); }; } diff --git a/core/modules/field/field.deprecated.inc b/core/modules/field/field.deprecated.inc index 86fa460..fcb7785 100644 --- a/core/modules/field/field.deprecated.inc +++ b/core/modules/field/field.deprecated.inc @@ -8,10 +8,10 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Language\Language; +use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\entity\Entity\EntityDisplay; use Drupal\field\Field; - /** * Returns information about field types. * @@ -565,8 +565,6 @@ function field_attach_form(EntityInterface $entity, &$form, &$form_state, $langc // Get the entity_form_display object for this form. $form_display = $form_state['form_display']; - // If no language is provided use the default site language. - $options['langcode'] = field_valid_language($langcode); $form += (array) field_invoke_method('form', _field_invoke_widget_target($form_display), $entity, $form, $form_state, $options); $form['#entity_type'] = $entity->entityType(); @@ -631,7 +629,8 @@ function field_attach_form_validate(ContentEntityInterface $entity, $form, &$for if ($has_violations) { // Map errors back to form elements. - field_invoke_method('flagErrors', _field_invoke_widget_target($form_state['form_display']), $entity, $form, $form_state, $options); + $form_display = $form_state['form_display']; + field_invoke_method('flagErrors', _field_invoke_widget_target($form_display), $entity, $form, $form_state, $options); } } @@ -696,8 +695,6 @@ function field_attach_extract_form_values(EntityInterface $entity, $form, &$form * @deprecated as of Drupal 8.0. Use the entity system instead. */ function field_attach_prepare_view($entity_type, array $entities, array $displays, $langcode = NULL) { - $options['langcode'] = array(); - // To ensure hooks are only run once per entity, only process items without // the _field_view_prepared flag. // @todo: resolve this more generally for both entity and field level hooks. @@ -707,10 +704,6 @@ function field_attach_prepare_view($entity_type, array $entities, array $display // Add this entity to the items to be prepared. $prepare[$id] = $entity; - // Determine the actual language code to display for each field, given the - // language codes available in the field data. - $options['langcode'][$id] = field_language($entity, NULL, $langcode); - // Mark this item as prepared. $entity->_field_view_prepared = TRUE; } @@ -719,9 +712,9 @@ function field_attach_prepare_view($entity_type, array $entities, array $display // Then let the formatters do their own specific massaging. For each // instance, call the prepareView() method on the formatter object handed by // the entity display. - $target_function = function ($instance) use ($displays) { - if (isset($displays[$instance->bundle])) { - return $displays[$instance->bundle]->getRenderer($instance->getFieldName()); + $target_function = function (FieldDefinitionInterface $field_definition, $bundle) use ($displays) { + if (isset($displays[$bundle])) { + return $displays[$bundle]->getRenderer($field_definition->getFieldName()); } }; $null = NULL; @@ -749,7 +742,7 @@ function field_attach_prepare_view($entity_type, array $entities, array $display * provided the current language is used. * @param array $options * An associative array of additional options. See field_invoke_method() for - * details. Note: key "langcode" will be overridden inside this function. + * details. * * @return array * A renderable array for the field values. @@ -757,14 +750,10 @@ function field_attach_prepare_view($entity_type, array $entities, array $display * @deprecated as of Drupal 8.0. Use the entity system instead. */ function field_attach_view(EntityInterface $entity, EntityDisplay $display, $langcode = NULL, array $options = array()) { - // Determine the actual language code to display for each field, given the - // language codes available in the field data. - $options['langcode'] = field_language($entity, NULL, $langcode); - - // For each instance, call the view() method on the formatter object handed + // For each field, call the view() method on the formatter object handed // by the entity display. - $target_function = function ($instance) use ($display) { - return $display->getRenderer($instance->getFieldName()); + $target_function = function (FieldDefinitionInterface $field_definition) use ($display) { + return $display->getRenderer($field_definition->getFieldName()); }; $null = NULL; $output = field_invoke_method('view', $target_function, $entity, $null, $null, $options); diff --git a/core/modules/field/field.module b/core/modules/field/field.module index 91464f0..584a554 100644 --- a/core/modules/field/field.module +++ b/core/modules/field/field.module @@ -4,6 +4,7 @@ * Attach custom data fields to Drupal entities. */ +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Template\Attribute; use Drupal\field\FieldInterface; @@ -444,7 +445,7 @@ function field_view_value(EntityInterface $entity, $field_name, $item, $display * The function takes care of invoking the prepare_view steps. It also respects * field access permissions. * - * @param \Drupal\Core\Entity\EntityInterface $entity + * @param \Drupal\Core\Entity\ContentEntityInterface $entity * The entity containing the field to display. * @param $field_name * The name of the field to display. @@ -477,16 +478,16 @@ function field_view_value(EntityInterface $entity, $field_name, $item, $display * * @see field_view_value() */ -function field_view_field(EntityInterface $entity, $field_name, $display_options = array(), $langcode = NULL) { +function field_view_field(ContentEntityInterface $entity, $field_name, $display_options = array(), $langcode = NULL) { $output = array(); $bundle = $entity->bundle(); $entity_type = $entity->entityType(); // Return nothing if the field doesn't exist. - $instance = field_info_instance($entity_type, $field_name, $bundle); - if (!$instance) { + if (!$entity->hasField($field_name)) { return $output; } + $field_definition = $entity->get($field_name)->getFieldDefinition(); // Get the formatter object. if (is_string($display_options)) { @@ -497,11 +498,10 @@ function field_view_field(EntityInterface $entity, $field_name, $display_options $view_mode = '_custom'; // hook_field_attach_display_alter() needs to receive the 'prepared' // $display_options, so we cannot let preparation happen internally. - $field = field_info_field($entity_type, $field_name); $formatter_manager = Drupal::service('plugin.manager.field.formatter'); - $display_options = $formatter_manager->prepareConfiguration($field->getFieldType(), $display_options); + $display_options = $formatter_manager->prepareConfiguration($field_definition->getFieldType(), $display_options); $formatter = $formatter_manager->getInstance(array( - 'field_definition' => $instance, + 'field_definition' => $field_definition, 'view_mode' => $view_mode, 'prepare' => FALSE, 'configuration' => $display_options, @@ -711,7 +711,7 @@ function template_preprocess_field(&$variables, $hook) { * the exact performance impact depends on the server configuration and the * details of the website. * - * @param $variables + * @param array $variables * An associative array containing: * - label_hidden: A boolean indicating whether to show or hide the field * label. diff --git a/core/modules/field/lib/Drupal/field/Tests/reEnableModuleFieldTest.php b/core/modules/field/lib/Drupal/field/Tests/reEnableModuleFieldTest.php index 928adbb..87e2347 100644 --- a/core/modules/field/lib/Drupal/field/Tests/reEnableModuleFieldTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/reEnableModuleFieldTest.php @@ -85,8 +85,8 @@ function testReEnabledField() { // Submit an article node with a telephone field so data exist for the // field. $edit = array( - "title" => $this->randomName(), - "field_telephone[0][value]" => "123456789", + 'title[0][value]' => $this->randomName(), + 'field_telephone[0][value]' => "123456789", ); $this->drupalPostForm(NULL, $edit, t('Save')); $this->assertRaw(''); diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php index 7edeec7..0405c3a 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php @@ -139,7 +139,7 @@ function updateFileField($name, $type_name, $instance_settings = array(), $widge */ function uploadNodeFile($file, $field_name, $nid_or_type, $new_revision = TRUE, $extras = array()) { $edit = array( - "title" => $this->randomName(), + 'title[0][value]' => $this->randomName(), 'revision' => (string) (int) $new_revision, ); diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php index d4e27f5..b6d6c48 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php @@ -37,7 +37,8 @@ function testRequired() { $test_file = $this->getTestFile('text'); // Try to post a new node without uploading a file. - $edit = array("title" => $this->randomName()); + $edit = array(); + $edit['title[0][value]'] = $this->randomName(); $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish')); $this->assertRaw(t('!title field is required.', array('!title' => $instance->getFieldLabel())), 'Node save failed when required file field was empty.'); @@ -56,7 +57,8 @@ function testRequired() { $this->createFileField($field_name, 'node', $type_name, array('cardinality' => FieldDefinitionInterface::CARDINALITY_UNLIMITED), array('required' => '1')); // Try to post a new node without uploading a file in the multivalue field. - $edit = array('title' => $this->randomName()); + $edit = array(); + $edit['title[0][value]'] = $this->randomName(); $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish')); $this->assertRaw(t('!title field is required.', array('!title' => $instance->getFieldLabel())), 'Node save failed when required multiple value file field was empty.'); diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php index d328bd5..bf80c17 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php @@ -189,7 +189,7 @@ function testMultiValuedWidget() { $this->assertNoFieldByXPath('//input[@type="submit"]', t('Remove'), format_string('After removing all files, there is no "Remove" button displayed (JSMode=%type).', array('%type' => $type))); // Save the node and ensure it does not have any files. - $this->drupalPostForm(NULL, array('title' => $this->randomName()), t('Save and publish')); + $this->drupalPostForm(NULL, array('title[0][value]' => $this->randomName()), t('Save and publish')); $matches = array(); preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches); $nid = $matches[1]; @@ -267,10 +267,10 @@ function testPrivateFileComment() { // Create node. $edit = array( - 'title' => $this->randomName(), + 'title[0][value]' => $this->randomName(), ); $this->drupalPostForm('node/add/article', $edit, t('Save and publish')); - $node = $this->drupalGetNodeByTitle($edit['title']); + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); // Add a comment with a file. $text_file = $this->getTestFile('text'); diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterAdminTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterAdminTest.php index bccc9f3..e10c5ca 100644 --- a/core/modules/filter/lib/Drupal/filter/Tests/FilterAdminTest.php +++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterAdminTest.php @@ -232,13 +232,13 @@ function testFilterAdmin() { $text = $body . '' . $extra_text . ''; $edit = array(); - $edit["title"] = $this->randomName(); + $edit['title[0][value]'] = $this->randomName(); $edit['body[0][value]'] = $text; $edit['body[0][format]'] = $basic; $this->drupalPostForm('node/add/page', $edit, t('Save')); - $this->assertRaw(t('Basic page %title has been created.', array('%title' => $edit["title"])), 'Filtered node created.'); + $this->assertRaw(t('Basic page %title has been created.', array('%title' => $edit['title[0][value]'])), 'Filtered node created.'); - $node = $this->drupalGetNodeByTitle($edit["title"]); + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); $this->assertTrue($node, 'Node found in database.'); $this->drupalGet('node/' . $node->id()); diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php index d18e7d5..cbf1661 100644 --- a/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php +++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php @@ -211,11 +211,11 @@ function testFormatWidgetPermissions() { // Create node to edit. $this->drupalLogin($this->admin_user); $edit = array(); - $edit['title'] = $this->randomName(8); + $edit['title[0][value]'] = $this->randomName(8); $edit[$body_value_key] = $this->randomName(16); $edit[$body_format_key] = $this->disallowed_format->format; $this->drupalPostForm('node/add/page', $edit, t('Save')); - $node = $this->drupalGetNodeByTitle($edit['title']); + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); // Try to edit with a less privileged user. $this->drupalLogin($this->web_user); @@ -227,14 +227,14 @@ function testFormatWidgetPermissions() { // Verify that title can be changed, but preview displays original body. $new_edit = array(); - $new_edit['title'] = $this->randomName(8); + $new_edit['title[0][value]'] = $this->randomName(8); $this->drupalPostForm(NULL, $new_edit, t('Preview')); $this->assertText($edit[$body_value_key], 'Old body found in preview.'); // Save and verify that only the title was changed. $this->drupalPostForm(NULL, $new_edit, t('Save')); - $this->assertNoText($edit['title'], 'Old title not found.'); - $this->assertText($new_edit['title'], 'New title found.'); + $this->assertNoText($edit['title[0][value]'], 'Old title not found.'); + $this->assertText($new_edit['title[0][value]'], 'New title found.'); $this->assertText($edit[$body_value_key], 'Old body found.'); // Check that even an administrator with "administer filters" permission @@ -266,9 +266,10 @@ function testFormatWidgetPermissions() { // Verify that trying to save the node without selecting a new text format // produces an error message, and does not result in the node being saved. - $old_title = $new_edit['title']; + $old_title = $new_edit['title[0][value]']; $new_title = $this->randomName(8); - $edit = array('title' => $new_title); + $edit = array(); + $edit['title[0][value]'] = $new_title; $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); $this->assertText(t('!name field is required.', array('!name' => t('Text format'))), 'Error message is displayed.'); $this->drupalGet('node/' . $node->id()); @@ -302,7 +303,8 @@ function testFormatWidgetPermissions() { $this->drupalLogin($this->filter_admin_user); $old_title = $new_title; $new_title = $this->randomName(8); - $edit = array('title' => $new_title); + $edit = array(); + $edit['title[0][value]'] = $new_title; $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); $this->assertText(t('!name field is required.', array('!name' => t('Text format'))), 'Error message is displayed.'); $this->drupalGet('node/' . $node->id()); diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterHooksTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterHooksTest.php index febf33d..b23ed88 100644 --- a/core/modules/filter/lib/Drupal/filter/Tests/FilterHooksTest.php +++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterHooksTest.php @@ -65,11 +65,10 @@ function testFilterHooks() { // Use the format created. $title = $this->randomName(8); - $edit = array( - "title" => $title, - "body[0][value]" => $this->randomName(32), - "body[0][format]" => $format_id, - ); + $edit = array(); + $edit['title[0][value]'] = $title; + $edit['body[0][value]'] = $this->randomName(32); + $edit['body[0][format]'] = $format_id; $this->drupalPostForm("node/add/{$type->type}", $edit, t('Save and publish')); $this->assertText(t('@type @title has been created.', array('@type' => $type_name, '@title' => $title))); diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php index dda30f1..ab8feb9 100644 --- a/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php +++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php @@ -170,7 +170,7 @@ protected function createForumTopics($count = 5) { $date->modify('+1 minute'); $edit = array( - 'title' => $title, + 'title[0][value]' => $title, 'body[0][value]' => $body, // Forum posts are ordered by timestamp, so force a unique timestamp by // adding the index. diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumIndexTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumIndexTest.php index 3cc01d2..8c1f3ee 100644 --- a/core/modules/forum/lib/Drupal/forum/Tests/ForumIndexTest.php +++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumIndexTest.php @@ -47,7 +47,7 @@ function testForumIndexStatus() { // Create a test node. $title = $this->randomName(20); $edit = array( - 'title' => $title, + 'title[0][value]' => $title, 'body[0][value]' => $this->randomName(200), ); diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php index 489cc1b..99f8b25 100644 --- a/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php +++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php @@ -52,7 +52,7 @@ function testForumNodeAccess() { // Create a private node. $private_node_title = $this->randomName(20); $edit = array( - 'title' => $private_node_title, + 'title[0][value]' => $private_node_title, 'body[0][value]' => $this->randomName(200), 'private' => TRUE, ); @@ -63,7 +63,7 @@ function testForumNodeAccess() { // Create a public node. $public_node_title = $this->randomName(20); $edit = array( - 'title' => $public_node_title, + 'title[0][value]' => $public_node_title, 'body[0][value]' => $this->randomName(200), ); $this->drupalPostForm('node/add/forum', $edit, t('Save'), array('query' => array('forum_id' => 1))); diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php index 8e7bbb4..9065673 100644 --- a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php +++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php @@ -223,8 +223,11 @@ function testAddOrphanTopic() { entity_delete_multiple('taxonomy_term', $tids); // Create an orphan forum item. + $edit = array(); + $edit['title[0][value]'] = $this->randomName(10); + $edit['body[0][value]'] = $this->randomName(120); $this->drupalLogin($this->admin_user); - $this->drupalPostForm('node/add/forum', array('title' => $this->randomName(10), 'body[0][value]' => $this->randomName(120)), t('Save')); + $this->drupalPostForm('node/add/forum', $edit, t('Save')); $nid_count = db_query('SELECT COUNT(nid) FROM {node}')->fetchField(); $this->assertEqual(0, $nid_count, 'A forum node was not created when missing a forum vocabulary.'); @@ -484,7 +487,7 @@ function createForumTopic($forum, $container = FALSE) { $body = $this->randomName(200); $edit = array( - 'title' => $title, + 'title[0][value]' => $title, 'body[0][value]' => $body, ); $tid = $forum['tid']; @@ -572,13 +575,13 @@ private function verifyForums($node_user, EntityInterface $node, $admin, $respon if ($response == 200) { // Edit forum node (including moving it to another forum). $edit = array(); - $edit['title'] = 'node/' . $node->id(); + $edit['title[0][value]'] = 'node/' . $node->id(); $edit['body[0][value]'] = $this->randomName(256); // Assume the topic is initially associated with $forum. $edit['taxonomy_forums'] = $this->root_forum['tid']; $edit['shadow'] = TRUE; $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); - $this->assertRaw(t('Forum topic %title has been updated.', array('%title' => $edit["title"])), 'Forum node was edited'); + $this->assertRaw(t('Forum topic %title has been updated.', array('%title' => $edit['title[0][value]'])), 'Forum node was edited'); // Verify topic was moved to a different forum. $forum_tid = db_query("SELECT tid FROM {forum} WHERE nid = :nid AND vid = :vid", array( @@ -590,7 +593,7 @@ private function verifyForums($node_user, EntityInterface $node, $admin, $respon // Delete forum node. $this->drupalPostForm('node/' . $node->id() . '/delete', array(), t('Delete')); $this->assertResponse($response); - $this->assertRaw(t('Forum topic %title has been deleted.', array('%title' => $edit['title'])), 'Forum node was deleted'); + $this->assertRaw(t('Forum topic %title has been deleted.', array('%title' => $edit['title[0][value]'])), 'Forum node was deleted'); } } diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php index 64523a1..a000828 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php @@ -114,7 +114,7 @@ function createImageField($name, $type_name, $field_settings = array(), $instanc */ function uploadNodeImage($image, $field_name, $type) { $edit = array( - 'title' => $this->randomName(), + 'title[0][value]' => $this->randomName(), ); $edit['files[' . $field_name . '_0]'] = drupal_realpath($image->uri); $this->drupalPostForm('node/add/' . $type, $edit, t('Save and publish')); diff --git a/core/modules/menu/lib/Drupal/menu/Tests/MenuNodeTest.php b/core/modules/menu/lib/Drupal/menu/Tests/MenuNodeTest.php index 39a9d43..d7dd52c 100644 --- a/core/modules/menu/lib/Drupal/menu/Tests/MenuNodeTest.php +++ b/core/modules/menu/lib/Drupal/menu/Tests/MenuNodeTest.php @@ -62,7 +62,7 @@ function testMenuNodeFormWidget() { // Create a node. $node_title = $this->randomName(); $edit = array( - 'title' => $node_title, + 'title[0][value]' => $node_title, 'body[0][value]' => $this->randomString(), ); $this->drupalPostForm('node/add/page', $edit, t('Save')); diff --git a/core/modules/node/lib/Drupal/node/Entity/Node.php b/core/modules/node/lib/Drupal/node/Entity/Node.php index 3700499..1d8c5c5 100644 --- a/core/modules/node/lib/Drupal/node/Entity/Node.php +++ b/core/modules/node/lib/Drupal/node/Entity/Node.php @@ -359,13 +359,13 @@ public static function baseFieldDefinitions($entity_type) { $properties['title'] = array( 'label' => t('Title'), 'description' => t('The title of this node, always treated as non-markup plain text.'), - 'type' => 'string_field', + 'type' => 'field_item:text', + 'list_class' => '\Drupal\node\NodeTitleItemList', 'required' => TRUE, 'settings' => array( 'default_value' => '', - ), - 'property_constraints' => array( - 'value' => array('Length' => array('max' => 255)), + 'max_length' => 255, + 'text_processing' => 0, ), 'translatable' => TRUE, ); diff --git a/core/modules/node/lib/Drupal/node/NodeFormController.php b/core/modules/node/lib/Drupal/node/NodeFormController.php index 70cf1da..1153188 100644 --- a/core/modules/node/lib/Drupal/node/NodeFormController.php +++ b/core/modules/node/lib/Drupal/node/NodeFormController.php @@ -101,18 +101,6 @@ public function form(array $form, array &$form_state) { '#default_value' => $node->getChangedTime(), ); - $node_type = node_type_load($node->getType()); - if ($node_type->has_title) { - $form['title'] = array( - '#type' => 'textfield', - '#title' => check_plain($node_type->title_label), - '#required' => TRUE, - '#default_value' => $node->title->value, - '#maxlength' => 255, - '#weight' => -5, - ); - } - $language_configuration = module_invoke('language', 'get_default_configuration', 'node', $node->getType()); $form['langcode'] = array( '#title' => t('Language'), diff --git a/core/modules/node/lib/Drupal/node/NodeTitleItemList.php b/core/modules/node/lib/Drupal/node/NodeTitleItemList.php new file mode 100644 index 0000000..c5f25e9 --- /dev/null +++ b/core/modules/node/lib/Drupal/node/NodeTitleItemList.php @@ -0,0 +1,34 @@ +getType()); + if (isset($node_type->title_label)) { + $definition->setFieldLabel($node_type->title_label); + } + parent::__construct($definition, $name, $node); + } + +} diff --git a/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php b/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php index 25036b9..d8a67a0 100644 --- a/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php @@ -61,7 +61,7 @@ function testMultiStepNodeFormBasicOptions() { ->save(); $edit = array( - 'title' => 'a', + 'title[0][value]' => 'a', 'promote' => FALSE, 'sticky' => 1, "{$this->field_name}[0][value]" => $this->randomString(32), diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeAccessBaseTableTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeAccessBaseTableTest.php index 8fc72f6..e78b5bc 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeAccessBaseTableTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeAccessBaseTableTest.php @@ -72,7 +72,7 @@ function testNodeAccessBasic() { $this->drupalLogin($this->webUser); foreach (array(0 => 'Public', 1 => 'Private') as $is_private => $type) { $edit = array( - 'title' => t('@private_public Article created by @user', array('@private_public' => $type, '@user' => $this->webUser->getUsername())), + 'title[0][value]' => t('@private_public Article created by @user', array('@private_public' => $type, '@user' => $this->webUser->getUsername())), ); if ($is_private) { $edit['private'] = TRUE; @@ -85,13 +85,13 @@ function testNodeAccessBasic() { } $this->drupalPostForm('node/add/article', $edit, t('Save')); - $nid = db_query('SELECT nid FROM {node_field_data} WHERE title = :title', array(':title' => $edit['title']))->fetchField(); + $nid = db_query('SELECT nid FROM {node_field_data} WHERE title = :title', array(':title' => $edit['title[0][value]']))->fetchField(); $private_status = db_query('SELECT private FROM {node_access_test} where nid = :nid', array(':nid' => $nid))->fetchField(); $this->assertTrue($is_private == $private_status, 'The private status of the node was properly set in the node_access_test table.'); if ($is_private) { $private_nodes[] = $nid; } - $titles[$nid] = $edit['title']; + $titles[$nid] = $edit['title[0][value]']; $this->nodesByUser[$this->webUser->id()][$nid] = $is_private; } } diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeCreationTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeCreationTest.php index 2e69cde..71e07de 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeCreationTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeCreationTest.php @@ -45,15 +45,15 @@ function setUp() { function testNodeCreation() { // Create a node. $edit = array(); - $edit["title"] = $this->randomName(8); - $edit["body[0][value]"] = $this->randomName(16); + $edit['title[0][value]'] = $this->randomName(8); + $edit['body[0][value]'] = $this->randomName(16); $this->drupalPostForm('node/add/page', $edit, t('Save')); // Check that the Basic page has been created. - $this->assertRaw(t('!post %title has been created.', array('!post' => 'Basic page', '%title' => $edit["title"])), 'Basic page created.'); + $this->assertRaw(t('!post %title has been created.', array('!post' => 'Basic page', '%title' => $edit['title[0][value]'])), 'Basic page created.'); // Check that the node exists in the database. - $node = $this->drupalGetNodeByTitle($edit["title"]); + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); $this->assertTrue($node, 'Node found in database.'); } @@ -110,7 +110,7 @@ function testUnpublishedNodeCreation() { // Create a node. $edit = array(); - $edit['title'] = $this->randomName(8); + $edit['title[0][value]'] = $this->randomName(8); $edit['body[0][value]'] = $this->randomName(16); $this->drupalPostForm('node/add/page', $edit, t('Save')); @@ -119,7 +119,7 @@ function testUnpublishedNodeCreation() { $this->assertText(t('Test page text')); // Confirm that the node was created. - $this->assertRaw(t('!post %title has been created.', array('!post' => 'Basic page', '%title' => $edit["title"]))); + $this->assertRaw(t('!post %title has been created.', array('!post' => 'Basic page', '%title' => $edit['title[0][value]']))); } /** diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeEntityViewModeAlterTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeEntityViewModeAlterTest.php index 7a1ed97..2fb9918 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeEntityViewModeAlterTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeEntityViewModeAlterTest.php @@ -34,12 +34,12 @@ function testNodeViewModeChange() { // Create a node. $edit = array(); - $edit['title'] = $this->randomName(8); + $edit['title[0][value]'] = $this->randomName(8); $edit['body[0][value]'] = t('Data that should appear only in the body for the node.'); $edit['body[0][summary]'] = t('Extra data that should appear only in the teaser for the node.'); $this->drupalPostForm('node/add/page', $edit, t('Save')); - $node = $this->drupalGetNodeByTitle($edit["title"]); + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); // Set the flag to alter the view mode and view the node. \Drupal::state()->set('node_test_change_view_mode', 'teaser'); diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php index e6626ca..f535182 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php @@ -70,7 +70,7 @@ function setUp() { function testMultilingualNodeForm() { // Create "Basic page" content. $langcode = language_get_default_langcode('node', 'page'); - $title_key = "title"; + $title_key = 'title[0][value]'; $title_value = $this->randomName(8); $body_key = 'body[0][value]'; $body_value = $this->randomName(16); @@ -114,7 +114,7 @@ function testMultilingualNodeForm() { */ function testMultilingualDisplaySettings() { // Create "Basic page" content. - $title_key = "title"; + $title_key = 'title[0][value]'; $title_value = $this->randomName(8); $body_key = 'body[0][value]'; $body_value = $this->randomName(16); diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeFormButtonsTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeFormButtonsTest.php index 539d695..1aa7dcd 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeFormButtonsTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeFormButtonsTest.php @@ -47,7 +47,7 @@ function testNodeFormButtons() { // Save the node and assert it's published after clicking // 'Save and publish'. - $edit = array('title' => $this->randomString()); + $edit = array('title[0][value]' => $this->randomString()); $this->drupalPostForm('node/add/article', $edit, t('Save and publish')); // Get the node. @@ -83,7 +83,7 @@ function testNodeFormButtons() { $this->assertButtons(array(t('Save')), FALSE); // Create the node. - $edit = array('title' => $this->randomString()); + $edit = array('title[0][value]' => $this->randomString()); $this->drupalPostForm('node/add/article', $edit, t('Save')); $node_2 = node_load(2); $this->assertTrue($node_2->isPublished(), 'Node is published'); @@ -118,7 +118,7 @@ function testNodeFormButtons() { // Verify the node is unpublished by default for a normal user. $this->drupalLogout(); $this->drupalLogin($this->web_user); - $edit = array('title' => $this->randomString()); + $edit = array('title[0][value]' => $this->randomString()); $this->drupalPostForm('node/add/article', $edit, t('Save')); $node_3 = node_load(3); $this->assertFalse($node_3->isPublished(), 'Node is unpublished'); diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeLastChangedTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeLastChangedTest.php index 13d8ffd..bf23498 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeLastChangedTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeLastChangedTest.php @@ -19,7 +19,7 @@ class NodeLastChangedTest extends DrupalUnitTestBase { * * @var array */ - public static $modules = array('entity', 'user', 'node', 'field'); + public static $modules = array('entity', 'user', 'node', 'field', 'text', 'filter'); public static function getInfo() { return array( diff --git a/core/modules/node/lib/Drupal/node/Tests/NodePostSettingsTest.php b/core/modules/node/lib/Drupal/node/Tests/NodePostSettingsTest.php index d213a69..1759837 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodePostSettingsTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodePostSettingsTest.php @@ -39,12 +39,12 @@ function testPagePostInfo() { // Create a node. $edit = array(); - $edit['title'] = $this->randomName(8); + $edit['title[0][value]'] = $this->randomName(8); $edit['body[0][value]'] = $this->randomName(16); $this->drupalPostForm('node/add/page', $edit, t('Save')); // Check that the post information is displayed. - $node = $this->drupalGetNodeByTitle($edit["title"]); + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); $elements = $this->xpath('//*[contains(@class,:class)]', array(':class' => 'submitted')); $this->assertEqual(count($elements), 1, 'Post information is displayed.'); $node->delete(); @@ -56,7 +56,7 @@ function testPagePostInfo() { // Create a node. $edit = array(); - $edit['title'] = $this->randomName(8); + $edit['title[0][value]'] = $this->randomName(8); $edit['body[0][value]'] = $this->randomName(16); $this->drupalPostForm('node/add/page', $edit, t('Save')); diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTitleTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTitleTest.php index 40015ec..9b503ff 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeTitleTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeTitleTest.php @@ -60,7 +60,7 @@ function testNodeTitle() { $this->assertEqual(current($this->xpath($xpath)), $node->label(), 'Node breadcrumb is equal to node title.', 'Node'); // Test node title in comment preview. - $this->assertEqual(current($this->xpath('//article[@id=:id]/h2/a', array(':id' => 'node-' . $node->id()))), $node->label(), 'Node preview title is equal to node title.', 'Node'); + $this->assertEqual(current($this->xpath('//article[@id=:id]/h2/a/span', array(':id' => 'node-' . $node->id()))), $node->label(), 'Node preview title is equal to node title.', 'Node'); // Test node title is clickable on teaser list (/node). $this->drupalGet('node'); diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTitleXSSTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTitleXSSTest.php index 3ec53b1..4eb58b7 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeTitleXSSTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeTitleXSSTest.php @@ -29,7 +29,8 @@ function testNodeTitleXSS() { $xss = ''; $title = $xss . $this->randomName(); - $edit = array("title" => $title); + $edit = array(); + $edit['title[0][value]'] = $title; $this->drupalPostForm('node/add/page', $edit, t('Preview')); $this->assertNoRaw($xss, 'Harmful tags are escaped when previewing a node.'); @@ -39,7 +40,7 @@ function testNodeTitleXSS() { $this->drupalGet('node/' . $node->id()); // assertTitle() decodes HTML-entities inside the element. - $this->assertTitle($edit["title"] . ' | Drupal', 'Title is diplayed when viewing a node.'); + $this->assertTitle($title . ' | Drupal', 'Title is diplayed when viewing a node.'); $this->assertNoRaw($xss, 'Harmful tags are escaped when viewing a node.'); $this->drupalGet('node/' . $node->id() . '/edit'); diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php index 25cce23..d75da20 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php @@ -77,7 +77,7 @@ protected function getAdministratorPermissions() { * Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::getNewEntityValues(). */ protected function getNewEntityValues($langcode) { - return array('title' => $this->randomName()) + parent::getNewEntityValues($langcode); + return array('title' => array(array('value' => $this->randomName()))) + parent::getNewEntityValues($langcode); } /** @@ -86,7 +86,7 @@ protected function getNewEntityValues($langcode) { protected function createEntity($values, $langcode, $bundle_name = NULL) { $this->drupalLogin($this->editor); $edit = array( - 'title' => $values['title'], + 'title[0][value]' => $values['title'][0]['value'], "{$this->fieldName}[0][value]" => $values[$this->fieldName][0]['value'], 'langcode' => $langcode, ); @@ -262,7 +262,7 @@ protected function doTestTranslations($path, array $values) { $languages = language_list(); foreach ($this->langcodes as $langcode) { $this->drupalGet($path, array('language' => $languages[$langcode])); - $this->assertText($values[$langcode]['title'], format_string('The %langcode node translation is correctly displayed.', array('%langcode' => $langcode))); + $this->assertText($values[$langcode]['title'][0]['value'], format_string('The %langcode node translation is correctly displayed.', array('%langcode' => $langcode))); } } diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php index be9f1b8..dc655e7 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php @@ -101,11 +101,11 @@ function testNodeTypeInitialLanguageDefaults() { function testLanguageFieldVisibility() { // Creates a node to test Language field visibility feature. $edit = array( - 'title' => $this->randomName(8), + 'title[0][value]' => $this->randomName(8), 'body[0][value]' => $this->randomName(16), ); $this->drupalPostForm('node/add/article', $edit, t('Save')); - $node = $this->drupalGetNodeByTitle($edit['title']); + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); $this->assertTrue($node, 'Node found in database.'); // Loads node page and check if Language field is hidden by default. diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php index 5e18494..7b0a0a0 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php @@ -54,13 +54,13 @@ public function testValidation() { $violations = $node->validate(); $this->assertEqual(count($violations), 1, 'Violation found when title is too long.'); $this->assertEqual($violations[0]->getPropertyPath(), 'title.0.value'); - $this->assertEqual($violations[0]->getMessage(), t('This value is too long. It should have %limit characters or less.', array('%limit' => 255))); + $this->assertEqual($violations[0]->getMessage(), '<em class="placeholder">Title</em>: the text may not be longer than 255 characters.'); $node->set('title', NULL); $violations = $node->validate(); $this->assertEqual(count($violations), 1, 'Violation found when title is not set.'); $this->assertEqual($violations[0]->getPropertyPath(), 'title'); - $this->assertEqual($violations[0]->getMessage(), t('This value should not be null.')); + $this->assertEqual($violations[0]->getMessage(), 'This value should not be null.'); // Make the title valid again. $node->set('title', $this->randomString()); @@ -71,6 +71,6 @@ public function testValidation() { $violations = $node->validate(); $this->assertEqual(count($violations), 1, 'Violation found when changed date is before the last changed date.'); $this->assertEqual($violations[0]->getPropertyPath(), 'changed.0.value'); - $this->assertEqual($violations[0]->getMessage(), t('The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.')); + $this->assertEqual($violations[0]->getMessage(), 'The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.'); } } diff --git a/core/modules/node/lib/Drupal/node/Tests/PageEditTest.php b/core/modules/node/lib/Drupal/node/Tests/PageEditTest.php index 78bac8d..3e52eb0 100644 --- a/core/modules/node/lib/Drupal/node/Tests/PageEditTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/PageEditTest.php @@ -35,7 +35,7 @@ function setUp() { function testPageEdit() { $this->drupalLogin($this->web_user); - $title_key = 'title'; + $title_key = 'title[0][value]'; $body_key = 'body[0][value]'; // Create node to edit. $edit = array(); @@ -77,13 +77,13 @@ function testPageEdit() { // Edit the same node, creating a new revision. $this->drupalGet("node/" . $node->id() . "/edit"); $edit = array(); - $edit['title'] = $this->randomName(8); + $edit['title[0][value]'] = $this->randomName(8); $edit[$body_key] = $this->randomName(16); $edit['revision'] = TRUE; $this->drupalPostForm(NULL, $edit, t('Save and keep published')); // Ensure that the node revision has been created. - $revised_node = $this->drupalGetNodeByTitle($edit['title'], TRUE); + $revised_node = $this->drupalGetNodeByTitle($edit['title[0][value]'], TRUE); $this->assertNotIdentical($node->getRevisionId(), $revised_node->getRevisionId(), 'A new revision has been created.'); // Ensure that the node author is preserved when it was not changed in the // edit form. @@ -104,12 +104,12 @@ function testPageAuthoredBy() { // Create node to edit. $body_key = 'body[0][value]'; $edit = array(); - $edit['title'] = $this->randomName(8); + $edit['title[0][value]'] = $this->randomName(8); $edit[$body_key] = $this->randomName(16); $this->drupalPostForm('node/add/page', $edit, t('Save and publish')); // Check that the node was authored by the currently logged in user. - $node = $this->drupalGetNodeByTitle($edit['title']); + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); $this->assertIdentical($node->getAuthorId(), $this->admin_user->id(), 'Node authored by admin user.'); // Try to change the 'authored by' field to an invalid user name. diff --git a/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php b/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php index 8bd1081..9704459 100644 --- a/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php @@ -110,7 +110,7 @@ function setUp() { * Checks the node preview functionality. */ function testPagePreview() { - $title_key = "title"; + $title_key = 'title[0][value]'; $body_key = 'body[0][value]'; $term_key = $this->field_name; @@ -159,7 +159,7 @@ function testPagePreview() { $this->assertNoLink($newterm1); $this->assertNoLink($newterm2); - $this->drupalPostForm('node/add/page', $edit, t('Save')); + $this->drupalPostForm(NULL, $edit, t('Save')); // Check with one more new term, keeping old terms, removing the existing // one. @@ -171,17 +171,17 @@ function testPagePreview() { $this->assertRaw('>' . $newterm2 . '<', 'Second existing term displayed.'); $this->assertRaw('>' . $newterm3 . '<', 'Third new term displayed.'); $this->assertNoText($this->term->label()); - $this->assertNoLink($newterm1); - $this->assertNoLink($newterm2); + $this->assertLink($newterm1); + $this->assertLink($newterm2); $this->assertNoLink($newterm3); - $this->drupalPostForm('node/add/page', $edit, t('Save')); + $this->drupalPostForm(NULL, $edit, t('Save')); } /** * Checks the node preview functionality, when using revisions. */ function testPagePreviewWithRevisions() { - $title_key = 'title'; + $title_key = 'title[0][value]'; $body_key = 'body[0][value]'; $term_key = $this->field_name; // Force revision on "Basic page" content. diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 8da4271..a1bde76 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -19,6 +19,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Template\Attribute; use Drupal\entity\Entity\EntityDisplay; +use Drupal\entity\Entity\EntityFormDisplay; use Drupal\file\Entity\File; use Drupal\user\UserInterface; @@ -171,6 +172,9 @@ function node_theme() { 'render element' => 'form', 'template' => 'node-edit-form', ), + 'field__node__title' => array( + 'base hook' => 'field', + ), ); } @@ -191,14 +195,42 @@ function node_entity_bundle_info() { * Implements hook_entity_display_alter(). */ function node_entity_display_alter(EntityDisplay $display, $context) { - // Hide field labels in search index. - if ($context['entity_type'] == 'node' && $context['view_mode'] == 'search_index') { - foreach ($display->getComponents() as $name => $options) { - if (isset($options['label'])) { - $options['label'] = 'hidden'; - $display->setComponent($name, $options); + if ($context['entity_type'] == 'node') { + // Hide field labels in search index. + if ($context['view_mode'] == 'search_index') { + foreach ($display->getComponents() as $name => $options) { + if (isset($options['label'])) { + $options['label'] = 'hidden'; + $display->setComponent($name, $options); + } } } + // @todo Manage base field displays in the YAML: + // https://drupal.org/node/2144919. + $display->setComponent('title', array( + 'label' => 'hidden', + 'type' => 'text_default', + )); + } +} + +/** + * Implements hook_entity_form_display_alter(). + */ +function node_entity_form_display_alter(EntityFormDisplay $form_display, $context) { + if ($context['entity_type'] == 'node') { + // @todo Manage base field displays in the YAML: + // https://drupal.org/node/2144919. + $node_type = node_type_load($context['bundle']); + if ($node_type->has_title) { + // Title is also registered in node_field_extra_fields(). + $options = $form_display->getComponent('title') ?: array('weight' => -5); + $options['type'] = 'text_textfield'; + $form_display->setComponent('title', $options); + } + else { + $form_display->removeComponent('title'); + } } } @@ -648,7 +680,8 @@ function template_preprocess_node(&$variables) { $uri = $node->uri(); $variables['node_url'] = url($uri['path'], $uri['options']); - $variables['label'] = check_plain($node->label()); + $variables['label'] = $variables['elements']['title']; + unset($variables['elements']['title']); $variables['page'] = $variables['view_mode'] == 'full' && node_is_page($node); // Helpful $content variable for templates. @@ -707,6 +740,23 @@ function template_preprocess_node(&$variables) { } /** + * Returns HTML for the node title field. + * + * This is an override of theme_field() for the node title field. See that + * function for documentation about its details and overrides. + * + * @param array $variables + * An associative array. See theme_field() for details. + * + * @see theme_field() + * + * @ingroup themeable + */ +function theme_field__node__title($variables) { + return '<span' . $variables['attributes'] . '>' . drupal_render($variables['items']) . '</span>'; +} + +/** * Implements hook_permission(). */ function node_permission() { diff --git a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php index 8a1d9b2..dd476fe 100644 --- a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php +++ b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php @@ -199,7 +199,7 @@ function testNumberIntegerField() { // Create new content and check that prefix and suffix are shown. $rand_number = rand(); $edit = array( - 'title' => $this->randomName(), + 'title[0][value]' => $this->randomName(), 'field_' .$field_name . '[0][value]' => $rand_number, ); $this->drupalPostForm("node/add/$type", $edit, t('Save')); diff --git a/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php b/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php index 63ebf66..d4f7ec5 100644 --- a/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php +++ b/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php @@ -94,7 +94,7 @@ function testAliasTranslation() { $this->clickLink(t('Add')); $edit = array(); - $edit['title'] = $this->randomName(); + $edit['title[0][value]'] = $this->randomName(); $edit['body[0][value]'] = $this->randomName(); $french_alias = $this->randomName(); $edit['path[alias]'] = $french_alias; diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php index 284df1d..be5f604 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -2273,7 +2273,7 @@ protected function assertNoLinkByHref($href, $message = '', $group = 'Other') { */ protected function clickLink($label, $index = 0) { $url_before = $this->getUrl(); - $urls = $this->xpath('//a[normalize-space(text())=:label]', array(':label' => $label)); + $urls = $this->xpath('//a[normalize-space()=:label]', array(':label' => $label)); if (isset($urls[$index])) { $url_target = $this->getAbsoluteUrl($urls[$index]['href']); 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 78326e9..7530db1 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php @@ -60,14 +60,14 @@ function testEntityFormLanguage() { // Create a node with language Language::LANGCODE_NOT_SPECIFIED. $edit = array(); - $edit["title"] = $this->randomName(8); + $edit['title[0][value]'] = $this->randomName(8); $edit['body[0][value]'] = $this->randomName(16); $this->drupalGet('node/add/page'); $form_langcode = \Drupal::state()->get('entity_test.form_langcode') ?: FALSE; $this->drupalPostForm(NULL, $edit, t('Save')); - $node = $this->drupalGetNodeByTitle($edit["title"]); + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); $this->assertTrue($node->language()->id == $form_langcode, 'Form language is the same as the entity language.'); // Edit the node and test the form language. @@ -91,14 +91,14 @@ function testEntityFormLanguage() { // Create a node with language. $edit = array(); $langcode = $this->langcodes[0]; - $edit['title'] = $this->randomName(8); + $edit['title[0][value]'] = $this->randomName(8); $edit['body[0][value]'] = $this->randomName(16); $edit['langcode'] = $langcode; $this->drupalPostForm('node/add/page', $edit, t('Save')); - $this->assertRaw(t('Basic page %title has been created.', array('%title' => $edit["title"])), 'Basic page created.'); + $this->assertRaw(t('Basic page %title has been created.', array('%title' => $edit['title[0][value]'])), 'Basic page created.'); // Check to make sure the node was created. - $node = $this->drupalGetNodeByTitle($edit["title"]); + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); $this->assertTrue($node, 'Node found in database.'); // Make body translatable. diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/ContextPluginTest.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/ContextPluginTest.php index 262537b..6f3bd49 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Plugin/ContextPluginTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Plugin/ContextPluginTest.php @@ -17,7 +17,7 @@ */ class ContextPluginTest extends DrupalUnitTestBase { - public static $modules = array('system', 'user', 'node', 'field'); + public static $modules = array('system', 'user', 'node', 'field', 'filter', 'text'); public static function getInfo() { return array( diff --git a/core/modules/system/lib/Drupal/system/Tests/System/PageTitleTest.php b/core/modules/system/lib/Drupal/system/Tests/System/PageTitleTest.php index d08817d..bafa68d 100644 --- a/core/modules/system/lib/Drupal/system/Tests/System/PageTitleTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/System/PageTitleTest.php @@ -71,16 +71,16 @@ function testTitleTags() { $this->assertTrue(strpos(drupal_get_title(), '<em>') !== FALSE, 'Tags in title are not converted to entities when $output is PASS_THROUGH.'); // Generate node content. $edit = array( - 'title' => '!SimpleTest! ' . $title . $this->randomName(20), + 'title[0][value]' => '!SimpleTest! ' . $title . $this->randomName(20), 'body[0][value]' => '!SimpleTest! test body' . $this->randomName(200), ); // Create the node with HTML in the title. $this->drupalPostForm('node/add/page', $edit, t('Save')); - $node = $this->drupalGetNodeByTitle($edit["title"]); + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); $this->assertNotNull($node, 'Node created and found in database'); $this->drupalGet("node/" . $node->id()); - $this->assertText(check_plain($edit["title"]), 'Check to make sure tags in the node title are converted.'); + $this->assertText(check_plain($edit['title[0][value]']), 'Check to make sure tags in the node title are converted.'); } /** * Test if the title of the site is XSS proof. diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php index 8c72ac0..9852d72 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php @@ -37,14 +37,14 @@ function testTaxonomyLegacyNode() { // Posts an article with a taxonomy term and a date prior to 1970. $date = new DrupalDateTime('1969-01-01 00:00:00'); $edit = array(); - $edit['title'] = $this->randomName(); + $edit['title[0][value]'] = $this->randomName(); $edit['date[date]'] = $date->format('Y-m-d'); $edit['date[time]'] = $date->format('H:i:s'); $edit['body[0][value]'] = $this->randomName(); $edit['field_tags'] = $this->randomName(); $this->drupalPostForm('node/add/article', $edit, t('Save and publish')); // Checks that the node has been saved. - $node = $this->drupalGetNodeByTitle($edit['title']); + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); $this->assertEqual($node->getCreatedTime(), $date->getTimestamp(), 'Legacy node was saved with the right date.'); } } diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php index e89c531..875fc59 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php @@ -94,7 +94,7 @@ function testTaxonomyRss() { // Post an article. $edit = array(); - $edit["title"] = $this->randomName(); + $edit['title[0][value]'] = $this->randomName(); $edit[$this->field_name . '[]'] = $term1->id(); $this->drupalPostForm('node/add/article', $edit, t('Save')); diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php index c7abc5c..c1e9bb2 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php @@ -105,14 +105,14 @@ function testTaxonomyIndex() { // Post an article. $edit = array(); - $edit["title"] = $this->randomName(); + $edit['title[0][value]'] = $this->randomName(); $edit['body[0][value]'] = $this->randomName(); $edit["{$this->field_name_1}[]"] = $term_1->id(); $edit["{$this->field_name_2}[]"] = $term_1->id(); $this->drupalPostForm('node/add/article', $edit, t('Save')); // Check that the term is indexed, and only once. - $node = $this->drupalGetNodeByTitle($edit["title"]); + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array( ':nid' => $node->id(), ':tid' => $term_1->id(), diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php index dcae350..a8be8da 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php @@ -112,13 +112,13 @@ function testTaxonomyNode() { // Post an article. $edit = array(); - $edit['title'] = $this->randomName(); + $edit['title[0][value]'] = $this->randomName(); $edit['body[0][value]'] = $this->randomName(); $edit[$this->instance->getFieldName() . '[]'] = $term1->id(); $this->drupalPostForm('node/add/article', $edit, t('Save')); // Check that the term is displayed when the node is viewed. - $node = $this->drupalGetNodeByTitle($edit["title"]); + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); $this->drupalGet('node/' . $node->id()); $this->assertText($term1->label(), 'Term is displayed when viewing the node.'); @@ -163,7 +163,7 @@ function testNodeTermCreationAndDeletion() { ); $edit = array(); - $edit['title'] = $this->randomName(); + $edit['title[0][value]'] = $this->randomName(); $edit['body[0][value]'] = $this->randomName(); // Insert the terms in a comma separated list. Vocabulary 1 is a // free-tagging field created by the default profile. @@ -186,7 +186,7 @@ function testNodeTermCreationAndDeletion() { // Save, creating the terms. $this->drupalPostForm('node/add/article', $edit, t('Save')); - $this->assertRaw(t('@type %title has been created.', array('@type' => t('Article'), '%title' => $edit["title"])), 'The node was created successfully.'); + $this->assertRaw(t('@type %title has been created.', array('@type' => t('Article'), '%title' => $edit['title[0][value]'])), 'The node was created successfully.'); foreach ($terms as $term) { $this->assertText($term, 'The term was saved and appears on the node page.'); } @@ -207,7 +207,7 @@ function testNodeTermCreationAndDeletion() { $term_names = array($term_objects['term3']->label(), $term_objects['term4']->label()); // Get the node. - $node = $this->drupalGetNodeByTitle($edit["title"]); + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); $this->drupalGet('node/' . $node->id()); foreach ($term_names as $term_name) { @@ -526,7 +526,7 @@ function testReSavingTags() { // Create a term and a node using it. $term = $this->createTerm($this->vocabulary); $edit = array(); - $edit['title'] = $this->randomName(8); + $edit['title[0][value]'] = $this->randomName(8); $edit['body[0][value]'] = $this->randomName(16); $edit[$this->instance->getFieldName()] = $term->label(); $this->drupalPostForm('node/add/article', $edit, t('Save')); diff --git a/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php b/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php index 1f5ab23..f66f6d9 100644 --- a/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php +++ b/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php @@ -87,8 +87,8 @@ function testTelephoneField() { // Test basic entery of telephone field. $edit = array( - "title" => $this->randomName(), - "field_telephone[0][value]" => "123456789", + 'title[0][value]' => $this->randomName(), + 'field_telephone[0][value]' => "123456789", ); $this->drupalPostForm(NULL, $edit, t('Save')); @@ -96,8 +96,8 @@ function testTelephoneField() { // Add number with a space in it. Need to ensure it is stripped on output. $edit = array( - "title" => $this->randomName(), - "field_telephone[0][value]" => "1234 56789", + 'title[0][value]' => $this->randomName(), + 'field_telephone[0][value]' => "1234 56789", ); $this->drupalPostForm('node/add/article', $edit, t('Save')); 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 8a04604..a4dabc7 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php @@ -110,15 +110,15 @@ function testTaggedWith() { // Create three nodes, with different tags. $edit = array(); - $edit['title'] = $node_tag1_title = $this->randomName(); + $edit['title[0][value]'] = $node_tag1_title = $this->randomName(); $edit[$this->tag_field->name] = 'tag1'; $this->drupalPostForm($node_add_path, $edit, t('Save')); $edit = array(); - $edit['title'] = $node_tag1_tag2_title = $this->randomName(); + $edit['title[0][value]'] = $node_tag1_tag2_title = $this->randomName(); $edit[$this->tag_field->name] = 'tag1, tag2'; $this->drupalPostForm($node_add_path, $edit, t('Save')); $edit = array(); - $edit['title'] = $node_no_tags_title = $this->randomName(); + $edit['title[0][value]'] = $node_no_tags_title = $this->randomName(); $this->drupalPostForm($node_add_path, $edit, t('Save')); // Create a view that filters by taxonomy term "tag1". It should show only