diff --git a/core/core.services.yml b/core/core.services.yml index a98b28b..c4c7593 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -489,7 +489,7 @@ services: arguments: [replica] typed_data_manager: class: Drupal\Core\TypedData\TypedDataManager - parent: default_plugin_manager + arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@class_resolver'] calls: - [setValidationConstraintManager, ['@validation.constraint']] tags: diff --git a/core/lib/Drupal/Core/TypedData/TypedDataManager.php b/core/lib/Drupal/Core/TypedData/TypedDataManager.php index d42a3d2..955be72 100644 --- a/core/lib/Drupal/Core/TypedData/TypedDataManager.php +++ b/core/lib/Drupal/Core/TypedData/TypedDataManager.php @@ -10,10 +10,12 @@ use Drupal\Component\Plugin\Exception\PluginException; use Drupal\Component\Utility\String; use Drupal\Core\Cache\CacheBackendInterface; +use Drupal\Core\DependencyInjection\ClassResolverInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Plugin\DefaultPluginManager; use Drupal\Core\TypedData\Validation\MetadataFactory; use Drupal\Core\Validation\ConstraintManager; +use Drupal\Core\Validation\ConstraintValidatorFactory; use Drupal\Core\Validation\DrupalTranslator; use Symfony\Component\Validator\Validation; use Symfony\Component\Validator\Validator\ValidatorInterface; @@ -44,20 +46,30 @@ class TypedDataManager extends DefaultPluginManager { */ protected $prototypes = array(); - /** - * Constructs a new TypedDataManager. - * - * @param \Traversable $namespaces - * An object that implements \Traversable which contains the root paths - * keyed by the corresponding namespace to look for plugin implementations. - * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend - * Cache backend instance to use. - * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler - * The module handler. - */ - public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) { + /** + * The class resolver. + * + * @var \Drupal\Core\DependencyInjection\ClassResolverInterface + */ + protected $classResolver; + + /** + * Constructs a new TypedDataManager. + * + * @param \Traversable $namespaces + * An object that implements \Traversable which contains the root paths + * keyed by the corresponding namespace to look for plugin implementations. + * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend + * Cache backend instance to use. + * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler + * The module handler. + * @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver + * The class resolver. + */ + public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, ClassResolverInterface $class_resolver) { $this->alterInfo('data_type_info'); $this->setCacheBackend($cache_backend, 'typed_data_types_plugins'); + $this->classResolver = $class_resolver; parent::__construct('Plugin/DataType', $namespaces, $module_handler, NULL, 'Drupal\Core\TypedData\Annotation\DataType'); } @@ -322,6 +334,7 @@ public function getValidator() { $this->validator = Validation::createValidatorBuilder() ->setMetadataFactory(new MetadataFactory()) ->setTranslator(new DrupalTranslator()) + ->setConstraintValidatorFactory(new ConstraintValidatorFactory($this->classResolver)) ->setApiVersion(Validation::API_VERSION_2_4) ->getValidator(); } diff --git a/core/lib/Drupal/Core/Validation/ConstraintValidatorFactory.php b/core/lib/Drupal/Core/Validation/ConstraintValidatorFactory.php new file mode 100644 index 0000000..b9d9f94 --- /dev/null +++ b/core/lib/Drupal/Core/Validation/ConstraintValidatorFactory.php @@ -0,0 +1,41 @@ +classResolver = $class_resolver; + } + + /** + * {@inheritdoc} + */ + public function getInstance(Constraint $constraint) { + $class_name = $constraint->validatedBy(); + + if (!isset($this->validators[$class_name])) { + $this->validators[$class_name] = $this->classResolver->getInstanceFromDefinition($class_name); + } + + return $this->validators[$class_name]; + } + +} diff --git a/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraintValidator.php b/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraintValidator.php index ad316e5..f6397e0 100644 --- a/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraintValidator.php +++ b/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraintValidator.php @@ -7,6 +7,9 @@ namespace Drupal\comment\Plugin\Validation\Constraint; +use Drupal\Core\DependencyInjection\ContainerInjectionInterface; +use Drupal\user\UserStorageInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\comment\CommentInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; @@ -14,7 +17,31 @@ /** * Validates the CommentName constraint. */ -class CommentNameConstraintValidator extends ConstraintValidator { +class CommentNameConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface { + + /** + * User storage handler. + * + * @var \Drupal\user\UserStorageInterface + */ + protected $userStorage; + + /** + * Constructs a new CommentNameConstraintValidator. + * + * @param \Drupal\user\UserStorageInterface $user_storage + * The user storage handler. + */ + public function __construct(UserStorageInterface $user_storage) { + $this->userStorage = $user_storage; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static($container->get('entity.manager')->getStorage('user')); + } /** * {@inheritdoc} @@ -37,8 +64,7 @@ public function validate($items, Constraint $constraint) { // Do not allow unauthenticated comment authors to use a name that is // taken by a registered user. if (isset($author_name) && $author_name !== '' && $comment->getOwnerId() === 0) { - // @todo Properly inject dependency https://drupal.org/node/2197029 - $users = \Drupal::entityManager()->getStorage('user')->loadByProperties(array('name' => $author_name)); + $users = $this->userStorage->loadByProperties(array('name' => $author_name)); if (!empty($users)) { $this->context->addViolation($constraint->messageNameTaken, array('%name' => $author_name)); } diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php index 7f50f89..e65f78c 100644 --- a/core/modules/user/src/Entity/User.php +++ b/core/modules/user/src/Entity/User.php @@ -512,8 +512,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['signature'] = BaseFieldDefinition::create('string') ->setLabel(t('Signature')) ->setDescription(t('The signature of this user.')) - ->setTranslatable(TRUE) - ->setConstraints(array('UserSignature' => array())); + ->setTranslatable(TRUE); $fields['signature_format'] = BaseFieldDefinition::create('string') ->setLabel(t('Signature format')) ->setDescription(t('The signature format of this user.')); diff --git a/core/modules/user/src/Plugin/Validation/Constraint/UserSignatureConstraint.php b/core/modules/user/src/Plugin/Validation/Constraint/UserSignatureConstraint.php deleted file mode 100644 index 7fe663b..0000000 --- a/core/modules/user/src/Plugin/Validation/Constraint/UserSignatureConstraint.php +++ /dev/null @@ -1,23 +0,0 @@ -getFieldDefinition()->getSetting('max_length'); - - if (Unicode::strlen($items->value) > $max_length) { - $this->context->addViolation($constraint->tooLongMessage, array('%max' => $max_length)); - return; - } - } - } -} diff --git a/core/modules/user/src/Tests/UserRegistrationTest.php b/core/modules/user/src/Tests/UserRegistrationTest.php index 853891a..5808349 100644 --- a/core/modules/user/src/Tests/UserRegistrationTest.php +++ b/core/modules/user/src/Tests/UserRegistrationTest.php @@ -138,13 +138,13 @@ function testRegistrationEmailDuplicates() { // Attempt to create a new account using an existing email address. $this->drupalPostForm('user/register', $edit, t('Create new account')); - $this->assertText(t('The email address @email is already registered.', array('@email' => $duplicate_user->getEmail())), 'Supplying an exact duplicate email address displays an error message'); + $this->assertText(t('The email address %email is already taken.', array('%email' => $duplicate_user->getEmail())), 'Supplying an exact duplicate email address displays an error message'); // Attempt to bypass duplicate email registration validation by adding spaces. $edit['mail'] = ' ' . $duplicate_user->getEmail() . ' '; $this->drupalPostForm('user/register', $edit, t('Create new account')); - $this->assertText(t('The email address @email is already registered.', array('@email' => $duplicate_user->getEmail())), 'Supplying a duplicate email address with added whitespace displays an error message'); + $this->assertText(t('The email address %email is already taken.', array('%email' => $duplicate_user->getEmail())), 'Supplying a duplicate email address with added whitespace displays an error message'); } function testRegistrationDefaultValues() { diff --git a/core/modules/user/src/Tests/UserValidationTest.php b/core/modules/user/src/Tests/UserValidationTest.php index 47dd1c2..f5ae202 100644 --- a/core/modules/user/src/Tests/UserValidationTest.php +++ b/core/modules/user/src/Tests/UserValidationTest.php @@ -129,15 +129,8 @@ function testValidation() { $this->assertEqual($violations[0]->getMessage(), t('The email address %mail is already taken.', array('%mail' => 'existing@example.com'))); $user->set('mail', NULL); - $max_signature_length = $user->get('signature')->getFieldDefinition()->getSetting('max_length'); - $user->set('signature', $this->randomString(256)); - $violations = $user->validate(); - $this->assertEqual(count($violations), 2, 'Violation found when signature is too long.'); - $this->assertEqual($violations[0]->getPropertyPath(), 'signature'); - $this->assertEqual($violations[0]->getMessage(), t('The signature is too long: it must be %max characters or less.', array('%max' => $max_signature_length))); - $this->assertEqual($violations[1]->getPropertyPath(), 'signature.0.value'); - $this->assertEqual($violations[1]->getMessage(), t('%name: may not be longer than @max characters.', array('@max' => $max_signature_length, '%name' => $user->get('signature')->getFieldDefinition()->getLabel()))); + $this->assertLengthViolation($user, 'signature', 255); $user->set('signature', NULL); $user->set('timezone', $this->randomString(33));