Completed
Push — 8.x-1.x ( 0b2c90...9836fb )
by Janez
01:54
created

EntityHelperTrait::renderEntityEmbed()   C

Complexity

Conditions 12
Paths 96

Size

Total Lines 62
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 9
Bugs 1 Features 0
Metric Value
c 9
b 1
f 0
dl 0
loc 62
rs 6.2072
cc 12
eloc 30
nc 96
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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