entity.inc 20.3 KB
Newer Older
1 2 3 4 5 6 7
<?php

/**
 * @file
 * Entity API for handling entities like nodes or users.
 */

8
use Drupal\Core\Entity\EntityInterface;
9
use Drupal\Core\Entity\Entity\EntityFormDisplay;
10
use Drupal\Core\Entity\Entity\EntityViewDisplay;
11

12 13 14 15 16 17
/**
 * Clears the entity render cache for all entity types.
 */
function entity_render_cache_clear() {
  $entity_manager = Drupal::entityManager();
  foreach ($entity_manager->getDefinitions() as $entity_type => $info) {
18
    if ($entity_manager->hasHandler($entity_type, 'view_builder')) {
19
      $entity_manager->getViewBuilder($entity_type)->resetCache();
20 21 22 23
    }
  }
}

24
/**
25
 * Returns the entity bundle info.
26
 *
27 28 29 30 31 32
 * @param string|null $entity_type
 *   The entity type whose bundle info should be returned, or NULL for all
 *   bundles info. Defaults to NULL.
 *
 * @return array
 *   The bundle info for a specific entity type, or all entity types.
33
 *
34
 * @deprecated in Drupal 8.x-dev and will be removed before Drupal 9.0.0. Use
35 36 37 38
 *   \Drupal\Core\Entity\EntityTypeBundleInfoInterface::getBundleInfo() for a
 *   single bundle, or
 *   \Drupal\Core\Entity\EntityTypeBundleInfoInterface::getAllBundleInfo() for
 *   all bundles.
39
 *
40 41
 * @see \Drupal\Core\Entity\EntityTypeBundleInfoInterface::getBundleInfo()
 * @see \Drupal\Core\Entity\EntityTypeBundleInfoInterface::getAllBundleInfo()
42 43
 */
function entity_get_bundles($entity_type = NULL) {
44
  if (isset($entity_type)) {
45
    return \Drupal::entityManager()->getBundleInfo($entity_type);
46
  }
47
  else {
48
    return \Drupal::entityManager()->getAllBundleInfo();
49 50 51
  }
}

52
/**
53 54 55 56
 * Loads an entity from the database.
 *
 * @param string $entity_type
 *   The entity type to load, e.g. node or user.
57
 * @param mixed $id
58 59 60 61
 *   The id of the entity to load.
 * @param bool $reset
 *   Whether to reset the internal cache for the requested entity type.
 *
62 63
 * @return \Drupal\Core\Entity\EntityInterface|null
 *   The entity object, or NULL if there is no entity with the given ID.
64
 *
65 66 67 68 69 70
 * @deprecated in Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
 *   The method overriding Entity::load() for the entity type, e.g.
 *   \Drupal\node\Entity\Node::load() if the entity type is known. If the
 *   entity type is variable, use the entity manager service to load the entity
 *   from the entity storage:
 * @code
71
 * \Drupal::entityTypeManager()->getStorage($entity_type)->load($id);
72 73 74
 * @endcode
 *
 * @see \Drupal\Core\Entity\EntityInterface::load()
75
 * @see \Drupal\Core\Entity\EntityTypeManagerInterface::getStorage()
76
 * @see \Drupal\Core\Entity\EntityStorageInterface::load()
77
 * @see \Drupal\Core\Entity\Sql\SqlContentEntityStorage
78
 * @see \Drupal\Core\Entity\Query\QueryInterface
79 80
 */
function entity_load($entity_type, $id, $reset = FALSE) {
81
  $controller = \Drupal::entityManager()->getStorage($entity_type);
82 83 84 85
  if ($reset) {
    $controller->resetCache(array($id));
  }
  return $controller->load($id);
86 87
}

88 89 90 91 92 93 94 95
/**
 * Loads an entity from the database.
 *
 * @param string $entity_type
 *   The entity type to load, e.g. node or user.
 * @param int $revision_id
 *   The id of the entity to load.
 *
96 97
 * @return \Drupal\Core\Entity\EntityInterface|null
 *   The entity object, or NULL if there is no entity with the given revision
98 99
 *   id.
 *
100 101 102 103
 * @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
 *   the entity storage's loadRevision() method to load a specific entity
 *   revision:
 * @code
104 105 106
 * \Drupal::entityTypeManager()
 *   ->getStorage($entity_type)
 *   ->loadRevision($revision_id);
107 108
 * @endcode
 *
109
 * @see \Drupal\Core\Entity\EntityTypeManagerInterface::getStorage()
110
 * @see \Drupal\Core\Entity\EntityStorageInterface::loadRevision()
111
 * @see \Drupal\Core\Entity\Sql\SqlContentEntityStorage
112 113
 */
function entity_revision_load($entity_type, $revision_id) {
114
  return \Drupal::entityManager()
115
    ->getStorage($entity_type)
116
    ->loadRevision($revision_id);
117 118
}

119
/**
120
 * Deletes an entity revision.
121 122 123 124 125
 *
 * @param string $entity_type
 *   The entity type to load, e.g. node or user.
 * @param $revision_id
 *   The revision ID to delete.
126 127 128 129 130
 *
 * @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
 *   the entity storage's deleteRevision() method to delete a specific entity
 *   revision:
 * @code
131 132 133
 * \Drupal::entityTypeManager()
 *   ->getStorage($entity_type)
 *   ->deleteRevision($revision_id);
134 135
 * @endcode
 *
136
 * @see \Drupal\Core\Entity\EntityTypeManagerInterface::getStorage()
137
 * @see \Drupal\Core\Entity\EntityStorageInterface::deleteRevision()
138 139
 */
function entity_revision_delete($entity_type, $revision_id) {
140
  \Drupal::entityManager()
141
    ->getStorage($entity_type)
142
    ->deleteRevision($revision_id);
143 144
}

145 146
/**
 * Loads multiple entities from the database.
147 148 149 150 151 152
 *
 * This function should be used whenever you need to load more than one entity
 * from the database. The entities are loaded into memory and will not require
 * database access if loaded again during the same page request.
 *
 * The actual loading is done through a class that has to implement the
153 154
 * \Drupal\Core\Entity\EntityStorageInterface interface. By default,
 * \Drupal\Core\Entity\Sql\SqlContentEntityStorage is used for content entities
155 156
 * and Drupal\Core\Config\Entity\ConfigEntityStorage for config entities. Entity
 * types can specify that a different class should be used by setting the
157 158
 * "handlers['storage']" key in the entity plugin annotation. These classes
 * can either implement the \Drupal\Core\Entity\EntityStorageInterface
159
 * interface, or, most commonly, extend the
160 161
 * \Drupal\Core\Entity\Sql\SqlContentEntityStorage class. See
 * \Drupal\node\Entity\Node and \Drupal\node\NodeStorage for an example.
162
 *
163
 * @param string $entity_type
164
 *   The entity type to load, e.g. node or user.
165 166
 * @param array $ids
 *   (optional) An array of entity IDs. If omitted, all entities are loaded.
167
 * @param bool $reset
168 169
 *   Whether to reset the internal cache for the requested entity type.
 *
170
 * @return array
171
 *   An array of entity objects indexed by their IDs.
172
 *
173 174 175 176 177 178
 * @deprecated in Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
 *   The method overriding Entity::loadMultiple() for the entity type, e.g.
 *   \Drupal\node\Entity\Node::loadMultiple() if the entity type is known. If
 *   the entity type is variable, use the entity manager service to load the
 *   entity from the entity storage:
 * @code
179
 * \Drupal::entityTypeManager()->getStorage($entity_type)->loadMultiple($id);
180 181 182
 * @endcode
 *
 * @see \Drupal\Core\Entity\EntityInterface::loadMultiple()
183
 * @see \Drupal\Core\Entity\EntityTypeManagerInterface::getStorage()
184
 * @see \Drupal\Core\Entity\EntityStorageInterface::loadMultiple()
185
 * @see \Drupal\Core\Entity\Sql\SqlContentEntityStorage
186
 * @see \Drupal\Core\Entity\Query\QueryInterface
187
 */
188
function entity_load_multiple($entity_type, array $ids = NULL, $reset = FALSE) {
189
  $controller = \Drupal::entityManager()->getStorage($entity_type);
190
  if ($reset) {
191
    $controller->resetCache($ids);
192
  }
193
  return $controller->loadMultiple($ids);
194 195 196 197 198 199 200 201 202 203 204 205
}

/**
 * Load entities by their property values.
 *
 * @param string $entity_type
 *   The entity type to load, e.g. node or user.
 * @param array $values
 *   An associative array where the keys are the property names and the
 *   values are the values those properties must have.
 *
 * @return array
206
 *   An array of entity objects indexed by their IDs. Returns an empty array if
207
 *   no matching entities are found.
208 209 210 211 212
 *
 * @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
 *   the entity storage's loadByProperties() method to load an entity by their
 *   property values:
 * @code
213 214 215
 * \Drupal::entityTypeManager()
 *   ->getStorage($entity_type)
 *   ->loadByProperties($values);
216 217
 * @endcode
 *
218
 * @see \Drupal\Core\Entity\EntityTypeManagerInterface::getStorage()
219
 * @see \Drupal\Core\Entity\EntityStorageInterface::loadByProperties()
220 221
 */
function entity_load_multiple_by_properties($entity_type, array $values) {
222
  return \Drupal::entityManager()
223
    ->getStorage($entity_type)
224
    ->loadByProperties($values);
225 226 227 228 229 230 231 232 233 234 235 236 237
}

/**
 * Loads the unchanged, i.e. not modified, entity from the database.
 *
 * Unlike entity_load() this function ensures the entity is directly loaded from
 * the database, thus bypassing any static cache. In particular, this function
 * is useful to determine changes by comparing the entity being saved to the
 * stored entity.
 *
 * @param $entity_type
 *   The entity type to load, e.g. node or user.
 * @param $id
238
 *   The ID of the entity to load.
239
 *
240
 * @return \Drupal\Core\Entity\EntityInterface|null
241
 *   The unchanged entity, or FALSE if the entity cannot be loaded.
242 243 244 245
 *
 * @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
 *   the entity storage's loadUnchanged() method to load an unchanged entity:
 * @code
246
 * \Drupal::entityTypeManager()->getStorage($entity_type)->loadUnchanged($id);
247 248
 * @endcode
 *
249
 * @see \Drupal\Core\Entity\EntityTypeManagerInterface::getStorage()
250
 * @see \Drupal\Core\Entity\EntityStorageInterface::loadUnchanged()
251 252
 */
function entity_load_unchanged($entity_type, $id) {
253
  return \Drupal::entityManager()
254
    ->getStorage($entity_type)
255
    ->loadUnchanged($id);
256 257
}

258 259 260
/**
 * Deletes multiple entities permanently.
 *
261
 * @param string $entity_type
262
 *   The type of the entity.
263
 * @param array $ids
264
 *   An array of entity IDs of the entities to delete.
265 266 267 268
 *
 * @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
 *   the entity storage's delete() method to delete multiple entities:
 * @code
269
 * $storage_handler = \Drupal::entityTypeManager()->getStorage($entity_type);
270 271 272 273
 * $entities = $storage_handler->loadMultiple($ids);
 * $storage_handler->delete($entities);
 * @endcode
 *
274
 * @see \Drupal\Core\Entity\EntityTypeManagerInterface::getStorage()
275 276
 * @see \Drupal\Core\Entity\EntityStorageInterface::loadMultiple()
 * @see \Drupal\Core\Entity\EntityStorageInterface::delete()
277
 */
278
function entity_delete_multiple($entity_type, array $ids) {
279
  $controller = \Drupal::entityManager()->getStorage($entity_type);
280
  $entities = $controller->loadMultiple($ids);
281
  $controller->delete($entities);
282 283 284
}

/**
285
 * Constructs a new entity object, without permanently saving it.
286
 *
287
 * @param string $entity_type
288
 *   The type of the entity.
289 290 291
 * @param array $values
 *   (optional) An array of values to set, keyed by property name. If the
 *   entity type has bundles, the bundle key has to be specified.
292
 *
293
 * @return \Drupal\Core\Entity\EntityInterface
294
 *   A new entity object.
295
 *
296 297 298 299 300 301
 * @deprecated in Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
 *   The method overriding Entity::create() for the entity type, e.g.
 *   \Drupal\node\Entity\Node::create() if the entity type is known. If the
 *   entity type is variable, use the entity storage's create() method to
 *   construct a new entity:
 * @code
302
 * \Drupal::entityTypeManager()->getStorage($entity_type)->create($values);
303 304
 * @endcode
 *
305
 * @see \Drupal\Core\Entity\EntityTypeManagerInterface::getStorage()
306
 * @see \Drupal\Core\Entity\EntityStorageInterface::create()
307
 */
308
function entity_create($entity_type, array $values = array()) {
309
  return \Drupal::entityManager()
310
    ->getStorage($entity_type)
311
    ->create($values);
312 313
}

314 315 316
/**
 * Returns the label of an entity.
 *
317
 * @param \Drupal\Core\Entity\EntityInterface $entity
318
 *   The entity for which to generate the label.
319 320 321 322
 * @param $langcode
 *   (optional) The language code of the language that should be used for
 *   getting the label. If set to NULL, the entity's default language is
 *   used.
323
 *
324
 * @return string|null
325
 *   The label of the entity, or NULL if there is no label defined.
326
 *
327 328 329 330 331 332
 * @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
 *   the entity's label() method to get the label of the entity:
 * @code
 * $entity->label($langcode);
 * @endcode
 *
333
 * @see \Drupal\Core\Entity\EntityInterface::label()
334
 */
335 336
function entity_page_label(EntityInterface $entity, $langcode = NULL) {
  return $entity->label($langcode);
337 338
}

339 340 341
/**
 * Returns the render array for an entity.
 *
342
 * @param \Drupal\Core\Entity\EntityInterface $entity
343 344 345 346 347 348
 *   The entity to be rendered.
 * @param string $view_mode
 *   The view mode that should be used to display the entity.
 * @param string $langcode
 *   (optional) For which language the entity should be rendered, defaults to
 *   the current content language.
349 350 351
 * @param bool $reset
 *   (optional) Whether to reset the render cache for the requested entity.
 *   Defaults to FALSE.
352 353 354
 *
 * @return array
 *   A render array for the entity.
355 356 357 358
 *
 * @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0.
 *   Use the entity view builder's view() method for creating a render array:
 * @code
359 360
 * $view_builder = \Drupal::entityTypeManager()
 *   ->getViewBuilder($entity->getEntityTypeId());
361 362 363
 * return $view_builder->view($entity, $view_mode, $langcode);
 * @endcode
 *
364
 * @see \Drupal\Core\Entity\EntityTypeManagerInterface::getViewBuilder()
365
 * @see \Drupal\Core\Entity\EntityViewBuilderInterface::view()
366
 */
367
function entity_view(EntityInterface $entity, $view_mode, $langcode = NULL, $reset = FALSE) {
368
  $render_controller = \Drupal::entityManager()->getViewBuilder($entity->getEntityTypeId());
369
  if ($reset) {
370
    $render_controller->resetCache([$entity]);
371 372
  }
  return $render_controller->view($entity, $view_mode, $langcode);
373 374 375 376 377
}

/**
 * Returns the render array for the provided entities.
 *
378
 * @param \Drupal\Core\Entity\EntityInterface[] $entities
379 380 381 382 383 384
 *   The entities to be rendered, must be of the same type.
 * @param string $view_mode
 *   The view mode that should be used to display the entity.
 * @param string $langcode
 *   (optional) For which language the entity should be rendered, defaults to
 *   the current content language.
385 386 387
 * @param bool $reset
 *   (optional) Whether to reset the render cache for the requested entities.
 *   Defaults to FALSE.
388 389 390 391
 *
 * @return array
 *   A render array for the entities, indexed by the same keys as the
 *   entities array passed in $entities.
392 393 394 395 396
 *
 * @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0.
 *   Use the entity view builder's viewMultiple() method for creating a render
 *   array for the provided entities:
 * @code
397 398
 * $view_builder = \Drupal::entityTypeManager()
 *   ->getViewBuilder($entity->getEntityTypeId());
399 400 401
 * return $view_builder->viewMultiple($entities, $view_mode, $langcode);
 * @endcode
 *
402
 * @see \Drupal\Core\Entity\EntityTypeManagerInterface::getViewBuilder()
403
 * @see \Drupal\Core\Entity\EntityViewBuilderInterface::viewMultiple()
404
 */
405
function entity_view_multiple(array $entities, $view_mode, $langcode = NULL, $reset = FALSE) {
406
  $render_controller = \Drupal::entityManager()->getViewBuilder(reset($entities)->getEntityTypeId());
407
  if ($reset) {
408
    $render_controller->resetCache($entities);
409 410
  }
  return $render_controller->viewMultiple($entities, $view_mode, $langcode);
411
}
412

413
/**
414
 * Returns the entity view display associated with a bundle and view mode.
415 416 417 418 419 420
 *
 * Use this function when assigning suggested display options for a component
 * in a given view mode. Note that they will only be actually used at render
 * time if the view mode itself is configured to use dedicated display settings
 * for the bundle; if not, the 'default' display is used instead.
 *
421 422 423 424 425
 * The function reads the entity view display from the current configuration, or
 * returns a ready-to-use empty one if configuration entry exists yet for this
 * bundle and view mode. This streamlines manipulation of display objects by
 * always returning a consistent object that reflects the current state of the
 * configuration.
426 427 428 429 430
 *
 * Example usage:
 * - Set the 'body' field to be displayed and the 'field_image' field to be
 *   hidden on article nodes in the 'default' display.
 * @code
431
 * entity_get_display('node', 'article', 'default')
432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
 *   ->setComponent('body', array(
 *     'type' => 'text_summary_or_trimmed',
 *     'settings' => array('trim_length' => '200')
 *     'weight' => 1,
 *   ))
 *   ->removeComponent('field_image')
 *   ->save();
 * @endcode
 *
 * @param string $entity_type
 *   The entity type.
 * @param string $bundle
 *   The bundle.
 * @param string $view_mode
 *   The view mode, or 'default' to retrieve the 'default' display object for
 *   this bundle.
 *
449
 * @return \Drupal\Core\Entity\Display\EntityViewDisplayInterface
450
 *   The entity view display associated with the view mode.
451 452 453
 *
 * @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0.
 *   If the display is available in configuration use:
454
 *   @code
455 456 457
 *   \Drupal::entityTypeManager()
 *     ->getStorage('entity_view_display')
 *     ->load($entity_type . '.' . $bundle . '.' . $view_mode);
458
 *   @endcode
459 460
 *   When the display is not available in configuration, you can create a new
 *   EntityViewDisplay object using:
461 462 463 464 465 466
 *   @code
 *   $values = array(
 *     'targetEntityType' => $entity_type,
 *     'bundle' => $bundle,
 *     'mode' => $view_mode,
 *     'status' => TRUE,
467
 *   );
468 469 470
 *   \Drupal::entityTypeManager()
 *     ->getStorage('entity_view_display')
 *     ->create($values);
471
 *   @endcode
472 473 474
 *
 * @see \Drupal\Core\Entity\EntityStorageInterface::create()
 * @see \Drupal\Core\Entity\EntityStorageInterface::load()
475 476 477
 */
function entity_get_display($entity_type, $bundle, $view_mode) {
  // Try loading the display from configuration.
478
  $display = EntityViewDisplay::load($entity_type . '.' . $bundle . '.' . $view_mode);
479 480

  // If not found, create a fresh display object. We do not preemptively create
481 482 483 484
  // new entity_view_display configuration entries for each existing entity type
  // and bundle whenever a new view mode becomes available. Instead,
  // configuration entries are only created when a display object is explicitly
  // configured and saved.
485
  if (!$display) {
486
    $display = EntityViewDisplay::create(array(
487 488
      'targetEntityType' => $entity_type,
      'bundle' => $bundle,
489
      'mode' => $view_mode,
490
      'status' => TRUE,
491 492 493 494 495 496
    ));
  }

  return $display;
}

497
/**
498
 * Returns the entity form display associated with a bundle and form mode.
499
 *
500 501
 * The function reads the entity form display object from the current
 * configuration, or returns a ready-to-use empty one if no configuration entry
502
 * exists yet for this bundle and form mode. This streamlines manipulation of
503 504
 * entity form displays by always returning a consistent object that reflects
 * the current state of the configuration.
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528
 *
 * Example usage:
 * - Set the 'body' field to be displayed with the 'text_textarea_with_summary'
 *   widget and the 'field_image' field to be hidden on article nodes in the
 *  'default' form mode.
 * @code
 * entity_get_form_display('node', 'article', 'default')
 *   ->setComponent('body', array(
 *     'type' => 'text_textarea_with_summary',
 *     'weight' => 1,
 *   ))
 *   ->setComponent('field_image', array(
 *     'type' => 'hidden',
 *   ))
 *   ->save();
 * @endcode
 *
 * @param string $entity_type
 *   The entity type.
 * @param string $bundle
 *   The bundle.
 * @param string $form_mode
 *   The form mode.
 *
529
 * @return \Drupal\Core\Entity\Display\EntityFormDisplayInterface
530
 *   The entity form display associated with the given form mode.
531 532 533 534
 *
 * @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0.
 *   If the entity form display is available in configuration use:
 * @code
535 536 537
 *   \Drupal::entityTypeManager()
 *     ->getStorage('entity_form_display')
 *     ->load($entity_type . '.' . $bundle . '.' . $form_mode);
538
 * @endcode
539 540
 *   When the entity form display is not available in configuration, you can
 *   create a new EntityFormDisplay object using:
541 542 543 544 545 546 547
 * @code
 * $values = ('entity_form_display', array(
 *  'targetEntityType' => $entity_type,
 *  'bundle' => $bundle,
 *  'mode' => $form_mode,
 *  'status' => TRUE,
 * ));
548 549 550
 * \Drupal::entityTypeManager()
 *   ->getStorage('entity_form_display')
 *   ->create($values);
551 552 553 554
 * @endcode
 *
 * @see \Drupal\Core\Entity\EntityStorageInterface::create()
 * @see \Drupal\Core\Entity\EntityStorageInterface::load()
555 556 557
 */
function entity_get_form_display($entity_type, $bundle, $form_mode) {
  // Try loading the entity from configuration.
558
  $entity_form_display = EntityFormDisplay::load($entity_type . '.' . $bundle . '.' . $form_mode);
559 560

  // If not found, create a fresh entity object. We do not preemptively create
561
  // new entity form display configuration entries for each existing entity type
562
  // and bundle whenever a new form mode becomes available. Instead,
563
  // configuration entries are only created when an entity form display is
564 565
  // explicitly configured and saved.
  if (!$entity_form_display) {
566
    $entity_form_display = EntityFormDisplay::create(array(
567 568 569
      'targetEntityType' => $entity_type,
      'bundle' => $bundle,
      'mode' => $form_mode,
570
      'status' => TRUE,
571 572 573 574 575
    ));
  }

  return $entity_form_display;
}