Commit 2a554518 authored by alexpott's avatar alexpott

Issue #2403817 by larowlan: Feed entity validation misses form validation logic

parent febf423d
......@@ -2,18 +2,18 @@
/**
* @file
* Contains \Drupal\user\Plugin\Validation\Constraint\UserUniqueValidator.
* Contains \Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator.
*/
namespace Drupal\user\Plugin\Validation\Constraint;
namespace Drupal\Core\Validation\Plugin\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
/**
* Validates the unique user property constraint, such as name and email.
* Validates that a field is unique for the given entity type.
*/
class UserUniqueValidator extends ConstraintValidator {
class UniqueFieldValueValidator extends ConstraintValidator {
/**
* {@inheritdoc}
......@@ -23,10 +23,14 @@ public function validate($items, Constraint $constraint) {
return;
}
$field_name = $items->getFieldDefinition()->getName();
/** @var \Drupal\Core\Entity\EntityInterface $entity */
$entity = $items->getEntity();
$entity_type_id = $entity->getEntityTypeId();
$id_key = $entity->getEntityType()->getKey('id');
$value_taken = (bool) \Drupal::entityQuery('user')
// The UID could be NULL, so we cast it to 0 in that case.
->condition('uid', (int) $items->getEntity()->id(), '<>')
$value_taken = (bool) \Drupal::entityQuery($entity_type_id)
// The id could be NULL, so we cast it to 0 in that case.
->condition($id_key, (int) $items->getEntity()->id(), '<>')
->condition($field_name, db_like($items->first()->value), 'LIKE')
->range(0, 1)
->count()
......
......@@ -150,7 +150,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
'type' => 'string_textfield',
'weight' => -5,
))
->setDisplayConfigurable('form', TRUE);
->setDisplayConfigurable('form', TRUE)
->addConstraint('FeedTitle', []);
$fields['langcode'] = BaseFieldDefinition::create('language')
->setLabel(t('Language code'))
......@@ -171,7 +172,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
'type' => 'uri',
'weight' => -3,
))
->setDisplayConfigurable('form', TRUE);
->setDisplayConfigurable('form', TRUE)
->addConstraint('FeedUrl', []);
$intervals = array(900, 1800, 3600, 7200, 10800, 21600, 32400, 43200, 64800, 86400, 172800, 259200, 604800, 1209600, 2419200);
$period = array_map(array(\Drupal::service('date.formatter'), 'formatInterval'), array_combine($intervals, $intervals));
......
......@@ -29,25 +29,6 @@ public function form(array $form, FormStateInterface $form_state) {
return $form;
}
/**
* {@inheritdoc}
*/
public function validate(array $form, FormStateInterface $form_state) {
$feed = $this->buildEntity($form, $form_state);
// Check for duplicate titles.
$feed_storage = $this->entityManager->getStorage('aggregator_feed');
$result = $feed_storage->getFeedDuplicates($feed);
foreach ($result as $item) {
if (strcasecmp($item->label(), $feed->label()) == 0) {
$form_state->setErrorByName('title', $this->t('A feed named %feed already exists. Enter a unique title.', array('%feed' => $feed->label())));
}
if (strcasecmp($item->getUrl(), $feed->getUrl()) == 0) {
$form_state->setErrorByName('url', $this->t('A feed with this URL %url already exists. Enter a unique URL.', array('%url' => $feed->getUrl())));
}
}
parent::validate($form, $form_state);
}
/**
* {@inheritdoc}
*/
......
<?php
/**
* @file
* Contains \Drupal\aggregator\Plugin\Validation\Constraint\FeedTitleConstraint.
*/
namespace Drupal\aggregator\Plugin\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
/**
* Supports validating feed titles.
*
* @Plugin(
* id = "FeedTitle",
* label = @Translation("Feed title", context = "Validation")
* )
*/
class FeedTitleConstraint extends Constraint {
public $message = 'A feed named %value already exists. Enter a unique title.';
/**
* {@inheritdoc}
*/
public function validatedBy() {
return '\Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator';
}
}
<?php
/**
* @file
* Contains \Drupal\aggregator\Plugin\Validation\Constraint\FeedUrlConstraint.
*/
namespace Drupal\aggregator\Plugin\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
/**
* Supports validating feed URLs.
*
* @Plugin(
* id = "FeedUrl",
* label = @Translation("Feed URL", context = "Validation")
* )
*/
class FeedUrlConstraint extends Constraint {
public $message = 'A feed with this URL %value already exists. Enter a unique URL.';
/**
* {@inheritdoc}
*/
public function validatedBy() {
return '\Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator';
}
}
......@@ -30,6 +30,16 @@ function testAddFeed() {
$this->assertText($feed->label(), 'Page title');
$this->assertRaw($feed->getWebsiteUrl());
// Try to add a duplicate.
$edit = [
'title[0][value]' => $feed->label(),
'url[0][value]' => $feed->getUrl(),
'refresh' => '900',
];
$this->drupalPostForm('aggregator/sources/add', $edit, t('Save'));
$this->assertRaw(t('A feed named %feed already exists. Enter a unique title.', array('%feed' => $feed->label())));
$this->assertRaw(t('A feed with this URL %url already exists. Enter a unique URL.', array('%url' => $feed->getUrl())));
// Delete feed.
$this->deleteFeed($feed);
}
......
<?php
/**
* @file
* Contains \Drupal\aggregator\Tests\FeedValidationTest.
*/
namespace Drupal\aggregator\Tests;
use Drupal\aggregator\Entity\Feed;
use Drupal\system\Tests\Entity\EntityUnitTestBase;
/**
* Tests feed validation constraints.
*
* @group aggregator
*/
class FeedValidationTest extends EntityUnitTestBase {
/**
* Modules to install.
*
* @var array
*/
public static $modules = array('aggregator', 'options');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('aggregator_feed');
}
/**
* Tests the feed validation constraints.
*/
public function testValidation() {
// Add feed.
$feed = Feed::create([
'title' => 'Feed 1',
'url' => 'http://drupal.org/planet/rss',
'refresh' => 900,
]);
$violations = $feed->validate();
$this->assertEqual(count($violations), 0);
$feed->save();
// Add another feed.
/* @var \Drupal\aggregator\FeedInterface $feed */
$feed = Feed::create([
'title' => 'Feed 1',
'url' => 'http://drupal.org/planet/rss',
'refresh' => 900,
]);
$violations = $feed->validate();
$this->assertEqual(count($violations), 2);
$this->assertEqual($violations[0]->getPropertyPath(), 'title');
$this->assertEqual($violations[0]->getMessage(), t('A feed named %value already exists. Enter a unique title.', [
'%value' => $feed->label(),
]));
$this->assertEqual($violations[1]->getPropertyPath(), 'url');
$this->assertEqual($violations[1]->getMessage(), t('A feed with this URL %value already exists. Enter a unique URL.', [
'%value' => $feed->getUrl(),
]));
}
}
......@@ -25,6 +25,6 @@ class UserMailUnique extends Constraint {
* {@inheritdoc}
*/
public function validatedBy() {
return '\Drupal\user\Plugin\Validation\Constraint\UserUniqueValidator';
return '\Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator';
}
}
......@@ -25,6 +25,6 @@ class UserNameUnique extends Constraint {
* {@inheritdoc}
*/
public function validatedBy() {
return '\Drupal\user\Plugin\Validation\Constraint\UserUniqueValidator';
return '\Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator';
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment