Issue #2002158 by klausi, andypost, effulgentsia, vlad.dancer: Convert form validation of comments to entity validation.

8.0.x
Nathaniel Catchpole 2014-02-18 11:00:49 +00:00
parent a840af8381
commit 0f9e59fdba
4 changed files with 221 additions and 9 deletions

View File

@ -229,7 +229,8 @@ class Comment extends ContentEntityBase implements CommentInterface {
$fields['subject'] = FieldDefinition::create('string')
->setLabel(t('Subject'))
->setDescription(t('The comment title or subject.'));
->setDescription(t('The comment title or subject.'))
->setSetting('max_length', 64);
$fields['uid'] = FieldDefinition::create('entity_reference')
->setLabel(t('User ID'))
@ -242,19 +243,27 @@ class Comment extends ContentEntityBase implements CommentInterface {
$fields['name'] = FieldDefinition::create('string')
->setLabel(t('Name'))
->setDescription(t("The comment author's name."))
->setSetting('default_value', '');
->setSettings(array(
'default_value' => '',
'max_length' => 60,
))
->setConstraints(array('CommentName' => array()));
$fields['mail'] = FieldDefinition::create('email')
->setLabel(t('Email'))
->setDescription(t("The comment author's e-mail address."));
$fields['homepage'] = FieldDefinition::create('string')
$fields['homepage'] = FieldDefinition::create('uri')
->setLabel(t('Homepage'))
->setDescription(t("The comment author's home page address."));
->setDescription(t("The comment author's home page address."))
// URIs are not length limited by RFC 2616, but we can only store 255
// characters in our comment DB schema.
->setSetting('max_length', 255);
$fields['hostname'] = FieldDefinition::create('string')
->setLabel(t('Hostname'))
->setDescription(t("The comment author's hostname."));
->setDescription(t("The comment author's hostname."))
->setSetting('max_length', 128);
// @todo Convert to a "created" field in https://drupal.org/node/2145103.
$fields['created'] = FieldDefinition::create('integer')
@ -273,16 +282,18 @@ class Comment extends ContentEntityBase implements CommentInterface {
$fields['thread'] = FieldDefinition::create('string')
->setLabel(t('Thread place'))
->setDescription(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."));
->setDescription(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."))
->setSetting('max_length', 255);
$fields['entity_type'] = FieldDefinition::create('string')
->setLabel(t('Entity type'))
->setDescription(t('The entity type to which this comment is attached.'));
$fields['field_id'] = FieldDefinition::create('entity_reference')
// @todo Convert to the entity_reference field in
// https://drupal.org/node/2149859.
$fields['field_id'] = FieldDefinition::create('string')
->setLabel(t('Field ID'))
->setDescription(t('The comment field id.'))
->setSetting('target_type', 'field_entity');
->setDescription(t('The comment field id.'));
$fields['field_name'] = FieldDefinition::create('string')
->setLabel(t('Comment field name'))

View File

@ -0,0 +1,24 @@
<?php
/**
* @file
* Contains \Drupal\comment\Plugin\Validation\Constraint\CommentNameConstraint.
*/
namespace Drupal\comment\Plugin\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
/**
* Supports validating comment author names.
*
* @Plugin(
* id = "CommentName",
* label = @Translation("Comment author name", context = "Validation")
* )
*/
class CommentNameConstraint extends Constraint {
public $message = '%name belongs to a registered user.';
}

View File

@ -0,0 +1,36 @@
<?php
/**
* @file
* Contains \Drupal\comment\Plugin\Validation\Constraint\CommentNameConstraintValidator.
*/
namespace Drupal\comment\Plugin\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
/**
* Validates the CommentName constraint.
*/
class CommentNameConstraintValidator extends ConstraintValidator {
/**
* {@inheritdoc}
*/
public function validate($field_item, Constraint $constraint) {
$author_name = $field_item->value;
if (isset($author_name) && $author_name !== '') {
// Do not allow unauthenticated comment authors to use a name that is
// taken by a registered user.
if ($field_item->getEntity()->getOwnerId() === 0) {
// @todo Properly inject dependency https://drupal.org/node/2197029
$users = \Drupal::entityManager()->getStorageController('user')->loadByProperties(array('name' => $author_name));
if (!empty($users)) {
$this->context->addViolation($constraint->message, array('%name' => $author_name));
}
}
}
}
}

View File

@ -0,0 +1,141 @@
<?php
/**
* @file
* Contains \Drupal\comment\Tests\CommentValidationTest.
*/
namespace Drupal\comment\Tests;
use Drupal\comment\CommentInterface;
use Drupal\system\Tests\Entity\EntityUnitTestBase;
/**
* Tests comment validation constraints.
*/
class CommentValidationTest extends EntityUnitTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('comment', 'node');
/**
* {@inheritdoc}
*/
public static function getInfo() {
return array(
'name' => 'Comment Validation',
'description' => 'Tests the comment validation constraints.',
'group' => 'Comment',
);
}
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
$this->installSchema('node', array('node', 'node_field_data', 'node_field_revision', 'node_revision'));
}
/**
* Tests the comment validation constraints.
*/
public function testValidation() {
// Add comment field to content.
$this->entityManager->getStorageController('field_entity')->create(array(
'entity_type' => 'node',
'name' => 'comment',
'type' => 'comment',
))->save();
// Add comment field instance to page content.
$this->entityManager->getStorageController('field_instance')->create(array(
'field_name' => 'comment',
'entity_type' => 'node',
'bundle' => 'page',
'label' => 'Comment settings',
))->save();
$node = $this->entityManager->getStorageController('node')->create(array(
'type' => 'page',
'title' => 'test',
));
$node->save();
$comment = $this->entityManager->getStorageController('comment')->create(array(
'entity_id' => $node->id(),
'entity_type' => 'node',
'field_name' => 'comment',
));
$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");
$this->assertEqual($violations[0]->getMessage(), t('%name belongs to a registered user.', array('%name' => 'test')));
// Make the name valid.
$comment->set('name', 'valid unused name');
$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');
// @todo This message should be improved in https://drupal.org/node/2012690
$this->assertEqual($violations[0]->getMessage(), t('This value should be of the correct primitive type.'));
$comment->set('homepage', NULL);
$comment->set('hostname', $this->randomString(129));
$this->assertLengthViolation($comment, 'hostname', 128);
$comment->set('hostname', NULL);
$comment->set('thread', $this->randomString(256));
$this->assertLengthViolation($comment, 'thread', 255);
}
/**
* Verifies that a length violation exists for the given field.
*
* @param \Drupal\comment\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(CommentInterface $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)));
}
}