diff --git a/core/modules/node/lib/Drupal/node/NodeStorageController.php b/core/modules/node/lib/Drupal/node/NodeStorageController.php index 693b828d9576b201d60b22ced8a0b918f1f44287..d105abf8e0e233471438567bc82b81d7caea6cf1 100644 --- a/core/modules/node/lib/Drupal/node/NodeStorageController.php +++ b/core/modules/node/lib/Drupal/node/NodeStorageController.php @@ -155,6 +155,13 @@ public function baseFieldDefinitions() { 'label' => t('Title'), 'description' => t('The title of this node, always treated as non-markup plain text.'), 'type' => 'string_field', + 'required' => TRUE, + 'settings' => array( + 'default_value' => '', + ), + 'property_constraints' => array( + 'value' => array('Length' => array('max' => 255)), + ), ); $properties['uid'] = array( 'label' => t('User ID'), @@ -176,6 +183,9 @@ public function baseFieldDefinitions() { 'label' => t('Changed'), 'description' => t('The time that the node was last edited.'), 'type' => 'integer_field', + 'property_constraints' => array( + 'value' => array('NodeChanged' => array()), + ), ); $properties['comment'] = array( 'label' => t('Comment'), diff --git a/core/modules/node/lib/Drupal/node/Plugin/Validation/Constraint/NodeChangedConstraint.php b/core/modules/node/lib/Drupal/node/Plugin/Validation/Constraint/NodeChangedConstraint.php new file mode 100644 index 0000000000000000000000000000000000000000..1ca461f9aa33ae49415551fc3db9c2f7eb472459 --- /dev/null +++ b/core/modules/node/lib/Drupal/node/Plugin/Validation/Constraint/NodeChangedConstraint.php @@ -0,0 +1,25 @@ +<?php + +/** + * @file + * Contains \Drupal\node\Plugin\Validation\Constraint\NodeChangedConstraint. + */ + +namespace Drupal\node\Plugin\Validation\Constraint; + +use Drupal\Component\Annotation\Plugin; +use Drupal\Core\Annotation\Translation; +use Symfony\Component\Validator\Constraint; + +/** + * Validation constraint for the node changed timestamp. + * + * @Plugin( + * id = "NodeChanged", + * label = @Translation("Node changed", context = "Validation") + * ) + */ +class NodeChangedConstraint extends Constraint { + + public $message = '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/Plugin/Validation/Constraint/NodeChangedConstraintValidator.php b/core/modules/node/lib/Drupal/node/Plugin/Validation/Constraint/NodeChangedConstraintValidator.php new file mode 100644 index 0000000000000000000000000000000000000000..0479e3864072a92be6180bbbaedc386ca848f589 --- /dev/null +++ b/core/modules/node/lib/Drupal/node/Plugin/Validation/Constraint/NodeChangedConstraintValidator.php @@ -0,0 +1,33 @@ +<?php + +/** + * @file + * Contains \Drupal\node\Plugin\Validation\Constraint\NodeChangedConstraintValidator. + */ + +namespace Drupal\node\Plugin\Validation\Constraint; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; + +/** + * Validates the NodeChanged constraint. + */ +class NodeChangedConstraintValidator extends ConstraintValidator { + + /** + * {@inheritdoc} + */ + public function validate($value, Constraint $constraint) { + if (isset($value)) { + // We are on the field item level, so we need to go two levels up for the + // node object. + $node = $this->context->getMetadata()->getTypedData()->getParent()->getParent(); + $id = $node->id(); + $language = $node->language(); + if ($id && (node_last_changed($id, $language->id) > $value)) { + $this->context->addViolation($constraint->message); + } + } + } +} diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php new file mode 100644 index 0000000000000000000000000000000000000000..dcba3e21391d67dada7b77c6e65034dedb236e92 --- /dev/null +++ b/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php @@ -0,0 +1,77 @@ +<?php + +/** + * @file + * Contains \Drupal\node\Tests\NodeValidationTest. + */ + +namespace Drupal\node\Tests; + +use Drupal\simpletest\DrupalUnitTestBase; + +/** + * Tests node validation constraints. + */ +class NodeValidationTest extends DrupalUnitTestBase { + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = array('node', 'entity', 'field', 'text', 'field_sql_storage'); + + public static function getInfo() { + return array( + 'name' => 'Node Validation', + 'description' => 'Tests the node validation constraints.', + 'group' => 'Node', + ); + } + + /** + * Set the default field storage backend for fields created during tests. + */ + public function setUp() { + parent::setUp(); + $this->installSchema('node', 'node'); + $this->installSchema('node', 'node_field_data'); + $this->installSchema('node', 'node_field_revision'); + + // Create a node type for testing. + $type = entity_create('node_type', array('type' => 'page', 'name' => 'page')); + $type->save(); + } + + /** + * Tests the node validation constraints. + */ + public function testValidation() { + $node = entity_create('node', array('type' => 'page', 'title' => 'test')); + $violations = $node->validate(); + $this->assertEqual(count($violations), 0, 'No violations when validating a default node.'); + + $node->set('title', $this->randomString(256)); + $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))); + + $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.')); + + // Make the title valid again. + $node->set('title', $this->randomString()); + // Save the node so that it gets an ID and a changed date. + $node->save(); + // Set the changed date to something in the far past. + $node->set('changed', 433918800); + $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.')); + } +}