summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathaniel Catchpole2013-12-03 11:53:16 (GMT)
committerNathaniel Catchpole2013-12-03 11:53:16 (GMT)
commit15fded0c845f90c7d588f1c53003fdead7f0ce69 (patch)
tree96e702c611f23beb50b5065ee689d51f3c58a505
parentb20755f4c882dcdb2d7fb6e02cc2af38bc0aa98e (diff)
Issue #1988612 by effulgentsia, yched, Wim Leers, Berdir, Pancho: Apply formatters and widgets to rendered entity base fields, starting with node.title.
-rw-r--r--core/includes/entity.inc16
-rw-r--r--core/lib/Drupal/Core/Entity/EntityFormController.php9
-rw-r--r--core/lib/Drupal/Core/Entity/EntityViewBuilder.php15
-rw-r--r--core/lib/Drupal/Core/Field/WidgetBase.php31
-rw-r--r--core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/AllowedValuesConstraintValidator.php3
-rw-r--r--core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorTestBase.php2
-rw-r--r--core/modules/book/lib/Drupal/book/Tests/BookTest.php4
-rw-r--r--core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php2
-rw-r--r--core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php6
-rw-r--r--core/modules/edit/edit.services.yml2
-rw-r--r--core/modules/edit/js/editors/plainTextEditor.js8
-rw-r--r--core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php15
-rw-r--r--core/modules/edit/lib/Drupal/edit/EditController.php5
-rw-r--r--core/modules/edit/lib/Drupal/edit/Form/EditFieldForm.php20
-rw-r--r--core/modules/edit/tests/Drupal/edit/Tests/Access/EditEntityFieldAccessCheckTest.php103
-rw-r--r--core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php5
-rw-r--r--core/modules/entity/lib/Drupal/entity/Entity/EntityFormDisplay.php5
-rw-r--r--core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php71
-rw-r--r--core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php2
-rw-r--r--core/modules/field/field.attach.inc218
-rw-r--r--core/modules/field/field.deprecated.inc31
-rw-r--r--core/modules/field/field.module16
-rw-r--r--core/modules/field/lib/Drupal/field/Tests/reEnableModuleFieldTest.php4
-rw-r--r--core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php2
-rw-r--r--core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php6
-rw-r--r--core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php6
-rw-r--r--core/modules/filter/lib/Drupal/filter/Tests/FilterAdminTest.php6
-rw-r--r--core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php18
-rw-r--r--core/modules/filter/lib/Drupal/filter/Tests/FilterHooksTest.php9
-rw-r--r--core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php2
-rw-r--r--core/modules/forum/lib/Drupal/forum/Tests/ForumIndexTest.php2
-rw-r--r--core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php4
-rw-r--r--core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php13
-rw-r--r--core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php2
-rw-r--r--core/modules/menu/lib/Drupal/menu/Tests/MenuNodeTest.php2
-rw-r--r--core/modules/node/lib/Drupal/node/Entity/Node.php8
-rw-r--r--core/modules/node/lib/Drupal/node/NodeFormController.php12
-rw-r--r--core/modules/node/lib/Drupal/node/NodeTitleItemList.php34
-rw-r--r--core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php2
-rw-r--r--core/modules/node/lib/Drupal/node/Tests/NodeAccessBaseTableTest.php6
-rw-r--r--core/modules/node/lib/Drupal/node/Tests/NodeCreationTest.php12
-rw-r--r--core/modules/node/lib/Drupal/node/Tests/NodeEntityViewModeAlterTest.php4
-rw-r--r--core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php4
-rw-r--r--core/modules/node/lib/Drupal/node/Tests/NodeFormButtonsTest.php6
-rw-r--r--core/modules/node/lib/Drupal/node/Tests/NodeLastChangedTest.php2
-rw-r--r--core/modules/node/lib/Drupal/node/Tests/NodePostSettingsTest.php6
-rw-r--r--core/modules/node/lib/Drupal/node/Tests/NodeTitleTest.php2
-rw-r--r--core/modules/node/lib/Drupal/node/Tests/NodeTitleXSSTest.php5
-rw-r--r--core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php6
-rw-r--r--core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php4
-rw-r--r--core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php6
-rw-r--r--core/modules/node/lib/Drupal/node/Tests/PageEditTest.php10
-rw-r--r--core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php12
-rw-r--r--core/modules/node/node.module64
-rw-r--r--core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php2
-rw-r--r--core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php2
-rw-r--r--core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php2
-rw-r--r--core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php10
-rw-r--r--core/modules/system/lib/Drupal/system/Tests/Plugin/ContextPluginTest.php2
-rw-r--r--core/modules/system/lib/Drupal/system/Tests/System/PageTitleTest.php6
-rw-r--r--core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php4
-rw-r--r--core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php2
-rw-r--r--core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php4
-rw-r--r--core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php12
-rw-r--r--core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php8
-rw-r--r--core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php6
66 files changed, 460 insertions, 470 deletions
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 @@ class EntityFormController extends FormBase implements EntityFormControllerInter
$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 @@ class EntityViewBuilder implements EntityControllerInterface, EntityViewBuilderI
// 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 @@ abstract class WidgetBase extends PluginSettingsBase implements WidgetInterface
$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 @@ abstract class WidgetBase extends PluginSettingsBase implements WidgetInterface
// 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 @@ abstract class WidgetBase extends PluginSettingsBase implements WidgetInterface
// @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 @@ EOF;
// 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 @@ class BookTest extends WebTestBase {
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 @@ class BookTest extends WebTestBase {
}
// 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 @@ class CommentLanguageTest extends WebTestBase {
// 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 @@ class DbLogTest extends WebTestBase {
// 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 @@ class DbLogTest extends WebTestBase {
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 @@ class DbLogTest extends WebTestBase {
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\Routing\Route;
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 @@ class EditEntityFieldAccessCheck implements StaticAccessCheckInterface, EditEnti
// 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 @@ class EditController extends ContainerAware implements ContainerInjectionInterfa
}
// 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 @@ class EditController extends ContainerAware implements ContainerInjectionInterfa
$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 @@ class EditFieldForm implements FormInterface, ContainerInjectionInterface {
$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 @@ class EditFieldForm implements FormInterface, ContainerInjectionInterface {
*/
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 @@ class EditEntityFieldAccessCheckTest extends UnitTestCase {
->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 @@ class EditEntityFieldAccessCheckTest extends UnitTestCase {
* @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 @@ class EditEntityFieldAccessCheckTest extends UnitTestCase {
$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 @@ class EditEntityFieldAccessCheckTest extends UnitTestCase {
$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 @@ class EditEntityFieldAccessCheckTest extends UnitTestCase {
$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 @@ class EditEntityFieldAccessCheckTest extends UnitTestCase {
$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 @@ class EditEntityFieldAccessCheckTest extends UnitTestCase {
$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 @@ class EntityDisplay extends EntityDisplayBase implements EntityDisplayInterface
}
// 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 @@ class EntityFormDisplay extends EntityDisplayBase implements EntityFormDisplayIn
}
// 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 @@ abstract class EntityDisplayBase extends ConfigEntityBase implements EntityDispl
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 @@ abstract class EntityDisplayBase extends ConfigEntityBase implements EntityDispl
* {@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 @@ abstract class EntityDisplayBase extends ConfigEntityBase implements EntityDispl
return NULL;
}
}
-
- if (isset($this->content[$name])) {
+ elseif (isset($this->content[$name])) {
return $this->content[$name];
}
}
@@ -231,18 +255,18 @@ abstract class EntityDisplayBase extends ConfigEntityBase implements EntityDispl
$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 @@ abstract class EntityDisplayBase extends ConfigEntityBase implements EntityDispl
* {@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 @@ abstract class EntityDisplayBase extends ConfigEntityBase implements EntityDispl
}
else {
unset($this->content[$name]);
- unset($this->plugins[$name]);
}
+ unset($this->plugins[$name]);
+
return $this;
}
@@ -290,4 +317,18 @@ abstract class EntityDisplayBase extends ConfigEntityBase implements EntityDispl
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 @@ class EntityReferenceAutoCreateTest extends WebTestBase {
$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 @@ use Drupal\entity\Entity\EntityFormDisplay;
* @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 @@ use Drupal\entity\Entity\EntityFormDisplay;
* 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 @@ class reEnableModuleFieldTest extends WebTestBase {
// 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('<a href="tel:123456789">');
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 @@ abstract class FileFieldTestBase extends WebTestBase {
*/
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 @@ class FileFieldValidateTest extends FileFieldTestBase {
$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 @@ class FileFieldValidateTest extends FileFieldTestBase {
$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 @@ class FileFieldWidgetTest extends FileFieldTestBase {
$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 @@ class FileFieldWidgetTest extends FileFieldTestBase {
// 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 @@ class FilterAdminTest extends WebTestBase {
$text = $body . '<random>' . $extra_text . '</random>';
$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 @@ class FilterFormatAccessTest extends WebTestBase {
// 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 @@ class FilterFormatAccessTest extends WebTestBase {
// 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 @@ class FilterFormatAccessTest extends WebTestBase {
// 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 @@ class FilterFormatAccessTest extends WebTestBase {
$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 @@ class FilterHooksTest extends WebTestBase {
// 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 @@ class ForumBlockTest extends WebTestBase {
$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 @@ class ForumIndexTest extends WebTestBase {
// 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 @@ class ForumNodeAccessTest extends WebTestBase {
// 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 @@ class ForumNodeAccessTest extends WebTestBase {
// 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 caa03e1..70f411e 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 @@ class ForumTest extends WebTestBase {
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 @@ class ForumTest extends WebTestBase {
$body = $this->randomName(200);
$edit = array(
- 'title' => $title,
+ 'title[0][value]' => $title,
'body[0][value]' => $body,
);
$tid = $forum['tid'];
@@ -572,13 +575,13 @@ class ForumTest extends WebTestBase {
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 @@ class ForumTest extends WebTestBase {
// 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 @@ abstract class ImageFieldTestBase extends WebTestBase {
*/
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 @@ class MenuNodeTest extends WebTestBase {
// 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 @@ class Node extends ContentEntityBase implements NodeInterface {
$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 @@ class NodeFormController extends ContentEntityFormController {
'#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 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\node\NodeTitleItemList.
+ */
+
+namespace Drupal\node;
+
+use Drupal\Core\Field\FieldDefinition;
+use Drupal\Core\Field\FieldItemList;
+
+/**
+ * @todo This class is a temporary hack for allowing the label of the node title
+ * field to vary by node type. Remove it when https://drupal.org/node/2114707
+ * is solved.
+ */
+class NodeTitleItemList extends FieldItemList {
+
+ /**
+ * {@inheritdoc}
+ *
+ * The typehint for $definition is a class rather than an interface, because
+ * there is no interface for setFieldLabel().
+ */
+ public function __construct(FieldDefinition $definition, $name, NodeInterface $node) {
+ $node_type = node_type_load($node->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 @@ class MultiStepNodeFormBasicOptionsTest extends NodeTestBase {
->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 @@ class NodeAccessBaseTableTest extends NodeTestBase {
$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 @@ class NodeAccessBaseTableTest extends NodeTestBase {
}
$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 @@ class NodeCreationTest extends NodeTestBase {
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 @@ class NodeCreationTest extends NodeTestBase {
// 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 @@ class NodeCreationTest extends NodeTestBase {
$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 @@ class NodeEntityViewModeAlterTest extends NodeTestBase {
// 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 @@ class NodeFieldMultilingualTestCase extends WebTestBase {
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 @@ class NodeFieldMultilingualTestCase extends WebTestBase {
*/
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 @@ class NodeFormButtonsTest extends NodeTestBase {
// 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 @@ class NodeFormButtonsTest extends NodeTestBase {
$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 @@ class NodeFormButtonsTest extends NodeTestBase {
// 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 @@ class NodePostSettingsTest extends NodeTestBase {
// 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 @@ class NodePostSettingsTest extends NodeTestBase {
// 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 @@ class NodeTitleTest extends NodeTestBase {
$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 @@ class NodeTitleXSSTest extends NodeTestBase {
$xss = '<script>alert("xss")</script>';
$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 @@ class NodeTitleXSSTest extends NodeTestBase {
$this->drupalGet('node/' . $node->id());
// assertTitle() decodes HTML-entities inside the <title> 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 @@ class NodeTranslationUITest extends ContentTranslationUITest {
* 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 @@ class NodeTranslationUITest extends ContentTranslationUITest {
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 @@ class NodeTranslationUITest extends ContentTranslationUITest {
$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 @@ class NodeTypeInitialLanguageTest extends NodeTestBase {
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 @@ class NodeValidationTest extends EntityUnitTestBase {
$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 @@ class NodeValidationTest extends EntityUnitTestBase {
$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 @@ class PageEditTest extends NodeTestBase {
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 @@ class PageEditTest extends NodeTestBase {
// 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 @@ class PageEditTest extends NodeTestBase {
// 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 @@ class PagePreviewTest extends NodeTestBase {
* 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 @@ class PagePreviewTest extends NodeTestBase {
$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 @@ class PagePreviewTest extends NodeTestBase {
$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\node\NodeTypeInterface;
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 @@ class NumberFieldTest extends WebTestBase {
// 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 @@ class PathLanguageTest extends PathTestBase {
$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 @@ abstract class WebTestBase extends TestBase {
*/
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 @@ class EntityTranslationFormTest extends WebTestBase {
// 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 @@ class EntityTranslationFormTest extends WebTestBase {
// 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 @@ use Drupal\Component\Plugin\Exception\ContextException;
*/
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 @@ class PageTitleTest extends WebTestBase {
$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 @@ class LegacyTest extends TaxonomyTestBase {
// 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 @@ class RssTest extends TaxonomyTestBase {
// 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 @@ class TermIndexTest extends TaxonomyTestBase {
// 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 c6b21e4..5aec19f 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 @@ class TermTest extends TaxonomyTestBase {
// 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 @@ class TermTest extends TaxonomyTestBase {
);
$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 @@ class TermTest extends TaxonomyTestBase {
// 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 @@ class TermTest extends TaxonomyTestBase {
$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) {
@@ -531,7 +531,7 @@ class TermTest extends TaxonomyTestBase {
// 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 @@ class TelephoneFieldTest extends WebTestBase {
// 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 @@ class TelephoneFieldTest extends WebTestBase {
// 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 @@ class TaggedWithTest extends WizardTestBase {
// 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