Completed
Push — 8.x-1.x ( 9760c0...1376e8 )
by Janez
07:47
created

EntityHelperTrait   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 314
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 1

Importance

Changes 9
Bugs 3 Features 0
Metric Value
wmc 28
c 9
b 3
f 0
lcom 2
cbo 1
dl 0
loc 314
rs 10

15 Methods

Rating   Name   Duplication   Size   Complexity  
A loadEntity() 0 4 2
A loadMultipleEntities() 0 19 4
A canRenderEntity() 0 4 1
A canRenderEntityType() 0 3 1
A renderEntity() 0 4 1
A entityManager() 0 6 2
A moduleHandler() 0 6 2
A displayPluginManager() 0 6 2
A renderer() 0 6 2
A setRenderer() 0 4 1
A setEntityManager() 0 4 1
A setModuleHandler() 0 4 1
A setDisplayPluginManager() 0 4 1
B renderEntityEmbed() 0 38 5
A renderEntityEmbedDisplayPlugin() 0 15 2
1
<?php
2
3
/**
4
 * @file
5
 * Contains Drupal\entity_embed\EntityHelperTrait.
6
 */
7
8
namespace Drupal\entity_embed;
9
10
use Drupal\Core\Entity\EntityInterface;
11
use Drupal\Core\Entity\EntityManagerInterface;
12
use Drupal\Core\Entity\EntityStorageException;
13
use Drupal\Core\Extension\ModuleHandlerInterface;
14
use Drupal\Core\Render\RendererInterface;
15
use Drupal\entity_embed\EntityEmbedDisplay\EntityEmbedDisplayManager;
16
17
/**
18
 * Wrapper methods for entity loading and rendering.
19
 *
20
 * This utility trait should only be used in application-level code, such as
21
 * classes that would implement ContainerInjectionInterface. Services registered
22
 * in the Container should not use this trait but inject the appropriate service
23
 * directly for easier testing.
24
 */
25
trait EntityHelperTrait {
26
27
  /**
28
   * The entity manager service.
29
   *
30
   * @var \Drupal\Core\Entity\EntityManagerInterface
31
   */
32
  protected $entityManager;
33
34
  /**
35
   * The module handler service.
36
   *
37
   * @var \Drupal\Core\Extension\ModuleHandlerInterface.
38
   */
39
  protected $moduleHandler;
40
41
  /**
42
   * The Entity Embed Display plugin manager.
43
   *
44
   * @var \Drupal\entity_embed\EntityEmbedDisplay\EntityEmbedDisplayManager.
45
   */
46
  protected $displayPluginManager;
47
48
  /**
49
   * The renderer.
50
   *
51
   * @var \Drupal\Core\Render\RendererInterface.
52
   */
53
  protected $renderer;
54
55
  /**
56
   * Loads an entity from the database.
57
   *
58
   * @param string $entity_type
59
   *   The entity type to load, e.g. node or user.
60
   * @param mixed $id
61
   *   The id or UUID of the entity to load.
62
   *
63
   * @return \Drupal\Core\Entity\EntityInterface
64
   *   The entity object, or NULL if there is no entity with the given id or
65
   *   UUID.
66
   */
67
  protected function loadEntity($entity_type, $id) {
68
    $entities = $this->loadMultipleEntities($entity_type, array($id));
69
    return !empty($entities) ? reset($entities) : NULL;
70
  }
71
72
  /**
73
   * Loads multiple entities from the database.
74
   *
75
   * @param string $entity_type
76
   *   The entity type to load, e.g. node or user.
77
   * @param array $ids
78
   *   An array of entity IDs or UUIDs.
79
   *
80
   * @return array
81
   *   An array of entity objects indexed by their ids.
82
   *
83
   * @throws \Drupal\Core\Entity\EntityStorageException
84
   *   Throws an exception if the entity type does not supports UUIDs.
85
   */
86
  protected function loadMultipleEntities($entity_type, array $ids) {
87
    $entities = array();
88
    $storage = $this->entityManager()->getStorage($entity_type);
89
90
    $uuids = array_filter($ids, 'Drupal\Component\Uuid\Uuid::isValid');
91
    if (!empty($uuids)) {
92
      $definition = $this->entityManager()->getDefinition($entity_type);
93
      if (!$uuid_key = $definition->getKey('uuid')) {
94
        throw new EntityStorageException("Entity type $entity_type does not support UUIDs.");
95
      }
96
      $entities += $storage->loadByProperties(array($uuid_key => $uuids));
97
    }
98
99
    if ($remaining_ids = array_diff($ids, $uuids)) {
100
      $entities += $storage->loadMultiple($remaining_ids);
101
    }
102
103
    return $entities;
104
  }
105
106
  /**
107
   * Determines if an entity can be rendered.
108
   *
109
   * @param \Drupal\Core\Entity\EntityInterface $entity
110
   *   The entity object.
111
   *
112
   * @return bool
113
   *   TRUE if the entity's type has a view builder controller, otherwise FALSE.
114
   */
115
  protected function canRenderEntity(EntityInterface $entity) {
116
    $entity_type = $entity->getEntityTypeId();
117
    return $this->canRenderEntityType($entity_type);
118
  }
119
120
  /**
121
   * Determines if an entity type can be rendered.
122
   *
123
   * @param string $entity_type
124
   *   The entity type id.
125
   *
126
   * @return bool
127
   *   TRUE if the entitys type has a view builder controller, otherwise FALSE.
128
   */
129
  protected function canRenderEntityType($entity_type) {
130
    return $this->entityManager()->hasHandler($entity_type, 'view_builder');
131
  }
132
133
  /**
134
   * Returns the render array for an entity.
135
   *
136
   * @param \Drupal\Core\Entity\EntityInterface $entity
137
   *   The entity to be rendered.
138
   * @param string $view_mode
139
   *   The view mode that should be used to display the entity.
140
   * @param string $langcode
141
   *   (optional) For which language the entity should be rendered, defaults to
142
   *   the current content language.
143
   *
144
   * @return array
145
   *   A render array for the entity.
146
   */
147
  protected function renderEntity(EntityInterface $entity, $view_mode, $langcode = NULL) {
148
    $render_controller = $this->entityManager()->getViewBuilder($entity->getEntityTypeId());
149
    return $render_controller->view($entity, $view_mode, $langcode);
150
  }
151
152
  /**
153
   * Renders an embedded entity.
154
   *
155
   * @param \Drupal\Core\Entity\EntityInterface $entity
156
   *   The entity to be rendered.
157
   * @param array $context
158
   *   (optional) Array of context values, corresponding to the attributes on
159
   *   the embed HTML tag.
160
   *
161
   * @return string
162
   *   The HTML of the entity rendered with the Entity Embed Display plugin.
163
   */
164
  protected function renderEntityEmbed(EntityInterface $entity, array $context = array()) {
165
    // Support the deprecated view-mode data attribute.
166
    if (isset($context['data-view-mode']) && !isset($context['data-entity-embed-display']) && !isset($context['data-entity-embed-settings'])) {
167
      $context['data-entity-embed-display'] = 'entity_reference:entity_reference_entity_view';
168
      $context['data-entity-embed-settings'] = ['view_mode' => &$context['data-view-mode']];
169
    }
170
171
    // Merge in default attributes.
172
    $context += array(
173
      'data-entity-id' => $entity->id(),
174
      'data-entity-type' => $entity->getEntityTypeId(),
175
      'data-entity-embed-display' => 'entity_reference:entity_reference_entity_view',
176
      'data-entity-embed-settings' => array(),
177
    );
178
179
    // The default Entity Embed Display plugin has been deprecated by the
180
    // rendered entity field formatter.
181
    if ($context['data-entity-embed-display'] === 'default') {
182
      $context['data-entity-embed-display'] = 'entity_reference:entity_reference_entity_view';
183
    }
184
185
    // Allow modules to alter the entity prior to embed rendering.
186
    $this->moduleHandler()->alter(array("{$context['data-entity-type']}_embed_context", 'entity_embed_context'), $context, $entity);
187
188
    // Build and render the Entity Embed Display plugin, allowing modules to
189
    // alter the result before rendering.
190
    $build = $this->renderEntityEmbedDisplayPlugin(
191
      $entity,
192
      $context['data-entity-embed-display'],
193
      $context['data-entity-embed-settings'],
194
      $context
195
    );
196
    // @todo Should this hook get invoked if $build is an empty array?
197
    $this->moduleHandler()->alter(array("{$context['data-entity-type']}_embed", 'entity_embed'), $build, $entity, $context);
198
    $entity_output = $this->renderer()->render($build);
199
200
    return $entity_output;
201
  }
202
203
  /**
204
   * Renders an entity using an Entity Embed Display plugin.
205
   *
206
   * @param \Drupal\Core\Entity\EntityInterface $entity
207
   *   The entity to be rendered.
208
   * @param string $plugin_id
209
   *   The Entity Embed Display plugin ID.
210
   * @param array $plugin_configuration
211
   *   (optional) Array of plugin configuration values.
212
   * @param array $context
213
   *   (optional) Array of additional context values, usually the embed HTML
214
   *   tag's attributes.
215
   *
216
   * @return array
217
   *   A render array for the Entity Embed Display plugin.
218
   */
219
  protected function renderEntityEmbedDisplayPlugin(EntityInterface $entity, $plugin_id, array $plugin_configuration = array(), array $context = array()) {
220
    // Build the Entity Embed Display plugin.
221
    /** @var \Drupal\entity_embed\EntityEmbedDisplay\EntityEmbedDisplayBase $display */
222
    $display = $this->displayPluginManager()->createInstance($plugin_id, $plugin_configuration);
223
    $display->setContextValue('entity', $entity);
224
    $display->setAttributes($context);
225
226
    // Check if the Entity Embed Display plugin is accessible. This also checks
227
    // entity access, which is why we never call $entity->access() here.
228
    if (!$display->access()) {
229
      return array();
230
    }
231
232
    return $display->build();
233
  }
234
235
  /**
236
   * Returns the entity manager.
237
   *
238
   * @return \Drupal\Core\Entity\EntityManagerInterface
239
   *   The entity manager.
240
   */
241
  protected function entityManager() {
242
    if (!isset($this->entityManager)) {
243
      $this->entityManager = \Drupal::entityManager();
244
    }
245
    return $this->entityManager;
246
  }
247
248
  /**
249
   * Sets the entity manager service.
250
   *
251
   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
252
   *   The entity manager service.
253
   *
254
   * @return self
255
   */
256
  public function setEntityManager(EntityManagerInterface $entity_manager) {
257
    $this->entityManager = $entity_manager;
258
    return $this;
259
  }
260
261
  /**
262
   * Returns the module handler.
263
   *
264
   * @return \Drupal\Core\Extension\ModuleHandlerInterface
265
   *   The module handler.
266
   */
267
  protected function moduleHandler() {
268
    if (!isset($this->moduleHandler)) {
269
      $this->moduleHandler = \Drupal::moduleHandler();
270
    }
271
    return $this->moduleHandler;
272
  }
273
274
  /**
275
   * Sets the module handler service.
276
   *
277
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
278
   *   The module handler service.
279
   *
280
   * @return self
281
   */
282
  public function setModuleHandler(ModuleHandlerInterface $module_handler) {
283
    $this->moduleHandler = $module_handler;
0 ignored issues
show
Documentation Bug introduced by
It seems like $module_handler of type object<Drupal\Core\Exten...ModuleHandlerInterface> is incompatible with the declared type object<Drupal\Core\Exten...oduleHandlerInterface.> of property $moduleHandler.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
284
    return $this;
285
  }
286
287
  /**
288
   * Returns the Entity Embed Display plugin manager.
289
   *
290
   * @return \Drupal\entity_embed\EntityEmbedDisplay\EntityEmbedDisplayManager
291
   *   The Entity Embed Display plugin manager.
292
   */
293
  protected function displayPluginManager() {
294
    if (!isset($this->displayPluginManager)) {
295
      $this->displayPluginManager = \Drupal::service('plugin.manager.entity_embed.display');
296
    }
297
    return $this->displayPluginManager;
298
  }
299
300
  /**
301
   * Sets the Entity Embed Display plugin manager service.
302
   *
303
   * @param \Drupal\entity_embed\EntityEmbedDisplay\EntityEmbedDisplayManager $display_plugin_manager
304
   *   The Entity Embed Display plugin manager service.
305
   *
306
   * @return self
307
   */
308
  public function setDisplayPluginManager(EntityEmbedDisplayManager $display_plugin_manager) {
309
    $this->displayPluginManager = $display_plugin_manager;
310
    return $this;
311
  }
312
313
  /**
314
   * Returns the renderer.
315
   *
316
   * @return \Drupal\Core\Render\RendererInterface
317
   *   The renderer.
318
   */
319
  protected function renderer() {
320
    if (!isset($this->renderer)) {
321
      $this->renderer = \Drupal::service('renderer');
322
    }
323
    return $this->renderer;
324
  }
325
326
  /**
327
   * Sets the renderer.
328
   *
329
   * @param \Drupal\Core\Render\RendererInterface $renderer
330
   *   The renderer.
331
   *
332
   * @return self
333
   */
334
  public function setRenderer(RendererInterface $renderer) {
335
    $this->renderer = $renderer;
0 ignored issues
show
Documentation Bug introduced by
It seems like $renderer of type object<Drupal\Core\Render\RendererInterface> is incompatible with the declared type object<Drupal\Core\Render\RendererInterface.> of property $renderer.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
336
    return $this;
337
  }
338
}
339