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 @@ ...@@ -2,18 +2,18 @@
/** /**
* @file * @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\Constraint;
use Symfony\Component\Validator\ConstraintValidator; 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} * {@inheritdoc}
...@@ -23,10 +23,14 @@ public function validate($items, Constraint $constraint) { ...@@ -23,10 +23,14 @@ public function validate($items, Constraint $constraint) {
return; return;
} }
$field_name = $items->getFieldDefinition()->getName(); $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') $value_taken = (bool) \Drupal::entityQuery($entity_type_id)
// The UID could be NULL, so we cast it to 0 in that case. // The id could be NULL, so we cast it to 0 in that case.
->condition('uid', (int) $items->getEntity()->id(), '<>') ->condition($id_key, (int) $items->getEntity()->id(), '<>')
->condition($field_name, db_like($items->first()->value), 'LIKE') ->condition($field_name, db_like($items->first()->value), 'LIKE')
->range(0, 1) ->range(0, 1)
->count() ->count()
......
...@@ -150,7 +150,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ...@@ -150,7 +150,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
'type' => 'string_textfield', 'type' => 'string_textfield',
'weight' => -5, 'weight' => -5,
)) ))
->setDisplayConfigurable('form', TRUE); ->setDisplayConfigurable('form', TRUE)
->addConstraint('FeedTitle', []);
$fields['langcode'] = BaseFieldDefinition::create('language') $fields['langcode'] = BaseFieldDefinition::create('language')
->setLabel(t('Language code')) ->setLabel(t('Language code'))
...@@ -171,7 +172,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ...@@ -171,7 +172,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
'type' => 'uri', 'type' => 'uri',
'weight' => -3, '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); $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)); $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) { ...@@ -29,25 +29,6 @@ public function form(array $form, FormStateInterface $form_state) {
return $form; 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} * {@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() { ...@@ -30,6 +30,16 @@ function testAddFeed() {
$this->assertText($feed->label(), 'Page title'); $this->assertText($feed->label(), 'Page title');
$this->assertRaw($feed->getWebsiteUrl()); $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. // Delete feed.
$this->deleteFeed($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 { ...@@ -25,6 +25,6 @@ class UserMailUnique extends Constraint {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function validatedBy() { 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 { ...@@ -25,6 +25,6 @@ class UserNameUnique extends Constraint {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function validatedBy() { 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