collection-8.x-1.x-dev/src/Controller/CollectionNew.php
src/Controller/CollectionNew.php
<?php
namespace Drupal\collection\Controller;
use Drupal\collection\Entity\CollectionInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Link;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Routing\RouteProviderInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
/**
* Controller class for the add content to collection route.
*/
class CollectionNew extends ControllerBase implements ContainerInjectionInterface {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The entity type bundle info.
*
* @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
*/
protected $entityTypeBundleInfo;
/**
* The entity repository service.
*
* @var \Drupal\Core\Entity\EntityRepositoryInterface
*/
protected $entityRepository;
/**
* The renderer service.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/**
* The route provider service.
*
* @var \Drupal\Core\Routing\RouteProviderInterface
*/
protected $routeProvider;
/**
* Constructs a NodeController object.
*
* @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 service.
* @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
* The route provider service.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info, EntityRepositoryInterface $entity_repository, RendererInterface $renderer, RouteProviderInterface $route_provider) {
$this->entityTypeManager = $entity_type_manager;
$this->entityTypeBundleInfo = $entity_type_bundle_info;
$this->entityRepository = $entity_repository;
$this->renderer = $renderer;
$this->routeProvider = $route_provider;
}
/**
* {@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('router.route_provider'),
);
}
/**
* Displays add content links for available content entities.
*
* @todo Redirect to [entity_type]/add/[type] if only one option is available.
*
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse
* A render array for a list of the entity_type/bundles that can be added;
* however, if there is only one node type defined for the site, the function
* will return a RedirectResponse to the add page for that one
* entity_type/bundle.
*/
public function content(CollectionInterface $collection, Request $request) {
$all_bundle_info = $this->entityTypeBundleInfo->getAllBundleInfo();
$collection_item_type_storage = $this->entityTypeManager->getStorage('collection_item_type');
$build = [];
$entity_type_groups = [];
foreach ($collection->type->entity->getAllowedCollectionItemTypes() as $allowed_collection_item_type) {
$collection_item_type = $collection_item_type_storage->load($allowed_collection_item_type);
foreach ($collection_item_type->getAllowedBundles() as $allowed_bundle) {
list($entity_type_id, $bundle) = explode('.', $allowed_bundle);
$entity_type_groups[$entity_type_id][$bundle] = $all_bundle_info[$entity_type_id][$bundle];
}
}
foreach ($entity_type_groups as $entity_type_id => $allowed_bundle_infos) {
$entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
$bundle_key = $entity_type->getKey('bundle');
$bundle_entity_type_id = $entity_type->getBundleEntityType();
$access_control_handler = $this->entityTypeManager->getAccessControlHandler($entity_type_id);
$build[$entity_type_id] = [
'label' => [
'#markup' => '<h3>' . $entity_type->getLabel() . '</h3>',
],
'bundles' => [
'#theme' => 'entity_add_list__collection_' . $collection->type->entity->id() . '_new_' . $entity_type_id,
'#collection' => $collection,
'#bundles' => [],
],
];
foreach ($allowed_bundle_infos as $bundle => $bundle_info) {
if ($entity_type_id === 'node') {
$form_route_name = 'node.add';
}
elseif ($entity_type_id === 'user') {
$form_route_name = 'user.admin_create';
}
else {
$form_route_name = 'entity.' . $entity_type_id . '.add_form';
}
// Skip the bundles the user doesn't have access to.
$access = $access_control_handler->createAccess($bundle, NULL, [], TRUE);
if (!$access->isAllowed()) {
continue;
}
$this->renderer->addCacheableDependency($build, $access);
$bundle_argument = $bundle_entity_type_id ?? $bundle_key;
try {
// Check the route name to see if it exists. If not, an exception will
// be thrown.
$this->routeProvider->getRouteByName($form_route_name);
}
catch (RouteNotFoundException $e) {
continue;
}
$build[$entity_type_id]['bundles']['#bundles'][$bundle] = [
'label' => $bundle_info['label'],
'description' => $bundle_info['description'] ?? '',
'add_link' => Link::createFromRoute($bundle_info['label'], $form_route_name, [$bundle_argument => $bundle], [
'query' => ['collection' => $collection->id()]
]),
];
}
if (empty($build[$entity_type_id]['bundles']['#bundles'])) {
unset($build[$entity_type_id]);
}
}
return $build;
}
/**
* Provides an add title callback for add content to collection page.
*
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The route match.
*
* @return string
* The title for the entity add page, if the bundle was found.
*/
public function addTitle(RouteMatchInterface $route_match) {
$collection = $route_match->getParameter('collection');
return $this->t('Add content to @collection', [
'@collection' => $collection->label(),
]);
}
}
