Completed
Push — 8.x-1.x ( b8baa3...990602 )
by Dave
02:07
created

EntityHelperTrait::renderEntityEmbed()   B

Complexity

Conditions 9
Paths 48

Size

Total Lines 57
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 0 Features 0
Metric Value
c 8
b 0
f 0
dl 0
loc 57
rs 7.0745
cc 9
eloc 28
nc 48
nop 2

How to fix   Long Method   

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
    // @todo Should this hook get invoked if $build is an empty array?
217
    $this->moduleHandler()->alter(array("{$context['data-entity-type']}_embed", 'entity_embed'), $build, $entity, $context);
218
    $entity_output = $this->renderer()->render($build);
219
220
    return $entity_output;
221
  }
222
223
  /**
224
   * Renders an entity using an Entity Embed Display plugin.
225
   *
226
   * @param \Drupal\Core\Entity\EntityInterface $entity
227
   *   The entity to be rendered.
228
   * @param string $plugin_id
229
   *   The Entity Embed Display plugin ID.
230
   * @param array $plugin_configuration
231
   *   (optional) Array of plugin configuration values.
232
   * @param array $context
233
   *   (optional) Array of additional context values, usually the embed HTML
234
   *   tag's attributes.
235
   *
236
   * @return array
237
   *   A render array for the Entity Embed Display plugin.
238
   */
239
  protected function renderEntityEmbedDisplayPlugin(EntityInterface $entity, $plugin_id, array $plugin_configuration = array(), array $context = array()) {
240
    // Build the Entity Embed Display plugin.
241
    /** @var \Drupal\entity_embed\EntityEmbedDisplay\EntityEmbedDisplayBase $display */
242
    $display = $this->displayPluginManager()->createInstance($plugin_id, $plugin_configuration);
243
    $display->setContextValue('entity', $entity);
244
    $display->setAttributes($context);
245
246
    // Check if the Entity Embed Display plugin is accessible. This also checks
247
    // entity access, which is why we never call $entity->access() here.
248
    if (!$display->access()) {
249
      return array();
250
    }
251
252
    return $display->build();
253
  }
254
255
  /**
256
   * Returns the entity manager.
257
   *
258
   * @return \Drupal\Core\Entity\EntityManagerInterface
259
   *   The entity manager.
260
   */
261
  protected function entityManager() {
262
    if (!isset($this->entityManager)) {
263
      $this->entityManager = \Drupal::entityManager();
264
    }
265
    return $this->entityManager;
266
  }
267
268
  /**
269
   * Sets the entity manager service.
270
   *
271
   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
272
   *   The entity manager service.
273
   *
274
   * @return self
275
   */
276
  public function setEntityManager(EntityManagerInterface $entity_manager) {
277
    $this->entityManager = $entity_manager;
278
    return $this;
279
  }
280
281
  /**
282
   * Returns the module handler.
283
   *
284
   * @return \Drupal\Core\Extension\ModuleHandlerInterface
285
   *   The module handler.
286
   */
287
  protected function moduleHandler() {
288
    if (!isset($this->moduleHandler)) {
289
      $this->moduleHandler = \Drupal::moduleHandler();
290
    }
291
    return $this->moduleHandler;
292
  }
293
294
  /**
295
   * Sets the module handler service.
296
   *
297
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
298
   *   The module handler service.
299
   *
300
   * @return self
301
   */
302
  public function setModuleHandler(ModuleHandlerInterface $module_handler) {
303
    $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...
304
    return $this;
305
  }
306
307
  /**
308
   * Returns the Entity Embed Display plugin manager.
309
   *
310
   * @return \Drupal\entity_embed\EntityEmbedDisplay\EntityEmbedDisplayManager
311
   *   The Entity Embed Display plugin manager.
312
   */
313
  protected function displayPluginManager() {
314
    if (!isset($this->displayPluginManager)) {
315
      $this->displayPluginManager = \Drupal::service('plugin.manager.entity_embed.display');
316
    }
317
    return $this->displayPluginManager;
318
  }
319
320
  /**
321
   * Sets the Entity Embed Display plugin manager service.
322
   *
323
   * @param \Drupal\entity_embed\EntityEmbedDisplay\EntityEmbedDisplayManager $display_plugin_manager
324
   *   The Entity Embed Display plugin manager service.
325
   *
326
   * @return self
327
   */
328
  public function setDisplayPluginManager(EntityEmbedDisplayManager $display_plugin_manager) {
329
    $this->displayPluginManager = $display_plugin_manager;
330
    return $this;
331
  }
332
333
  /**
334
   * Returns the renderer.
335
   *
336
   * @return \Drupal\Core\Render\RendererInterface
337
   *   The renderer.
338
   */
339
  protected function renderer() {
340
    if (!isset($this->renderer)) {
341
      $this->renderer = \Drupal::service('renderer');
342
    }
343
    return $this->renderer;
344
  }
345
346
  /**
347
   * Sets the renderer.
348
   *
349
   * @param \Drupal\Core\Render\RendererInterface $renderer
350
   *   The renderer.
351
   *
352
   * @return self
353
   */
354
  public function setRenderer(RendererInterface $renderer) {
355
    $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...
356
    return $this;
357
  }
358
}
359