123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- <?php
- namespace Drupal\Core\Entity;
- use Drupal\Core\Routing\RedirectDestinationTrait;
- use Drupal\Core\Url;
- use Symfony\Component\DependencyInjection\ContainerInterface;
- /**
- * Defines a generic implementation to build a listing of entities.
- *
- * @ingroup entity_api
- */
- class EntityListBuilder extends EntityHandlerBase implements EntityListBuilderInterface, EntityHandlerInterface {
- use RedirectDestinationTrait;
- /**
- * The entity storage class.
- *
- * @var \Drupal\Core\Entity\EntityStorageInterface
- */
- protected $storage;
- /**
- * The entity type ID.
- *
- * @var string
- */
- protected $entityTypeId;
- /**
- * Information about the entity type.
- *
- * @var \Drupal\Core\Entity\EntityTypeInterface
- */
- protected $entityType;
- /**
- * The number of entities to list per page, or FALSE to list all entities.
- *
- * For example, set this to FALSE if the list uses client-side filters that
- * require all entities to be listed (like the views overview).
- *
- * @var int|false
- */
- protected $limit = 50;
- /**
- * {@inheritdoc}
- */
- public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
- return new static(
- $entity_type,
- $container->get('entity.manager')->getStorage($entity_type->id())
- );
- }
- /**
- * Constructs a new EntityListBuilder object.
- *
- * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
- * The entity type definition.
- * @param \Drupal\Core\Entity\EntityStorageInterface $storage
- * The entity storage class.
- */
- public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage) {
- $this->entityTypeId = $entity_type->id();
- $this->storage = $storage;
- $this->entityType = $entity_type;
- }
- /**
- * {@inheritdoc}
- */
- public function getStorage() {
- return $this->storage;
- }
- /**
- * {@inheritdoc}
- */
- public function load() {
- $entity_ids = $this->getEntityIds();
- return $this->storage->loadMultiple($entity_ids);
- }
- /**
- * Loads entity IDs using a pager sorted by the entity id.
- *
- * @return array
- * An array of entity IDs.
- */
- protected function getEntityIds() {
- $query = $this->getStorage()->getQuery()
- ->sort($this->entityType->getKey('id'));
- // Only add the pager if a limit is specified.
- if ($this->limit) {
- $query->pager($this->limit);
- }
- return $query->execute();
- }
- /**
- * Gets the label of an entity.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity being listed.
- *
- * @return string
- * The entity label.
- *
- * @deprecated in Drupal 8.0.x, will be removed before Drupal 9.0.0
- * Use $entity->label() instead. This method used to escape the entity
- * label. The render system's autoescape is now relied upon.
- */
- protected function getLabel(EntityInterface $entity) {
- return $entity->label();
- }
- /**
- * {@inheritdoc}
- */
- public function getOperations(EntityInterface $entity) {
- $operations = $this->getDefaultOperations($entity);
- $operations += $this->moduleHandler()->invokeAll('entity_operation', [$entity]);
- $this->moduleHandler->alter('entity_operation', $operations, $entity);
- uasort($operations, '\Drupal\Component\Utility\SortArray::sortByWeightElement');
- return $operations;
- }
- /**
- * Gets this list's default operations.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity the operations are for.
- *
- * @return array
- * The array structure is identical to the return value of
- * self::getOperations().
- */
- protected function getDefaultOperations(EntityInterface $entity) {
- $operations = [];
- if ($entity->access('update') && $entity->hasLinkTemplate('edit-form')) {
- $operations['edit'] = [
- 'title' => $this->t('Edit'),
- 'weight' => 10,
- 'url' => $this->ensureDestination($entity->toUrl('edit-form')),
- ];
- }
- if ($entity->access('delete') && $entity->hasLinkTemplate('delete-form')) {
- $operations['delete'] = [
- 'title' => $this->t('Delete'),
- 'weight' => 100,
- 'url' => $this->ensureDestination($entity->toUrl('delete-form')),
- ];
- }
- return $operations;
- }
- /**
- * Builds the header row for the entity listing.
- *
- * @return array
- * A render array structure of header strings.
- *
- * @see \Drupal\Core\Entity\EntityListBuilder::render()
- */
- public function buildHeader() {
- $row['operations'] = $this->t('Operations');
- return $row;
- }
- /**
- * Builds a row for an entity in the entity listing.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity for this row of the list.
- *
- * @return array
- * A render array structure of fields for this entity.
- *
- * @see \Drupal\Core\Entity\EntityListBuilder::render()
- */
- public function buildRow(EntityInterface $entity) {
- $row['operations']['data'] = $this->buildOperations($entity);
- return $row;
- }
- /**
- * Builds a renderable list of operation links for the entity.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity on which the linked operations will be performed.
- *
- * @return array
- * A renderable array of operation links.
- *
- * @see \Drupal\Core\Entity\EntityListBuilder::buildRow()
- */
- public function buildOperations(EntityInterface $entity) {
- $build = [
- '#type' => 'operations',
- '#links' => $this->getOperations($entity),
- ];
- return $build;
- }
- /**
- * {@inheritdoc}
- *
- * Builds the entity listing as renderable array for table.html.twig.
- *
- * @todo Add a link to add a new item to the #empty text.
- */
- public function render() {
- $build['table'] = [
- '#type' => 'table',
- '#header' => $this->buildHeader(),
- '#title' => $this->getTitle(),
- '#rows' => [],
- '#empty' => $this->t('There is no @label yet.', ['@label' => $this->entityType->getLabel()]),
- '#cache' => [
- 'contexts' => $this->entityType->getListCacheContexts(),
- 'tags' => $this->entityType->getListCacheTags(),
- ],
- ];
- foreach ($this->load() as $entity) {
- if ($row = $this->buildRow($entity)) {
- $build['table']['#rows'][$entity->id()] = $row;
- }
- }
- // Only add the pager if a limit is specified.
- if ($this->limit) {
- $build['pager'] = [
- '#type' => 'pager',
- ];
- }
- return $build;
- }
- /**
- * Gets the title of the page.
- */
- protected function getTitle() {
- return;
- }
- /**
- * Ensures that a destination is present on the given URL.
- *
- * @param \Drupal\Core\Url $url
- * The URL object to which the destination should be added.
- *
- * @return \Drupal\Core\Url
- * The updated URL object.
- */
- protected function ensureDestination(Url $url) {
- return $url->mergeOptions(['query' => $this->getRedirectDestination()->getAsArray()]);
- }
- }
|