annotate core/lib/Drupal/Core/Annotation/ContextDefinition.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Core\Annotation;
Chris@0 4
Chris@0 5 use Drupal\Component\Annotation\Plugin;
Chris@0 6 use Drupal\Core\StringTranslation\TranslatableMarkup;
Chris@0 7
Chris@0 8 /**
Chris@0 9 * @defgroup plugin_context Annotation for context definition
Chris@0 10 * @{
Chris@0 11 * Describes how to use ContextDefinition annotation.
Chris@0 12 *
Chris@0 13 * When providing plugin annotations, contexts can be defined to support UI
Chris@0 14 * interactions through providing limits, and mapping contexts to appropriate
Chris@0 15 * plugins. Context definitions can be provided as such:
Chris@0 16 * @code
Chris@18 17 * context_definitions = {
Chris@0 18 * "node" = @ContextDefinition("entity:node")
Chris@0 19 * }
Chris@0 20 * @endcode
Chris@0 21 *
Chris@0 22 * To add a label to a context definition use the "label" key:
Chris@0 23 * @code
Chris@18 24 * context_definitions = {
Chris@0 25 * "node" = @ContextDefinition("entity:node", label = @Translation("Node"))
Chris@0 26 * }
Chris@0 27 * @endcode
Chris@0 28 *
Chris@0 29 * Contexts are required unless otherwise specified. To make an optional
Chris@0 30 * context use the "required" key:
Chris@0 31 * @code
Chris@18 32 * context_definitions = {
Chris@0 33 * "node" = @ContextDefinition("entity:node", required = FALSE, label = @Translation("Node"))
Chris@0 34 * }
Chris@0 35 * @endcode
Chris@0 36 *
Chris@0 37 * To define multiple contexts, simply provide different key names in the
Chris@0 38 * context array:
Chris@0 39 * @code
Chris@18 40 * context_definitions = {
Chris@0 41 * "artist" = @ContextDefinition("entity:node", label = @Translation("Artist")),
Chris@0 42 * "album" = @ContextDefinition("entity:node", label = @Translation("Album"))
Chris@0 43 * }
Chris@0 44 * @endcode
Chris@0 45 *
Chris@0 46 * Specifying a default value for the context definition:
Chris@0 47 * @code
Chris@18 48 * context_definitions = {
Chris@0 49 * "message" = @ContextDefinition("string",
Chris@0 50 * label = @Translation("Message"),
Chris@0 51 * default_value = @Translation("Checkout complete! Thank you for your purchase.")
Chris@0 52 * )
Chris@0 53 * }
Chris@0 54 * @endcode
Chris@0 55 *
Chris@0 56 * @see annotation
Chris@0 57 *
Chris@0 58 * @}
Chris@0 59 */
Chris@0 60
Chris@0 61 /**
Chris@0 62 * Defines a context definition annotation object.
Chris@0 63 *
Chris@0 64 * Some plugins require various data contexts in order to function. This class
Chris@0 65 * supports that need by allowing the contexts to be easily defined within an
Chris@0 66 * annotation and return a ContextDefinitionInterface implementing class.
Chris@0 67 *
Chris@0 68 * @Annotation
Chris@0 69 *
Chris@0 70 * @ingroup plugin_context
Chris@0 71 */
Chris@0 72 class ContextDefinition extends Plugin {
Chris@0 73
Chris@0 74 /**
Chris@0 75 * The ContextDefinitionInterface object.
Chris@0 76 *
Chris@0 77 * @var \Drupal\Core\Plugin\Context\ContextDefinitionInterface
Chris@0 78 */
Chris@0 79 protected $definition;
Chris@0 80
Chris@0 81 /**
Chris@0 82 * Constructs a new context definition object.
Chris@0 83 *
Chris@0 84 * @param array $values
Chris@0 85 * An associative array with the following keys:
Chris@0 86 * - value: The required data type.
Chris@0 87 * - label: (optional) The UI label of this context definition.
Chris@0 88 * - required: (optional) Whether the context definition is required.
Chris@0 89 * - multiple: (optional) Whether the context definition is multivalue.
Chris@0 90 * - description: (optional) The UI description of this context definition.
Chris@0 91 * - default_value: (optional) The default value in case the underlying
Chris@0 92 * value is not set.
Chris@0 93 * - class: (optional) A custom ContextDefinitionInterface class.
Chris@0 94 *
Chris@0 95 * @throws \Exception
Chris@0 96 * Thrown when the class key is specified with a non
Chris@0 97 * ContextDefinitionInterface implementing class.
Chris@0 98 */
Chris@0 99 public function __construct(array $values) {
Chris@0 100 $values += [
Chris@0 101 'required' => TRUE,
Chris@0 102 'multiple' => FALSE,
Chris@0 103 'default_value' => NULL,
Chris@0 104 ];
Chris@0 105 // Annotation classes extract data from passed annotation classes directly
Chris@0 106 // used in the classes they pass to.
Chris@0 107 foreach (['label', 'description'] as $key) {
Chris@0 108 // @todo Remove this workaround in https://www.drupal.org/node/2362727.
Chris@0 109 if (isset($values[$key]) && $values[$key] instanceof TranslatableMarkup) {
Chris@0 110 $values[$key] = (string) $values[$key]->get();
Chris@0 111 }
Chris@0 112 else {
Chris@0 113 $values[$key] = NULL;
Chris@0 114 }
Chris@0 115 }
Chris@0 116 if (isset($values['class']) && !in_array('Drupal\Core\Plugin\Context\ContextDefinitionInterface', class_implements($values['class']))) {
Chris@0 117 throw new \Exception('ContextDefinition class must implement \Drupal\Core\Plugin\Context\ContextDefinitionInterface.');
Chris@0 118 }
Chris@17 119
Chris@17 120 $class = $this->getDefinitionClass($values);
Chris@0 121 $this->definition = new $class($values['value'], $values['label'], $values['required'], $values['multiple'], $values['description'], $values['default_value']);
Chris@18 122
Chris@18 123 if (isset($values['constraints'])) {
Chris@18 124 foreach ($values['constraints'] as $constraint_name => $options) {
Chris@18 125 $this->definition->addConstraint($constraint_name, $options);
Chris@18 126 }
Chris@18 127 }
Chris@0 128 }
Chris@0 129
Chris@0 130 /**
Chris@17 131 * Determines the context definition class to use.
Chris@17 132 *
Chris@17 133 * If the annotation specifies a specific context definition class, we use
Chris@17 134 * that. Otherwise, we use \Drupal\Core\Plugin\Context\EntityContextDefinition
Chris@17 135 * if the data type starts with 'entity:', since it contains specialized logic
Chris@17 136 * specific to entities. Otherwise, we fall back to the generic
Chris@17 137 * \Drupal\Core\Plugin\Context\ContextDefinition class.
Chris@17 138 *
Chris@17 139 * @param array $values
Chris@17 140 * The annotation values.
Chris@17 141 *
Chris@17 142 * @return string
Chris@17 143 * The fully-qualified name of the context definition class.
Chris@17 144 */
Chris@17 145 protected function getDefinitionClass(array $values) {
Chris@17 146 if (isset($values['class'])) {
Chris@17 147 return $values['class'];
Chris@17 148 }
Chris@17 149 if (strpos($values['value'], 'entity:') === 0) {
Chris@17 150 return 'Drupal\Core\Plugin\Context\EntityContextDefinition';
Chris@17 151 }
Chris@17 152 return 'Drupal\Core\Plugin\Context\ContextDefinition';
Chris@17 153 }
Chris@17 154
Chris@17 155 /**
Chris@0 156 * Returns the value of an annotation.
Chris@0 157 *
Chris@0 158 * @return \Drupal\Core\Plugin\Context\ContextDefinitionInterface
Chris@0 159 */
Chris@0 160 public function get() {
Chris@0 161 return $this->definition;
Chris@0 162 }
Chris@0 163
Chris@0 164 }