summaryrefslogtreecommitdiffstats
path: root/core/lib/Drupal/Core/Annotation/ContextDefinition.php
blob: 043975295348b6e20592361d52c54fea3f3524dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<?php

namespace Drupal\Core\Annotation;

use Drupal\Component\Annotation\Plugin;
use Drupal\Core\StringTranslation\TranslatableMarkup;

/**
 * @defgroup plugin_context Annotation for context definition
 * @{
 * Describes how to use ContextDefinition annotation.
 *
 * When providing plugin annotations, contexts can be defined to support UI
 * interactions through providing limits, and mapping contexts to appropriate
 * plugins. Context definitions can be provided as such:
 * @code
 *   context = {
 *     "node" = @ContextDefinition("entity:node")
 *   }
 * @endcode
 *
 * To add a label to a context definition use the "label" key:
 * @code
 *   context = {
 *     "node" = @ContextDefinition("entity:node", label = @Translation("Node"))
 *   }
 * @endcode
 *
 * Contexts are required unless otherwise specified. To make an optional
 * context use the "required" key:
 * @code
 *   context = {
 *     "node" = @ContextDefinition("entity:node", required = FALSE, label = @Translation("Node"))
 *   }
 * @endcode
 *
 * To define multiple contexts, simply provide different key names in the
 * context array:
 * @code
 *   context = {
 *     "artist" = @ContextDefinition("entity:node", label = @Translation("Artist")),
 *     "album" = @ContextDefinition("entity:node", label = @Translation("Album"))
 *   }
 * @endcode
 *
 * Specifying a default value for the context definition:
 * @code
 *   context = {
 *     "message" = @ContextDefinition("string",
 *       label = @Translation("Message"),
 *       default_value = @Translation("Checkout complete! Thank you for your purchase.")
 *     )
 *   }
 * @endcode
 *
 * @see annotation
 *
 * @}
 */

/**
 * Defines a context definition annotation object.
 *
 * Some plugins require various data contexts in order to function. This class
 * supports that need by allowing the contexts to be easily defined within an
 * annotation and return a ContextDefinitionInterface implementing class.
 *
 * @Annotation
 *
 * @ingroup plugin_context
 */
class ContextDefinition extends Plugin {

  /**
   * The ContextDefinitionInterface object.
   *
   * @var \Drupal\Core\Plugin\Context\ContextDefinitionInterface
   */
  protected $definition;

  /**
   * Constructs a new context definition object.
   *
   * @param array $values
   *   An associative array with the following keys:
   *   - value: The required data type.
   *   - label: (optional) The UI label of this context definition.
   *   - required: (optional) Whether the context definition is required.
   *   - multiple: (optional) Whether the context definition is multivalue.
   *   - description: (optional) The UI description of this context definition.
   *   - default_value: (optional) The default value in case the underlying
   *     value is not set.
   *   - class: (optional) A custom ContextDefinitionInterface class.
   *
   * @throws \Exception
   *   Thrown when the class key is specified with a non
   *   ContextDefinitionInterface implementing class.
   */
  public function __construct(array $values) {
    $values += [
      'required' => TRUE,
      'multiple' => FALSE,
      'default_value' => NULL,
    ];
    // Annotation classes extract data from passed annotation classes directly
    // used in the classes they pass to.
    foreach (['label', 'description'] as $key) {
      // @todo Remove this workaround in https://www.drupal.org/node/2362727.
      if (isset($values[$key]) && $values[$key] instanceof TranslatableMarkup) {
        $values[$key] = (string) $values[$key]->get();
      }
      else {
        $values[$key] = NULL;
      }
    }
    if (isset($values['class']) && !in_array('Drupal\Core\Plugin\Context\ContextDefinitionInterface', class_implements($values['class']))) {
      throw new \Exception('ContextDefinition class must implement \Drupal\Core\Plugin\Context\ContextDefinitionInterface.');
    }
    $class = isset($values['class']) ? $values['class'] : 'Drupal\Core\Plugin\Context\ContextDefinition';
    $this->definition = new $class($values['value'], $values['label'], $values['required'], $values['multiple'], $values['description'], $values['default_value']);
  }

  /**
   * Returns the value of an annotation.
   *
   * @return \Drupal\Core\Plugin\Context\ContextDefinitionInterface
   */
  public function get() {
    return $this->definition;
  }

}