entity_generic-8.x-3.x-dev/entity_generic.module
entity_generic.module
<?php use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Render\Element; use Drupal\Core\Url; use Drupal\Core\Cache\Cache; use Drupal\Core\Link; use Drupal\entity_generic\Entity\BasicInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\ContentEntityTypeInterface; /** * Implements hook_theme(). */ function entity_generic_theme() { return array( 'entity_generic' => array( 'render element' => 'elements', ), ); } /** * Implements hook_entity_type_build(). * @param array $entity_types */ function entity_generic_entity_type_build(array &$entity_types) { /** @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */ foreach ($entity_types as $entity_type_id => &$entity_type) { // Check if the entity type has an 'entity_generic' mark. if (isset($entity_type->get('additional')['entity_generic']) && $entity_type instanceof ContentEntityTypeInterface) { $handlers = $entity_type->getHandlerClasses(); $links = $entity_type->getLinkTemplates(); // Add multiple delete possibility. if (!isset($handlers['form']['delete-multiple-confirm'])) { $handlers['form']['delete-multiple-confirm'] = 'Drupal\entity_generic\Form\GenericDeleteMultipleForm'; } if (!isset($links['delete-multiple-form']) && isset($links['collection'])) { $entity_type->setLinkTemplate('delete-multiple-form', $links['collection'] . '/delete'); } // Add multiple merge possibility. if (!isset($handlers['form']['merge-multiple-confirm'])) { $handlers['form']['merge-multiple-confirm'] = 'Drupal\entity_generic\Form\GenericMergeMultipleForm'; } if (!isset($links['merge-multiple-form']) && isset($links['collection'])) { $entity_type->setLinkTemplate('merge-multiple-form', $links['collection'] . '/merge'); } $entity_type->setHandlerClass('form', $handlers['form']); } } } /** * Helper function returns all "entity_generic" entity types. */ function entity_generic_types() { $entity_generic_types = &drupal_static(__FUNCTION__, []); if (!$entity_generic_types) { $entity_generic_types = []; $cid = 'entity_generic:types'; if ($cache = \Drupal::cache()->get($cid)) { $entity_generic_types = $cache->data; } else { $types = \Drupal::entityTypeManager()->getDefinitions(); foreach($types as $type) { if (isset($type->get('additional')['entity_generic'])) { $entity_generic_types[$type->id()] = $type; } } \Drupal::cache()->set($cid, $entity_generic_types, Cache::PERMANENT, ['entity_generic', 'entity_generic_types']); } } return $entity_generic_types; } /** * Checks whether the current page is the full page view of the passed-in entity. * * @param \Drupal\entity_generic\Entity\BasicInterface $entity * An entity. * * @return int|false * The ID of the entity if this is a full page view, otherwise FALSE. */ function entity_generic_is_page(BasicInterface $entity) { $route_match = \Drupal::routeMatch(); if ($route_match->getRouteName() == 'entity.'.$entity->getEntityTypeId().'.canonical') { $page_entity = $route_match->getParameter($entity->getEntityTypeId()); } return (!empty($page_entity) ? $page_entity->id() == $entity->id() : FALSE); } /** * Helper function to check if the entity is generic. * * @param $entity * * @return bool */ function entity_generic_is_generic(EntityInterface $entity) { return array_key_exists($entity->getEntityTypeId(), entity_generic_types()); } /** * Implements hook_entity_view_alter(). * * @param array $build * @param \Drupal\Core\Entity\EntityInterface $entity * @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display */ function entity_generic_entity_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) { // Generalize the entity-type-specific defaults for easier default theming. if ($entity instanceof BasicInterface) { $app_root = \Drupal::getContainer()->getParameter('app.root'); $file_path = $app_root . '/' . \Drupal::service('extension.list.module')->getPath($entity->getEntityType()->getProvider()) . '/templates/entity-generic--' . strtr($entity->getEntityTypeId(), '_', '-') . '.html.twig'; if (file_exists($file_path)) { $build['#theme'] = 'entity_generic__' . $entity->getEntityTypeId(); } $build['#entity_generic'] = $entity; } } /** * Alters suggestions for generic entities to add additional variants of templates. * Implements hook_theme_suggestions_HOOK_alter(). * * @param array $suggestions * @param array $variables */ function entity_generic_theme_suggestions_entity_generic_alter(array &$suggestions, array $variables) { /** @var \Drupal\entity_generic\Entity\BasicInterface $entity */ $entity = $variables['elements']['#entity_generic']; $sanitized_view_mode = 'vm-' . strtr($variables['elements']['#view_mode'], '.', '_'); $suggestions[] = 'entity_generic__' . $entity->getEntityTypeId(); $suggestions[] = 'entity_generic__' . $entity->getEntityTypeId() . '__' . $sanitized_view_mode; $suggestions[] = 'entity_generic__' . $entity->getEntityTypeId() . '__' . $entity->bundle(); $suggestions[] = 'entity_generic__' . $entity->getEntityTypeId() . '__' . $entity->bundle() . '__' . $sanitized_view_mode; $suggestions[] = 'entity_generic__' . $entity->getEntityTypeId() . '__' . $entity->id(); $suggestions[] = 'entity_generic__' . $entity->getEntityTypeId() . '__' . $entity->id() . '__' . $sanitized_view_mode; } /** * Alter the theme registry to add templates for existing generic entities. * Implements hook_theme_registry_alter(). * * @see hook_theme() * @see \Drupal\Core\Theme\Registry::processExtension() */ function entity_generic_theme_registry_alter(&$theme_registry) { $app_root = \Drupal::getContainer()->getParameter('app.root'); foreach (entity_generic_types() as $type => $definition) { $file_path = $app_root . '/' . \Drupal::service('extension.list.module')->getPath($definition->getProvider()) . '/templates/entity-generic--' . strtr($type, '_', '-') . '.html.twig'; if (file_exists($file_path)) { $theme_registry['entity_generic__' . $type] = [ 'path' => \Drupal::service('extension.list.module')->getPath($definition->getProvider()) . '/templates', 'preprocess functions' => [ 'template_preprocess', 'template_preprocess_entity_generic', 'template_preprocess_entity_generic__' . $type, ], 'render element' => 'elements', 'template' => 'entity-generic--' . strtr($type, '_', '-'), 'theme path' => \Drupal::service('extension.list.module')->getPath($definition->getProvider()), 'type' => 'module', ]; } } } /** * Prepares variables for list of available entity type templates. * * Default template: entity-generic-add-list.html.twig. * * @param array $variables * An associative array containing: * - content: An array of entity types. */ function template_preprocess_entity_generic_add_list(&$variables) { $variables['types'] = array(); if (!empty($variables['bundles'])) { foreach ($variables['bundles'] as $bundle) { $variables['types'][$bundle->id()] = array( 'label' => $bundle->id(), 'add_link' => Link::fromTextAndUrl($bundle->label(), new Url('entity.' .$variables['entity_type'] . '.add_form', array($bundle->getEntityTypeId() => $bundle->id()))), 'description' => array( '#markup' => $bundle->getDescription(), ), ); } } } /** * Prepares variables for entity templates. * Default template: entity-generic.html.twig. * * @param array $variables * An associative array containing: * - elements: An array of elements to display in view mode. * - entity: The entity object. * - view_mode: View mode; e.g., 'full', 'teaser', etc. */ function template_preprocess_entity_generic(&$variables) { // View mode. $variables['view_mode'] = $variables['elements']['#view_mode']; // Generic entity. $variables['entity_generic'] = $variables['elements']['#entity_generic']; // Entity type and bundle. $variables['entity_type'] = $variables['entity_generic']->getEntityTypeId(); $variables['bundle'] = $variables['entity_generic']->bundle(); // The 'page' variable is set to TRUE in two occasions: // - The view mode is 'full' or 'default' and we are on the 'entity.view' route. $variables['page'] = entity_generic_is_page($variables['entity_generic']) && $variables['view_mode'] == 'full'; // Entity label. if ($variables['page']) { $variables['label'] = $variables['entity_generic']->label(); } // Build the $content variable for templates. $variables += ['content' => []]; foreach (Element::children($variables['elements']) as $key) { $variables['content'][$key] = $variables['elements'][$key]; } // Add article ARIA role. $variables['attributes']['role'] = 'article'; }