Version 1
[yaffs-website] / web / core / lib / Drupal / Core / ImageToolkit / ImageToolkitOperationBase.php
1 <?php
2
3 namespace Drupal\Core\ImageToolkit;
4
5 use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
6 use Drupal\Core\Plugin\PluginBase;
7 use Psr\Log\LoggerInterface;
8
9 /**
10  * Provides a base class for image toolkit operation plugins.
11  *
12  * @see \Drupal\Core\ImageToolkit\Annotation\ImageToolkitOperation
13  * @see \Drupal\Core\ImageToolkit\ImageToolkitOperationInterface
14  * @see \Drupal\Core\ImageToolkit\ImageToolkitOperationManager
15  * @see plugin_api
16  */
17 abstract class ImageToolkitOperationBase extends PluginBase implements ImageToolkitOperationInterface {
18
19   /**
20    * The image toolkit.
21    *
22    * @var \Drupal\Core\ImageToolkit\ImageToolkitInterface
23    */
24   protected $toolkit;
25
26   /**
27    * A logger instance.
28    *
29    * @var \Psr\Log\LoggerInterface
30    */
31   protected $logger;
32
33   /**
34    * Constructs an image toolkit operation plugin.
35    *
36    * @param array $configuration
37    *   A configuration array containing information about the plugin instance.
38    * @param string $plugin_id
39    *   The plugin_id for the plugin instance.
40    * @param array $plugin_definition
41    *   The plugin implementation definition.
42    * @param \Drupal\Core\ImageToolkit\ImageToolkitInterface $toolkit
43    *   The image toolkit.
44    * @param \Psr\Log\LoggerInterface $logger
45    *   A logger instance.
46    */
47   public function __construct(array $configuration, $plugin_id, array $plugin_definition, ImageToolkitInterface $toolkit, LoggerInterface $logger) {
48     parent::__construct($configuration, $plugin_id, $plugin_definition);
49     $this->toolkit = $toolkit;
50     $this->logger = $logger;
51   }
52
53   /**
54    * Returns the image toolkit instance for this operation.
55    *
56    * Image toolkit implementers should provide a toolkit operation base class
57    * that overrides this method to correctly document the return type of this
58    * getter. This provides better DX (code checking and code completion) for
59    * image toolkit operation developers.
60    *
61    * @return \Drupal\Core\ImageToolkit\ImageToolkitInterface
62    */
63   protected function getToolkit() {
64     return $this->toolkit;
65   }
66
67   /**
68    * Returns the definition of the operation arguments.
69    *
70    * Image toolkit operation implementers must implement this method to
71    * "document" their operation, thus also if no arguments are expected.
72    *
73    * @return array
74    *   An array whose keys are the names of the arguments (e.g. "width",
75    *   "degrees") and each value is an associative array having the following
76    *   keys:
77    *   - description: A string with the argument description. This is used only
78    *     internally for documentation purposes, so it does not need to be
79    *     translatable.
80    *   - required: (optional) A boolean indicating if this argument should be
81    *     provided or not. Defaults to TRUE.
82    *   - default: (optional) When the argument is set to "required" = FALSE,
83    *     this must be set to a default value. Ignored for "required" = TRUE
84    *     arguments.
85    */
86   abstract protected function arguments();
87
88   /**
89    * Checks if required arguments are passed in and adds defaults for non passed
90    * in optional arguments.
91    *
92    * Image toolkit operation implementers should not normally need to override
93    * this method as they should place their own validation in validateArguments.
94    *
95    * @param array $arguments
96    *   An associative array of arguments to be used by the toolkit operation.
97    *
98    * @return array
99    *   The prepared arguments array.
100    *
101    * @throws \InvalidArgumentException.
102    * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException.
103    */
104   protected function prepareArguments(array $arguments) {
105     foreach ($this->arguments() as $id => $argument) {
106       $argument += ['required' => TRUE];
107       // Check if the argument is required and, if so, has been provided.
108       if ($argument['required']) {
109         if (!array_key_exists($id, $arguments)) {
110           // If the argument is required throw an exception.
111           throw new \InvalidArgumentException("Argument '$id' expected by plugin '{$this->getPluginId()}' but not passed");
112         }
113       }
114       else {
115         // Optional arguments require a 'default' value.
116         // We check this even if the argument is provided by the caller, as we
117         // want to fail fast here, i.e. at development time.
118         if (!array_key_exists('default', $argument)) {
119           // The plugin did not define a default, so throw a plugin exception,
120           // not an invalid argument exception.
121           throw new InvalidPluginDefinitionException("Default for argument '$id' expected by plugin '{$this->getPluginId()}' but not defined");
122         }
123
124         // Use the default value if the argument is not passed in.
125         if (!array_key_exists($id, $arguments)) {
126           $arguments[$id] = $argument['default'];
127         }
128       }
129     }
130     return $arguments;
131   }
132
133   /**
134    * Validates the arguments.
135    *
136    * Image toolkit operation implementers should place any argument validation
137    * in this method, throwing an InvalidArgumentException when an error is
138    * encountered.
139    *
140    * Validation typically includes things like:
141    * - Checking that width and height are not negative.
142    * - Checking that a color value is indeed a color.
143    *
144    * But validation may also include correcting the arguments, e.g:
145    * - Casting arguments to the correct type.
146    * - Rounding pixel values to an integer.
147    *
148    * This base implementation just returns the array of arguments and thus does
149    * not need to be called by overriding methods.
150    *
151    * @param array $arguments
152    *   An associative array of arguments to be used by the toolkit operation.
153    *
154    * @return array
155    *   The validated and corrected arguments array.
156    *
157    * @throws \InvalidArgumentException
158    *   If one or more of the arguments are not valid.
159    * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
160    *   If the plugin does not define a default for an optional argument.
161    */
162   protected function validateArguments(array $arguments) {
163     return $arguments;
164   }
165
166   /**
167    * {@inheritdoc}
168    */
169   public final function apply(array $arguments) {
170     $arguments = $this->prepareArguments($arguments);
171     $arguments = $this->validateArguments($arguments);
172     return $this->execute($arguments);
173   }
174
175   /**
176    * Performs the actual manipulation on the image.
177    *
178    * Image toolkit operation implementers must implement this method. This
179    * method is responsible for actually performing the operation on the image.
180    * When this method gets called, the implementer may assume all arguments,
181    * also the optional ones, to be available, validated and corrected.
182    *
183    * @param array $arguments
184    *   An associative array of arguments to be used by the toolkit operation.
185    *
186    * @return bool
187    *   TRUE if the operation was performed successfully, FALSE otherwise.
188    */
189   abstract protected function execute(array $arguments);
190
191 }