Newer
Older
Dries Buytaert
committed
<?php
/**
* @file
* Contains \Drupal\Core\Validation\ConstraintManager.
*/
namespace Drupal\Core\Validation;
use Drupal\Component\Plugin\Discovery\StaticDiscoveryDecorator;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\DefaultPluginManager;
Alex Bronstein
committed
use Drupal\Core\StringTranslation\TranslatableMarkup;
Dries Buytaert
committed
/**
* Constraint plugin manager.
*
* Manages validation constraints based upon
* \Symfony\Component\Validator\Constraint, whereas Symfony constraints are
* added in manually during construction. Constraint options are passed on as
* plugin configuration during plugin instantiation.
*
* While core does not prefix constraint plugins, modules have to prefix them
Jennifer Hodgdon
committed
* with the module name in order to avoid any naming conflicts; for example, a
* "profile" module would have to prefix any constraints with "Profile".
Dries Buytaert
committed
*
* Constraint plugins may specify data types to which support is limited via the
* 'type' key of plugin definitions. See
* \Drupal\Core\Validation\Annotation\Constraint for details.
*
* @see \Drupal\Core\Validation\Annotation\Constraint
Dries Buytaert
committed
*/
class ConstraintManager extends DefaultPluginManager {
Dries Buytaert
committed
/**
* Overrides \Drupal\Component\Plugin\PluginManagerBase::__construct().
* @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 to invoke the alter hook with.
Dries Buytaert
committed
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/Validation/Constraint', $namespaces, $module_handler, NULL, 'Drupal\Core\Validation\Annotation\Constraint');
$this->alterInfo('validation_constraint');
$this->setCacheBackend($cache_backend, 'validation_constraint_plugins');
Dries Buytaert
committed
}
/**
* {@inheritdoc}
*/
protected function getDiscovery() {
if (!isset($this->discovery)) {
$this->discovery = parent::getDiscovery();
$this->discovery = new StaticDiscoveryDecorator($this->discovery, [$this, 'registerDefinitions']);
}
return $this->discovery;
}
Alex Pott
committed
/**
* Creates a validation constraint.
*
* @param string $name
* The name or plugin id of the constraint.
* @param mixed $options
* The options to pass to the constraint class. Required and supported
* options depend on the constraint class.
*
* @return \Symfony\Component\Validator\Constraint
* A validation constraint plugin.
*/
public function create($name, $options) {
if (!is_array($options)) {
// Plugins need an array as configuration, so make sure we have one.
// The constraint classes support passing the options as part of the
// 'value' key also.
Alex Pott
committed
$options = isset($options) ? array('value' => $options) : array();
Alex Pott
committed
}
return $this->createInstance($name, $options);
}
Dries Buytaert
committed
/**
* Callback for registering definitions for constraints shipped with Symfony.
*
* @see ConstraintManager::__construct()
*/
public function registerDefinitions() {
$this->getDiscovery()->setDefinition('Callback', array(
Alex Bronstein
committed
'label' => new TranslatableMarkup('Callback'),
Alex Pott
committed
'class' => '\Symfony\Component\Validator\Constraints\Callback',
Dries Buytaert
committed
'type' => FALSE,
));
$this->getDiscovery()->setDefinition('Blank', array(
Alex Bronstein
committed
'label' => new TranslatableMarkup('Blank'),
Dries Buytaert
committed
'class' => '\Symfony\Component\Validator\Constraints\Blank',
'type' => FALSE,
));
$this->getDiscovery()->setDefinition('NotBlank', array(
Alex Bronstein
committed
'label' => new TranslatableMarkup('Not blank'),
Dries Buytaert
committed
'class' => '\Symfony\Component\Validator\Constraints\NotBlank',
'type' => FALSE,
));
$this->getDiscovery()->setDefinition('Email', array(
Alex Bronstein
committed
'label' => new TranslatableMarkup('Email'),
catch
committed
'class' => '\Drupal\Core\Validation\Plugin\Validation\Constraint\EmailConstraint',
Dries Buytaert
committed
'type' => array('string'),
));
}
/**
* {@inheritdoc}
Dries Buytaert
committed
*/
public function processDefinition(&$definition, $plugin_id) {
// Make sure 'type' is set and either an array or FALSE.
if ($definition['type'] !== FALSE && !is_array($definition['type'])) {
Dries Buytaert
committed
$definition['type'] = array($definition['type']);
}
}
/**
* Returns a list of constraints that support the given type.
*
* @param string $type
* The type to filter on.
*
* @return array
* An array of constraint plugin definitions supporting the given type,
* keyed by constraint name (plugin ID).
*/
public function getDefinitionsByType($type) {
$definitions = array();
foreach ($this->getDefinitions() as $plugin_id => $definition) {
if ($definition['type'] === FALSE || in_array($type, $definition['type'])) {
$definitions[$plugin_id] = $definition;
}
}
return $definitions;
}
}