content_entity_base-8.x-1.x-dev/src/Entity/Controller/EntityBaseController.php
src/Entity/Controller/EntityBaseController.php
<?php namespace Drupal\content_entity_base\Entity\Controller; use Drupal\Core\Entity\Controller\EntityController; use Drupal\Core\Entity\EntityRepositoryInterface; use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Link; use Drupal\Core\Render\RendererInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Routing\UrlGeneratorInterface; use Drupal\Core\Routing\UrlGeneratorTrait; use Drupal\Core\StringTranslation\TranslationInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Class EntityBaseController * * @internal This will be removed in a future version as addPage, addTitle and * addBundleTitle are being provided by \Drupal\Core\Entity\Controller\EntityController * in drupal 8.1.x. */ class EntityBaseController extends EntityController { use UrlGeneratorTrait; /** * The entity manager. * * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; /** * The entity type bundle info. * * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface */ protected $entityTypeBundleInfo; /** * The entity repository. * * @var \Drupal\Core\Entity\EntityRepositoryInterface */ protected $entityRepository; /** * The renderer. * * @var \Drupal\Core\Render\RendererInterface */ protected $renderer; /** * Constructs a new EntityController. * * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager. * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info * The entity type bundle info. * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository * The entity repository. * @param \Drupal\Core\Render\RendererInterface $renderer * The renderer. * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation * The string translation. * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator * The url generator. */ public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info, EntityRepositoryInterface $entity_repository, RendererInterface $renderer, TranslationInterface $string_translation, UrlGeneratorInterface $url_generator) { $this->entityTypeManager = $entity_type_manager; $this->entityTypeBundleInfo = $entity_type_bundle_info; $this->entityRepository = $entity_repository; $this->renderer = $renderer; $this->stringTranslation = $string_translation; $this->urlGenerator = $url_generator; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('entity_type.manager'), $container->get('entity_type.bundle.info'), $container->get('entity.repository'), $container->get('renderer'), $container->get('string_translation'), $container->get('url_generator') ); } /** * Displays add links for the available bundles. * * Redirects to the add form if there's only one bundle available. * * @param string $entity_type_id * The entity type ID. * * @return \Symfony\Component\HttpFoundation\RedirectResponse|array * If there's only one available bundle, a redirect response. * Otherwise, a render array with the add links for each bundle. */ public function addPage($entity_type_id) { $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); $bundles = $this->entityTypeBundleInfo->getBundleInfo($entity_type_id); $bundle_key = $entity_type->getKey('bundle'); $bundle_entity_type_id = $entity_type->getBundleEntityType(); $build = [ '#theme' => 'entity_add_list', '#bundle_type' => $bundle_entity_type_id, '#bundles' => [], ]; if ($bundle_entity_type_id) { $bundle_argument = $bundle_entity_type_id; $bundle_entity_type = $this->entityTypeManager->getDefinition($bundle_entity_type_id); $bundle_entity_type_label = $bundle_entity_type->getLowercaseLabel(); $build['#cache']['tags'] = $bundle_entity_type->getListCacheTags(); // Build the message shown when there are no bundles. $link_text = $this->t('Add a new @entity_type.', ['@entity_type' => $bundle_entity_type_label]); $link_route_name = 'entity.' . $bundle_entity_type->id() . '.add_form'; $build['#add_bundle_message'] = $this->t('There is no @entity_type yet. @add_link', [ '@entity_type' => $bundle_entity_type_label, '@add_link' => Link::createFromRoute($link_text, $link_route_name)->toString(), ]); // Filter out the bundles the user doesn't have access to. $access_control_handler = $this->entityTypeManager->getAccessControlHandler($entity_type_id); foreach ($bundles as $bundle_name => $bundle_info) { $access = $access_control_handler->createAccess($bundle_name, NULL, [], TRUE); if (!$access->isAllowed()) { unset($bundles[$bundle_name]); } $this->renderer->addCacheableDependency($build, $access); } // Add descriptions from the bundle entities. $bundles = $this->loadBundleDescriptions($bundles, $bundle_entity_type); } else { $bundle_argument = $bundle_key; } $form_route_name = 'entity.' . $entity_type_id . '.add_form'; // Redirect if there's only one bundle available. if (count($bundles) == 1) { $bundle_names = array_keys($bundles); $bundle_name = reset($bundle_names); return $this->redirect($form_route_name, [$bundle_argument => $bundle_name]); } // Prepare the #bundles array for the template. foreach ($bundles as $bundle_name => $bundle_info) { $build['#bundles'][$bundle_name] = [ 'label' => $bundle_info['label'], 'description' => isset($bundle_info['description']) ? $bundle_info['description'] : '', 'add_link' => Link::createFromRoute($bundle_info['label'], $form_route_name, [$bundle_argument => $bundle_name]), ]; } return $build; } /** * Provides a generic add title callback for an entity type. * * @param string $entity_type_id * The entity type ID. * * @return string * The title for the entity add page. */ public function addTitle($entity_type_id) { $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); return $this->t('Add @entity-type', ['@entity-type' => $entity_type->getLowercaseLabel()]); } /** * Provides a generic add title callback for entities with bundles. * * @param \Drupal\Core\Routing\RouteMatchInterface $route_match * The route match. * @param string $entity_type_id * The entity type ID. * @param string $bundle_parameter * The name of the route parameter that holds the bundle. * * @return string * The title for the entity add page, if the bundle was found. */ public function addBundleTitle(RouteMatchInterface $route_match, $entity_type_id, $bundle_parameter) { $bundles = $this->entityTypeBundleInfo->getBundleInfo($entity_type_id); // If the entity has bundle entities, the parameter might have been upcasted // so fetch the raw parameter. $bundle = $route_match->getRawParameter($bundle_parameter); if ((count($bundles) > 1) && isset($bundles[$bundle])) { return $this->t('Add @bundle', ['@bundle' => $bundles[$bundle]['label']]); } // If the entity supports bundles generally, but only has a single bundle, // the bundle is probably something like 'Default' so that it preferable to // use the entity type label. else { return $this->addTitle($entity_type_id); } } /** * Expands the bundle information with descriptions, if known. * * @param array $bundles * An array of bundle information. * @param \Drupal\Core\Entity\EntityTypeInterface $bundle_entity_type * The ID of the bundle entity type. * * @return array * The expanded array of bundle information. */ protected function loadBundleDescriptions(array $bundles, EntityTypeInterface $bundle_entity_type) { if (!$bundle_entity_type->isSubclassOf('\Drupal\Core\Entity\EntityDescriptionInterface')) { return $bundles; } $bundle_names = array_keys($bundles); $storage = $this->entityTypeManager->getStorage($bundle_entity_type->id()); /** @var \Drupal\Core\Entity\EntityDescriptionInterface[] $bundle_entities */ $bundle_entities = $storage->loadMultiple($bundle_names); foreach ($bundles as $bundle_name => &$bundle_info) { if (isset($bundle_entities[$bundle_name])) { $bundle_info['description'] = $bundle_entities[$bundle_name]->getDescription(); } } return $bundles; } }