diff --git a/core/lib/Drupal/Core/Entity/EntityStorageControllerBase.php b/core/lib/Drupal/Core/Entity/EntityStorageControllerBase.php index 988afa7..3b772b7 100644 --- a/core/lib/Drupal/Core/Entity/EntityStorageControllerBase.php +++ b/core/lib/Drupal/Core/Entity/EntityStorageControllerBase.php @@ -190,7 +190,8 @@ public function invokeFieldItemPrepareCache(EntityInterface $entity) { // of making LegacyConfigFieldItem implement PrepareCacheInterface. // @todo Remove once all core field types have been converted (see // http://drupal.org/node/2014671). - || (is_subclass_of($type_definition['class'], '\Drupal\field\Plugin\field\field_type\LegacyConfigFieldItem') && function_exists($type_definition['provider'] . '_field_load'))) { + || (is_subclass_of($type_definition['class'], '\Drupal\field\Plugin\field\field_type\LegacyConfigFieldItem') + && isset($type_definition['provider']) && function_exists($type_definition['provider'] . '_field_load'))) { // Call the prepareCache() method directly on each item // individually. diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/EmailItem.php b/core/lib/Drupal/Core/Entity/Plugin/DataType/EmailItem.php index b147976..254505c 100644 --- a/core/lib/Drupal/Core/Entity/Plugin/DataType/EmailItem.php +++ b/core/lib/Drupal/Core/Entity/Plugin/DataType/EmailItem.php @@ -52,6 +52,7 @@ public function getPropertyDefinitions() { * {@inheritdoc} */ public function isEmpty() { - return !isset($this->values['value']) || $this->values['value'] === ''; + $value = isset($this->values['value']) ? $this->values['value'] : $this->get('value')->getValue(); + return !isset($value) || $value === ''; } } diff --git a/core/modules/comment/lib/Drupal/comment/CommentStorageController.php b/core/modules/comment/lib/Drupal/comment/CommentStorageController.php index 8cd1a53..ff56396 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentStorageController.php +++ b/core/modules/comment/lib/Drupal/comment/CommentStorageController.php @@ -137,6 +137,9 @@ public function baseFieldDefinitions() { 'label' => t('Subject'), 'description' => t('The comment title or subject.'), 'type' => 'string_field', + 'property_constraints' => array( + 'value' => array('Length' => array('max' => 64)), + ), ); $properties['uid'] = array( 'label' => t('User ID'), @@ -152,21 +155,35 @@ public function baseFieldDefinitions() { 'description' => t("The comment author's name."), 'type' => 'string_field', 'settings' => array('default_value' => ''), + 'property_constraints' => array( + 'value' => array( + 'Length' => array('max' => 60), + 'CommentName' => array(), + ), + ), ); $properties['mail'] = array( 'label' => t('e-mail'), 'description' => t("The comment author's e-mail address."), - 'type' => 'string_field', + 'type' => 'email_field', ); $properties['homepage'] = array( 'label' => t('Homepage'), 'description' => t("The comment author's home page address."), - 'type' => 'string_field', + 'type' => 'uri_field', + // URIs are not length limited by RFC 2616, but we can only store 255 + // characters in our DB schema. + 'property_constraints' => array( + 'value' => array('Length' => array('max' => 255)), + ), ); $properties['hostname'] = array( 'label' => t('Hostname'), 'description' => t("The comment author's hostname."), 'type' => 'string_field', + 'property_constraints' => array( + 'value' => array('Length' => array('max' => 255)), + ), ); $properties['created'] = array( 'label' => t('Created'), @@ -187,6 +204,9 @@ public function baseFieldDefinitions() { 'label' => t('Thread place'), 'description' => t("The alphadecimal representation of the comment's place in a thread, consisting of a base 36 string prefixed by an integer indicating its length."), 'type' => 'string_field', + 'property_constraints' => array( + 'value' => array('Length' => array('max' => 255)), + ), ); $properties['node_type'] = array( // @todo: The bundle property should be stored so it's queryable. diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/Validation/Constraint/CommentNameConstraint.php b/core/modules/comment/lib/Drupal/comment/Plugin/Validation/Constraint/CommentNameConstraint.php new file mode 100644 index 0000000..9540b67 --- /dev/null +++ b/core/modules/comment/lib/Drupal/comment/Plugin/Validation/Constraint/CommentNameConstraint.php @@ -0,0 +1,25 @@ +context->getMetadata()->getTypedData()->getParent()->getParent(); + + if ($comment->uid->value === 0) { + $query = db_select('users', 'u'); + $query->addField('u', 'uid', 'uid'); + $taken = $query + ->condition('name', db_like($value), 'LIKE') + ->countQuery() + ->execute() + ->fetchField(); + if ($taken) { + $this->context->addViolation($constraint->message); + } + } + } +} diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentValidationTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentValidationTest.php new file mode 100644 index 0000000..9475a85 --- /dev/null +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentValidationTest.php @@ -0,0 +1,122 @@ + 'Comment Validation', + 'description' => 'Tests the comment validation constraints.', + 'group' => 'Comment', + ); + } + + public function setUp() { + parent::setUp(); + $this->installSchema('node', 'node'); + $this->installSchema('node', 'node_field_data'); + $this->installSchema('node', 'node_field_revision'); + $this->installSchema('comment', 'node_comment_statistics'); + $this->installSchema('user', 'users'); + $this->installSchema('user', 'users_roles'); + $this->installSchema('system', 'sequences'); + user_install(); + } + + /** + * Tests the comment validation constraints. + */ + public function testValidation() { + $node = entity_create('node', array( + 'type' => 'page', + 'title' => 'test', + )); + $node->save(); + + $comment = entity_create('comment', array('nid' => $node->id())); + $violations = $comment->validate(); + $this->assertEqual(count($violations), 0, 'No violations when validating a default comment.'); + + $comment->set('subject', $this->randomString(65)); + $this->assertLengthViolation($comment, 'subject', 64); + // Make the subject valid. + $comment->set('subject', $this->randomString()); + + $comment->set('name', $this->randomString(61)); + $this->assertLengthViolation($comment, 'name', 60); + // Validate a name collision between an anonymous comment author name and an + // existing user account name. + $user = entity_create('user', array('name' => 'test')); + $user->save(); + $comment->set('name', 'test'); + $violations = $comment->validate(); + $this->assertEqual(count($violations), 1, "Violation found on author name collision"); + $this->assertEqual($violations[0]->getPropertyPath(), "name.0.value"); + $this->assertEqual($violations[0]->getMessage(), t('The name you used belongs to a registered user.')); + + // Make the name valid. + $comment->set('name', $this->randomString()); + + $comment->set('mail', 'invalid'); + $violations = $comment->validate(); + $this->assertEqual(count($violations), 1, 'Violation found when email is invalid'); + $this->assertEqual($violations[0]->getPropertyPath(), 'mail.0.value'); + $this->assertEqual($violations[0]->getMessage(), t('This value is not a valid email address.')); + $comment->set('mail', NULL); + + $comment->set('homepage', 'http://example.com/' . $this->randomName(237)); + $this->assertLengthViolation($comment, 'homepage', 255); + + $comment->set('homepage', 'invalid'); + $violations = $comment->validate(); + $this->assertEqual(count($violations), 1, 'Violation found when homepage is invalid'); + $this->assertEqual($violations[0]->getPropertyPath(), 'homepage.0.value'); + $this->assertEqual($violations[0]->getMessage(), t('This value should be of the correct primitive type.')); + $comment->set('homepage', NULL); + + $comment->set('hostname', $this->randomString(256)); + $this->assertLengthViolation($comment, 'hostname', 255); + $comment->set('hostname', NULL); + + $comment->set('thread', $this->randomString(256)); + $this->assertLengthViolation($comment, 'thread', 255); + + // @todo Add a test for the allowed values of CommentNewValue once + // https://drupal.org/node/1758622 is committed. + } + + /** + * Verifies that a length violation exists for the given field. + * + * @param \Drupal\Core\Entity\ContentEntityInterface\CommentInterface $comment + * The comment object to validate. + * @param string $field_name + * The field that violates the maximum length. + * @param int $length + * Number of characters that was exceeded. + */ + protected function assertLengthViolation($comment, $field_name, $length) { + $violations = $comment->validate(); + $this->assertEqual(count($violations), 1, "Violation found when $field_name is too long."); + $this->assertEqual($violations[0]->getPropertyPath(), "$field_name.0.value"); + $this->assertEqual($violations[0]->getMessage(), t('This value is too long. It should have %limit characters or less.', array('%limit' => $length))); + } +} diff --git a/core/modules/node/lib/Drupal/node/NodeStorageController.php b/core/modules/node/lib/Drupal/node/NodeStorageController.php index d105abf..1a874fe 100644 --- a/core/modules/node/lib/Drupal/node/NodeStorageController.php +++ b/core/modules/node/lib/Drupal/node/NodeStorageController.php @@ -167,7 +167,10 @@ public function baseFieldDefinitions() { 'label' => t('User ID'), 'description' => t('The user ID of the node author.'), 'type' => 'entity_reference_field', - 'settings' => array('target_type' => 'user'), + 'settings' => array( + 'target_type' => 'user', + 'default_value' => 0, + ), ); $properties['status'] = array( 'label' => t('Publishing status'),