Upgraded drupal core with security updates
[yaffs-website] / web / core / lib / Drupal / Core / Validation / ConstraintManager.php
1 <?php
2
3 namespace Drupal\Core\Validation;
4
5 use Drupal\Component\Plugin\Discovery\StaticDiscoveryDecorator;
6 use Drupal\Core\Cache\CacheBackendInterface;
7 use Drupal\Core\Extension\ModuleHandlerInterface;
8 use Drupal\Core\Plugin\DefaultPluginManager;
9 use Drupal\Core\StringTranslation\TranslatableMarkup;
10
11 /**
12  * Constraint plugin manager.
13  *
14  * Manages validation constraints based upon
15  * \Symfony\Component\Validator\Constraint, whereas Symfony constraints are
16  * added in manually during construction. Constraint options are passed on as
17  * plugin configuration during plugin instantiation.
18  *
19  * While core does not prefix constraint plugins, modules have to prefix them
20  * with the module name in order to avoid any naming conflicts; for example, a
21  * "profile" module would have to prefix any constraints with "Profile".
22  *
23  * Constraint plugins may specify data types to which support is limited via the
24  * 'type' key of plugin definitions. See
25  * \Drupal\Core\Validation\Annotation\Constraint for details.
26  *
27  * @see \Drupal\Core\Validation\Annotation\Constraint
28  */
29 class ConstraintManager extends DefaultPluginManager {
30
31   /**
32    * Overrides \Drupal\Component\Plugin\PluginManagerBase::__construct().
33    *
34    * @param \Traversable $namespaces
35    *   An object that implements \Traversable which contains the root paths
36    *   keyed by the corresponding namespace to look for plugin implementations.
37    * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
38    *   Cache backend instance to use.
39    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
40    *   The module handler to invoke the alter hook with.
41    */
42   public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
43     parent::__construct('Plugin/Validation/Constraint', $namespaces, $module_handler, NULL, 'Drupal\Core\Validation\Annotation\Constraint');
44     $this->alterInfo('validation_constraint');
45     $this->setCacheBackend($cache_backend, 'validation_constraint_plugins');
46   }
47
48   /**
49    * {@inheritdoc}
50    */
51   protected function getDiscovery() {
52     if (!isset($this->discovery)) {
53       $this->discovery = parent::getDiscovery();
54       $this->discovery = new StaticDiscoveryDecorator($this->discovery, [$this, 'registerDefinitions']);
55     }
56     return $this->discovery;
57   }
58
59
60   /**
61    * Creates a validation constraint.
62    *
63    * @param string $name
64    *   The name or plugin id of the constraint.
65    * @param mixed $options
66    *   The options to pass to the constraint class. Required and supported
67    *   options depend on the constraint class.
68    *
69    * @return \Symfony\Component\Validator\Constraint
70    *   A validation constraint plugin.
71    */
72   public function create($name, $options) {
73     if (!is_array($options)) {
74       // Plugins need an array as configuration, so make sure we have one.
75       // The constraint classes support passing the options as part of the
76       // 'value' key also.
77       $options = isset($options) ? ['value' => $options] : [];
78     }
79     return $this->createInstance($name, $options);
80   }
81
82   /**
83    * Callback for registering definitions for constraints shipped with Symfony.
84    *
85    * @see ConstraintManager::__construct()
86    */
87   public function registerDefinitions() {
88     $this->getDiscovery()->setDefinition('Callback', [
89       'label' => new TranslatableMarkup('Callback'),
90       'class' => '\Symfony\Component\Validator\Constraints\Callback',
91       'type' => FALSE,
92     ]);
93     $this->getDiscovery()->setDefinition('Blank', [
94       'label' => new TranslatableMarkup('Blank'),
95       'class' => '\Symfony\Component\Validator\Constraints\Blank',
96       'type' => FALSE,
97     ]);
98     $this->getDiscovery()->setDefinition('NotBlank', [
99       'label' => new TranslatableMarkup('Not blank'),
100       'class' => '\Symfony\Component\Validator\Constraints\NotBlank',
101       'type' => FALSE,
102     ]);
103     $this->getDiscovery()->setDefinition('Email', [
104       'label' => new TranslatableMarkup('Email'),
105       'class' => '\Drupal\Core\Validation\Plugin\Validation\Constraint\EmailConstraint',
106       'type' => ['string'],
107     ]);
108   }
109
110   /**
111    * {@inheritdoc}
112    */
113   public function processDefinition(&$definition, $plugin_id) {
114     // Make sure 'type' is set and either an array or FALSE.
115     if ($definition['type'] !== FALSE && !is_array($definition['type'])) {
116       $definition['type'] = [$definition['type']];
117     }
118   }
119
120   /**
121    * Returns a list of constraints that support the given type.
122    *
123    * @param string $type
124    *   The type to filter on.
125    *
126    * @return array
127    *   An array of constraint plugin definitions supporting the given type,
128    *   keyed by constraint name (plugin ID).
129    */
130   public function getDefinitionsByType($type) {
131     $definitions = [];
132     foreach ($this->getDefinitions() as $plugin_id => $definition) {
133       if ($definition['type'] === FALSE || in_array($type, $definition['type'])) {
134         $definitions[$plugin_id] = $definition;
135       }
136     }
137     return $definitions;
138   }
139
140 }