entity_hierarchy-8.x-2.24/entity_hierarchy.module
entity_hierarchy.module
<?php /** * @file * A module to make entities hierarchical. */ use Drupal\Core\Entity\ContentEntityDeleteForm; use Drupal\Core\Entity\ContentEntityForm; use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\ContentEntityType; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\entity_hierarchy\Form\HierarchyChildrenForm; use Drupal\entity_hierarchy\Handler\EntityHierarchyHandler; use Drupal\entity_hierarchy\Handler\NodeEntityHierarchyHandler; use Drupal\entity_hierarchy\Information\ChildEntityWarningBuilder; use Drupal\entity_hierarchy\Routing\EntityHierarchyRouteProvider; use Drupal\entity_hierarchy\Storage\ParentEntityDeleteUpdater; use Drupal\entity_hierarchy\Storage\ParentEntityRevisionUpdater; use Drupal\field\FieldConfigInterface; /** * Implements @see hook_help(). */ function entity_hierarchy_help($route_name, RouteMatchInterface $route_match) { switch ($route_name) { case 'help.page.entity_hierarchy': return t('A module to create hierarchical entities. To get started, add a field of type <em>Entity Reference Hierarchy</em> to your entity to keep track of parents.'); } } /** * Implements @see hook_entity_type_build(). * * @see \Drupal\entity_hierarchy\Form\HierarchyChildrenForm */ function entity_hierarchy_entity_type_build(array &$entity_types) { /** @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types */ // Adds the entity_hierarchy_reorder link template. foreach ($entity_types as $entity_type_id => $entity_type) { if (!$entity_type instanceof ContentEntityType || !$entity_type->hasLinkTemplate('canonical')) { continue; } $providers = $entity_type->getRouteProviderClasses() ?: []; if (empty($providers['entity_hierarchy'])) { $providers['entity_hierarchy'] = EntityHierarchyRouteProvider::class; $entity_types[$entity_type_id]->setHandlerClass('route_provider', $providers); } // We have to add this for every content entity-type, regardless of if it // has hierarchy fields or not, because you cannot use the field manager // during a hook_entity_type_build, as it will cause recursion. $entity_types[$entity_type_id] ->setFormClass('entity_hierarchy_reorder', HierarchyChildrenForm::class) ->setHandlerClass('entity_hierarchy', EntityHierarchyHandler::class) ->setLinkTemplate('entity_hierarchy_reorder', $entity_type->getLinkTemplate('canonical') . '/children'); } if (isset($entity_types['node'])) { $entity_types['node']->setHandlerClass('entity_hierarchy', NodeEntityHierarchyHandler::class); } } /** * Implements hook_entity_update(). */ function entity_hierarchy_entity_update(EntityInterface $entity) { if (\Drupal::state()->get('entity_hierarchy_disable_writes', FALSE)) { return; } if (!$entity instanceof ContentEntityInterface) { return; } if (isset($entity->original)) { \Drupal::service('class_resolver')->getInstanceFromDefinition(ParentEntityRevisionUpdater::class) ->moveChildren($entity->original, $entity); } } /** * Implements hook_entity_delete(). */ function entity_hierarchy_entity_delete(EntityInterface $entity) { if (!$entity instanceof ContentEntityInterface) { return; } \Drupal::service('class_resolver')->getInstanceFromDefinition(ParentEntityDeleteUpdater::class) ->moveChildren($entity); } /** * Implements hook_form_alter(). */ function entity_hierarchy_form_alter(&$form, FormStateInterface $form_state, $form_id) { $formObject = $form_state->getFormObject(); if ($formObject instanceof ContentEntityDeleteForm) { if ($children = \Drupal::service('class_resolver')->getInstanceFromDefinition(ChildEntityWarningBuilder::class)->buildChildEntityWarnings($formObject->getEntity())) { foreach ($children as $ix => $child) { $form['children'][$ix] = [ 'title' => ['#markup' => '<p>' . $child->getWarning() . '</p>'], 'items' => $child->getList(), ]; } return; } } if ($formObject instanceof ContentEntityForm) { /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ $entity = $formObject->getEntity(); $parentFields = \Drupal::service('entity_field.manager')->getFieldMapByFieldType('entity_reference_hierarchy'); if (isset($parentFields[$entity->getEntityTypeId()])) { // We have a parent field. $requestQuery = \Drupal::request()->query; foreach ($parentFields[$entity->getEntityTypeId()] as $field_name => $detail) { if ( $entity->hasField($field_name) && $requestQuery->has($field_name) && isset($form[$field_name]) && (isset($form[$field_name]['widget'][0]['target_id']['target_id']) || $form[$field_name]['widget'][0]['target_id']['#type'] === 'select') && ($target_entity = \Drupal::entityTypeManager()->getStorage($entity->getEntityTypeId())->load($requestQuery->get($field_name))) && $target_entity->access('view') ) { if ( isset($form[$field_name]['widget'][0]['target_id']['#type']) && $form[$field_name]['widget'][0]['target_id']['#type'] === 'select' ) { $form[$field_name]['widget'][0]['target_id']['#default_value'] = $target_entity->id(); } else { $form[$field_name]['widget'][0]['target_id']['target_id']['#default_value'] = $target_entity; } } } } } } /** * Implements hook_ENTITY_TYPE_insert() for 'field_config'. */ function entity_hierarchy_field_config_insert(FieldConfigInterface $field): void { if ($field->getType() === 'entity_reference_hierarchy') { \Drupal::service('plugin.manager.entity_reference_selection')->clearCachedDefinitions(); } } /** * Implements hook_ENTITY_TYPE_insert() for 'field_config'. */ function entity_hierarchy_field_config_delete(FieldConfigInterface $field): void { if ($field->getType() === 'entity_reference_hierarchy') { \Drupal::service('plugin.manager.entity_reference_selection')->clearCachedDefinitions(); } }