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