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