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 are no @label yet.', ['@label' => $this->entityType->getPluralLabel()]), '#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()]); } }