Chris@14
|
1 <?php
|
Chris@14
|
2
|
Chris@14
|
3 namespace Drupal\layout_builder;
|
Chris@14
|
4
|
Chris@14
|
5 use Drupal\Component\Plugin\Exception\PluginException;
|
Chris@14
|
6 use Drupal\Core\Plugin\ContextAwarePluginInterface;
|
Chris@14
|
7 use Drupal\layout_builder\Event\SectionComponentBuildRenderArrayEvent;
|
Chris@14
|
8
|
Chris@14
|
9 /**
|
Chris@14
|
10 * Provides a value object for a section component.
|
Chris@14
|
11 *
|
Chris@14
|
12 * A component represents the smallest part of a layout (for example, a block).
|
Chris@14
|
13 * Components wrap a renderable plugin, currently using
|
Chris@14
|
14 * \Drupal\Core\Block\BlockPluginInterface, and contain the layout region
|
Chris@14
|
15 * within the section layout where the component will be rendered.
|
Chris@14
|
16 *
|
Chris@14
|
17 * @see \Drupal\Core\Layout\LayoutDefinition
|
Chris@14
|
18 * @see \Drupal\layout_builder\Section
|
Chris@14
|
19 * @see \Drupal\layout_builder\SectionStorageInterface
|
Chris@14
|
20 */
|
Chris@14
|
21 class SectionComponent {
|
Chris@14
|
22
|
Chris@14
|
23 /**
|
Chris@14
|
24 * The UUID of the component.
|
Chris@14
|
25 *
|
Chris@14
|
26 * @var string
|
Chris@14
|
27 */
|
Chris@14
|
28 protected $uuid;
|
Chris@14
|
29
|
Chris@14
|
30 /**
|
Chris@14
|
31 * The region the component is placed in.
|
Chris@14
|
32 *
|
Chris@14
|
33 * @var string
|
Chris@14
|
34 */
|
Chris@14
|
35 protected $region;
|
Chris@14
|
36
|
Chris@14
|
37 /**
|
Chris@14
|
38 * An array of plugin configuration.
|
Chris@14
|
39 *
|
Chris@14
|
40 * @var mixed[]
|
Chris@14
|
41 */
|
Chris@14
|
42 protected $configuration;
|
Chris@14
|
43
|
Chris@14
|
44 /**
|
Chris@14
|
45 * The weight of the component.
|
Chris@14
|
46 *
|
Chris@14
|
47 * @var int
|
Chris@14
|
48 */
|
Chris@14
|
49 protected $weight = 0;
|
Chris@14
|
50
|
Chris@14
|
51 /**
|
Chris@14
|
52 * Any additional properties and values.
|
Chris@14
|
53 *
|
Chris@14
|
54 * @var mixed[]
|
Chris@14
|
55 */
|
Chris@14
|
56 protected $additional = [];
|
Chris@14
|
57
|
Chris@14
|
58 /**
|
Chris@14
|
59 * Constructs a new SectionComponent.
|
Chris@14
|
60 *
|
Chris@14
|
61 * @param string $uuid
|
Chris@14
|
62 * The UUID.
|
Chris@14
|
63 * @param string $region
|
Chris@14
|
64 * The region.
|
Chris@14
|
65 * @param mixed[] $configuration
|
Chris@14
|
66 * The plugin configuration.
|
Chris@14
|
67 * @param mixed[] $additional
|
Chris@14
|
68 * An additional values.
|
Chris@14
|
69 */
|
Chris@14
|
70 public function __construct($uuid, $region, array $configuration = [], array $additional = []) {
|
Chris@14
|
71 $this->uuid = $uuid;
|
Chris@14
|
72 $this->region = $region;
|
Chris@14
|
73 $this->configuration = $configuration;
|
Chris@14
|
74 $this->additional = $additional;
|
Chris@14
|
75 }
|
Chris@14
|
76
|
Chris@14
|
77 /**
|
Chris@14
|
78 * Returns the renderable array for this component.
|
Chris@14
|
79 *
|
Chris@14
|
80 * @param \Drupal\Core\Plugin\Context\ContextInterface[] $contexts
|
Chris@14
|
81 * An array of available contexts.
|
Chris@14
|
82 * @param bool $in_preview
|
Chris@14
|
83 * TRUE if the component is being previewed, FALSE otherwise.
|
Chris@14
|
84 *
|
Chris@14
|
85 * @return array
|
Chris@14
|
86 * A renderable array representing the content of the component.
|
Chris@14
|
87 */
|
Chris@14
|
88 public function toRenderArray(array $contexts = [], $in_preview = FALSE) {
|
Chris@14
|
89 $event = new SectionComponentBuildRenderArrayEvent($this, $contexts, $in_preview);
|
Chris@14
|
90 $this->eventDispatcher()->dispatch(LayoutBuilderEvents::SECTION_COMPONENT_BUILD_RENDER_ARRAY, $event);
|
Chris@14
|
91 $output = $event->getBuild();
|
Chris@14
|
92 $event->getCacheableMetadata()->applyTo($output);
|
Chris@14
|
93 return $output;
|
Chris@14
|
94 }
|
Chris@14
|
95
|
Chris@14
|
96 /**
|
Chris@14
|
97 * Gets any arbitrary property for the component.
|
Chris@14
|
98 *
|
Chris@14
|
99 * @param string $property
|
Chris@14
|
100 * The property to retrieve.
|
Chris@14
|
101 *
|
Chris@14
|
102 * @return mixed
|
Chris@14
|
103 * The value for that property, or NULL if the property does not exist.
|
Chris@14
|
104 */
|
Chris@14
|
105 public function get($property) {
|
Chris@14
|
106 if (property_exists($this, $property)) {
|
Chris@14
|
107 $value = isset($this->{$property}) ? $this->{$property} : NULL;
|
Chris@14
|
108 }
|
Chris@14
|
109 else {
|
Chris@14
|
110 $value = isset($this->additional[$property]) ? $this->additional[$property] : NULL;
|
Chris@14
|
111 }
|
Chris@14
|
112 return $value;
|
Chris@14
|
113 }
|
Chris@14
|
114
|
Chris@14
|
115 /**
|
Chris@14
|
116 * Sets a value to an arbitrary property for the component.
|
Chris@14
|
117 *
|
Chris@14
|
118 * @param string $property
|
Chris@14
|
119 * The property to use for the value.
|
Chris@14
|
120 * @param mixed $value
|
Chris@14
|
121 * The value to set.
|
Chris@14
|
122 *
|
Chris@14
|
123 * @return $this
|
Chris@14
|
124 */
|
Chris@14
|
125 public function set($property, $value) {
|
Chris@14
|
126 if (property_exists($this, $property)) {
|
Chris@14
|
127 $this->{$property} = $value;
|
Chris@14
|
128 }
|
Chris@14
|
129 else {
|
Chris@14
|
130 $this->additional[$property] = $value;
|
Chris@14
|
131 }
|
Chris@14
|
132 return $this;
|
Chris@14
|
133 }
|
Chris@14
|
134
|
Chris@14
|
135 /**
|
Chris@14
|
136 * Gets the region for the component.
|
Chris@14
|
137 *
|
Chris@14
|
138 * @return string
|
Chris@14
|
139 * The region.
|
Chris@14
|
140 */
|
Chris@14
|
141 public function getRegion() {
|
Chris@14
|
142 return $this->region;
|
Chris@14
|
143 }
|
Chris@14
|
144
|
Chris@14
|
145 /**
|
Chris@14
|
146 * Sets the region for the component.
|
Chris@14
|
147 *
|
Chris@14
|
148 * @param string $region
|
Chris@14
|
149 * The region.
|
Chris@14
|
150 *
|
Chris@14
|
151 * @return $this
|
Chris@14
|
152 */
|
Chris@14
|
153 public function setRegion($region) {
|
Chris@14
|
154 $this->region = $region;
|
Chris@14
|
155 return $this;
|
Chris@14
|
156 }
|
Chris@14
|
157
|
Chris@14
|
158 /**
|
Chris@14
|
159 * Gets the weight of the component.
|
Chris@14
|
160 *
|
Chris@14
|
161 * @return int
|
Chris@14
|
162 * The zero-based weight of the component.
|
Chris@14
|
163 *
|
Chris@14
|
164 * @throws \UnexpectedValueException
|
Chris@14
|
165 * Thrown if the weight was never set.
|
Chris@14
|
166 */
|
Chris@14
|
167 public function getWeight() {
|
Chris@14
|
168 return $this->weight;
|
Chris@14
|
169 }
|
Chris@14
|
170
|
Chris@14
|
171 /**
|
Chris@14
|
172 * Sets the weight of the component.
|
Chris@14
|
173 *
|
Chris@14
|
174 * @param int $weight
|
Chris@14
|
175 * The zero-based weight of the component.
|
Chris@14
|
176 *
|
Chris@14
|
177 * @return $this
|
Chris@14
|
178 */
|
Chris@14
|
179 public function setWeight($weight) {
|
Chris@14
|
180 $this->weight = $weight;
|
Chris@14
|
181 return $this;
|
Chris@14
|
182 }
|
Chris@14
|
183
|
Chris@14
|
184 /**
|
Chris@14
|
185 * Gets the component plugin configuration.
|
Chris@14
|
186 *
|
Chris@14
|
187 * @return mixed[]
|
Chris@14
|
188 * The component plugin configuration.
|
Chris@14
|
189 */
|
Chris@14
|
190 protected function getConfiguration() {
|
Chris@14
|
191 return $this->configuration;
|
Chris@14
|
192 }
|
Chris@14
|
193
|
Chris@14
|
194 /**
|
Chris@14
|
195 * Sets the plugin configuration.
|
Chris@14
|
196 *
|
Chris@14
|
197 * @param mixed[] $configuration
|
Chris@14
|
198 * The plugin configuration.
|
Chris@14
|
199 *
|
Chris@14
|
200 * @return $this
|
Chris@14
|
201 */
|
Chris@14
|
202 public function setConfiguration(array $configuration) {
|
Chris@14
|
203 $this->configuration = $configuration;
|
Chris@14
|
204 return $this;
|
Chris@14
|
205 }
|
Chris@14
|
206
|
Chris@14
|
207 /**
|
Chris@14
|
208 * Gets the plugin ID.
|
Chris@14
|
209 *
|
Chris@14
|
210 * @return string
|
Chris@14
|
211 * The plugin ID.
|
Chris@14
|
212 *
|
Chris@14
|
213 * @throws \Drupal\Component\Plugin\Exception\PluginException
|
Chris@14
|
214 * Thrown if the plugin ID cannot be found.
|
Chris@14
|
215 */
|
Chris@14
|
216 public function getPluginId() {
|
Chris@14
|
217 if (empty($this->configuration['id'])) {
|
Chris@14
|
218 throw new PluginException(sprintf('No plugin ID specified for component with "%s" UUID', $this->uuid));
|
Chris@14
|
219 }
|
Chris@14
|
220 return $this->configuration['id'];
|
Chris@14
|
221 }
|
Chris@14
|
222
|
Chris@14
|
223 /**
|
Chris@14
|
224 * Gets the UUID for this component.
|
Chris@14
|
225 *
|
Chris@14
|
226 * @return string
|
Chris@14
|
227 * The UUID.
|
Chris@14
|
228 */
|
Chris@14
|
229 public function getUuid() {
|
Chris@14
|
230 return $this->uuid;
|
Chris@14
|
231 }
|
Chris@14
|
232
|
Chris@14
|
233 /**
|
Chris@14
|
234 * Gets the plugin for this component.
|
Chris@14
|
235 *
|
Chris@14
|
236 * @param \Drupal\Core\Plugin\Context\ContextInterface[] $contexts
|
Chris@14
|
237 * An array of contexts to set on the plugin.
|
Chris@14
|
238 *
|
Chris@14
|
239 * @return \Drupal\Component\Plugin\PluginInspectionInterface
|
Chris@14
|
240 * The plugin.
|
Chris@14
|
241 */
|
Chris@14
|
242 public function getPlugin(array $contexts = []) {
|
Chris@14
|
243 $plugin = $this->pluginManager()->createInstance($this->getPluginId(), $this->getConfiguration());
|
Chris@14
|
244 if ($contexts && $plugin instanceof ContextAwarePluginInterface) {
|
Chris@14
|
245 $this->contextHandler()->applyContextMapping($plugin, $contexts);
|
Chris@14
|
246 }
|
Chris@14
|
247 return $plugin;
|
Chris@14
|
248 }
|
Chris@14
|
249
|
Chris@14
|
250 /**
|
Chris@14
|
251 * Wraps the component plugin manager.
|
Chris@14
|
252 *
|
Chris@14
|
253 * @return \Drupal\Core\Block\BlockManagerInterface
|
Chris@14
|
254 * The plugin manager.
|
Chris@14
|
255 */
|
Chris@14
|
256 protected function pluginManager() {
|
Chris@14
|
257 // @todo Figure out the best way to unify fields and blocks and components
|
Chris@14
|
258 // in https://www.drupal.org/node/1875974.
|
Chris@14
|
259 return \Drupal::service('plugin.manager.block');
|
Chris@14
|
260 }
|
Chris@14
|
261
|
Chris@14
|
262 /**
|
Chris@14
|
263 * Wraps the context handler.
|
Chris@14
|
264 *
|
Chris@14
|
265 * @return \Drupal\Core\Plugin\Context\ContextHandlerInterface
|
Chris@14
|
266 * The context handler.
|
Chris@14
|
267 */
|
Chris@14
|
268 protected function contextHandler() {
|
Chris@14
|
269 return \Drupal::service('context.handler');
|
Chris@14
|
270 }
|
Chris@14
|
271
|
Chris@14
|
272 /**
|
Chris@14
|
273 * Wraps the event dispatcher.
|
Chris@14
|
274 *
|
Chris@14
|
275 * @return \Symfony\Component\EventDispatcher\EventDispatcherInterface
|
Chris@14
|
276 * The event dispatcher.
|
Chris@14
|
277 */
|
Chris@14
|
278 protected function eventDispatcher() {
|
Chris@14
|
279 return \Drupal::service('event_dispatcher');
|
Chris@14
|
280 }
|
Chris@14
|
281
|
Chris@14
|
282 /**
|
Chris@14
|
283 * Returns an array representation of the section component.
|
Chris@14
|
284 *
|
Chris@16
|
285 * Only use this method if you are implementing custom storage for sections.
|
Chris@14
|
286 *
|
Chris@14
|
287 * @return array
|
Chris@14
|
288 * An array representation of the section component.
|
Chris@14
|
289 */
|
Chris@14
|
290 public function toArray() {
|
Chris@14
|
291 return [
|
Chris@14
|
292 'uuid' => $this->getUuid(),
|
Chris@14
|
293 'region' => $this->getRegion(),
|
Chris@14
|
294 'configuration' => $this->getConfiguration(),
|
Chris@14
|
295 'additional' => $this->additional,
|
Chris@14
|
296 'weight' => $this->getWeight(),
|
Chris@14
|
297 ];
|
Chris@14
|
298 }
|
Chris@14
|
299
|
Chris@16
|
300 /**
|
Chris@16
|
301 * Creates an object from an array representation of the section component.
|
Chris@16
|
302 *
|
Chris@16
|
303 * Only use this method if you are implementing custom storage for sections.
|
Chris@16
|
304 *
|
Chris@16
|
305 * @param array $component
|
Chris@16
|
306 * An array of section component data in the format returned by ::toArray().
|
Chris@16
|
307 *
|
Chris@16
|
308 * @return static
|
Chris@16
|
309 * The section component object.
|
Chris@16
|
310 */
|
Chris@16
|
311 public static function fromArray(array $component) {
|
Chris@16
|
312 return (new static(
|
Chris@16
|
313 $component['uuid'],
|
Chris@16
|
314 $component['region'],
|
Chris@16
|
315 $component['configuration'],
|
Chris@16
|
316 $component['additional']
|
Chris@16
|
317 ))->setWeight($component['weight']);
|
Chris@16
|
318 }
|
Chris@16
|
319
|
Chris@14
|
320 }
|