annotate core/lib/Drupal/Core/Validation/ConstraintManager.php @ 13:5fb285c0d0e3

Update Drupal core to 8.4.7 via Composer. Security update; I *think* we've been lucky to get away with this so far, as we don't support self-registration which seems to be used by the so-called "drupalgeddon 2" attack that 8.4.5 was vulnerable to.
author Chris Cannam
date Mon, 23 Apr 2018 09:33:26 +0100
parents 4c8ae668cc8c
children 129ea1e6d783
rev   line source
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 /**
Chris@0 61 * Creates a validation constraint.
Chris@0 62 *
Chris@0 63 * @param string $name
Chris@0 64 * The name or plugin id of the constraint.
Chris@0 65 * @param mixed $options
Chris@0 66 * The options to pass to the constraint class. Required and supported
Chris@0 67 * options depend on the constraint class.
Chris@0 68 *
Chris@0 69 * @return \Symfony\Component\Validator\Constraint
Chris@0 70 * A validation constraint plugin.
Chris@0 71 */
Chris@0 72 public function create($name, $options) {
Chris@0 73 if (!is_array($options)) {
Chris@0 74 // Plugins need an array as configuration, so make sure we have one.
Chris@0 75 // The constraint classes support passing the options as part of the
Chris@0 76 // 'value' key also.
Chris@0 77 $options = isset($options) ? ['value' => $options] : [];
Chris@0 78 }
Chris@0 79 return $this->createInstance($name, $options);
Chris@0 80 }
Chris@0 81
Chris@0 82 /**
Chris@0 83 * Callback for registering definitions for constraints shipped with Symfony.
Chris@0 84 *
Chris@0 85 * @see ConstraintManager::__construct()
Chris@0 86 */
Chris@0 87 public function registerDefinitions() {
Chris@0 88 $this->getDiscovery()->setDefinition('Callback', [
Chris@0 89 'label' => new TranslatableMarkup('Callback'),
Chris@0 90 'class' => '\Symfony\Component\Validator\Constraints\Callback',
Chris@0 91 'type' => FALSE,
Chris@0 92 ]);
Chris@0 93 $this->getDiscovery()->setDefinition('Blank', [
Chris@0 94 'label' => new TranslatableMarkup('Blank'),
Chris@0 95 'class' => '\Symfony\Component\Validator\Constraints\Blank',
Chris@0 96 'type' => FALSE,
Chris@0 97 ]);
Chris@0 98 $this->getDiscovery()->setDefinition('NotBlank', [
Chris@0 99 'label' => new TranslatableMarkup('Not blank'),
Chris@0 100 'class' => '\Symfony\Component\Validator\Constraints\NotBlank',
Chris@0 101 'type' => FALSE,
Chris@0 102 ]);
Chris@0 103 $this->getDiscovery()->setDefinition('Email', [
Chris@0 104 'label' => new TranslatableMarkup('Email'),
Chris@0 105 'class' => '\Drupal\Core\Validation\Plugin\Validation\Constraint\EmailConstraint',
Chris@0 106 'type' => ['string'],
Chris@0 107 ]);
Chris@0 108 }
Chris@0 109
Chris@0 110 /**
Chris@0 111 * {@inheritdoc}
Chris@0 112 */
Chris@0 113 public function processDefinition(&$definition, $plugin_id) {
Chris@0 114 // Make sure 'type' is set and either an array or FALSE.
Chris@0 115 if ($definition['type'] !== FALSE && !is_array($definition['type'])) {
Chris@0 116 $definition['type'] = [$definition['type']];
Chris@0 117 }
Chris@0 118 }
Chris@0 119
Chris@0 120 /**
Chris@0 121 * Returns a list of constraints that support the given type.
Chris@0 122 *
Chris@0 123 * @param string $type
Chris@0 124 * The type to filter on.
Chris@0 125 *
Chris@0 126 * @return array
Chris@0 127 * An array of constraint plugin definitions supporting the given type,
Chris@0 128 * keyed by constraint name (plugin ID).
Chris@0 129 */
Chris@0 130 public function getDefinitionsByType($type) {
Chris@0 131 $definitions = [];
Chris@0 132 foreach ($this->getDefinitions() as $plugin_id => $definition) {
Chris@0 133 if ($definition['type'] === FALSE || in_array($type, $definition['type'])) {
Chris@0 134 $definitions[$plugin_id] = $definition;
Chris@0 135 }
Chris@0 136 }
Chris@0 137 return $definitions;
Chris@0 138 }
Chris@0 139
Chris@0 140 }