entity_references_map-1.0.0-alpha2/src/EntityReferencesMapBuilder.php

src/EntityReferencesMapBuilder.php
<?php

namespace Drupal\entity_references_map;

use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\entity_references_map\Form\MapForm;
use Drupal\node\NodeInterface;

/**
 * Provides list builder for ER fields structure.
 */
class EntityReferencesMapBuilder implements EntityReferencesMapBuilderInterface {

  use StringTranslationTrait;

  /**
   * Config Factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected ConfigFactoryInterface $configFactory;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Constructs EntityReferencesMapBuilder instance.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The ConfigFactory.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   */
  public function __construct(ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager) {
    $this->configFactory = $config_factory;
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   */
  public function build(NodeInterface $node): array {
    // Initialize main variables.
    $node_type = $node->getType();
    $config_data = $this->configFactory->get(MapForm::CONFIG_NAME)->get();
    // Return empty array if the config is empty or necessary node_type key
    // doesn't exist. We can't build the tree structure without this data.
    if (empty($config_data) || empty($config_data[$node_type])) {
      return [];
    }
    $forward_reference_fields = $config_data[$node_type]['forward_reference'];
    // Build Node tree main wrapper.
    $tree = $this->createMapWrapper($node_type, $this->t('The @node_type_label', ['@node_type_label' => node_get_type_label($node)]), $node->getTitle());
    // Loop through forward reference fields and build appropriate array for
    // jHtree library.
    foreach ($forward_reference_fields as $field_path) {
      [
        $entity_type,
        $node_type,
        $field_machine_name,
      ] = explode('.', $field_path);

      // Need to ensure that the reference entity type from the field isn't in
      // the excluded list.
      /** @var \Drupal\field\Entity\FieldStorageConfig $field_config */
      $field_config = $this->entityTypeManager
        ->getStorage('field_storage_config')
        ->load("{$entity_type}.{$field_machine_name}");
      if (in_array($field_config->getSettings()['target_type'], $config_data['excluded_entity_types'] ?? [])) {
        continue;
      }
      // We need to be sure that this field exists, and it is not empty.
      // Otherwise, there is not much sense to loop through them.
      if ($node->hasField($field_machine_name) && !$node->get($field_machine_name)
        ->isEmpty()) {
        $referenced_entities = $node->get($field_machine_name)
          ->referencedEntities();
        $header_color = NestedArray::getValue($config_data, [
          'node',
          $node_type,
          $field_machine_name,
          'header_color',
        ]) ?: '#cccccc';

        $content_color = NestedArray::getValue($config_data, [
          'node',
          $node_type,
          $field_machine_name,
          'content_color',
        ]) ?: '#ffffff';
        // Create a "wrapper" for the field. We need this due to the jHtree
        // features.
        $field_group = $this->createMapWrapper(
          implode('-', [
            $entity_type,
            $node_type,
            str_replace('_', '-', $field_machine_name),
          ]),
          $node->get($field_machine_name)->getFieldDefinition()->getLabel(),
          $field_machine_name,
          $header_color,
          $content_color,
        );
        $nested_levels = NestedArray::getValue($config_data, [
          $entity_type,
          $node_type,
          $field_machine_name,
          'nested_levels',
        ]);
        // Safely loop through field values (we always get an array). We need
        // this data for proper entity-linking of map elements.
        foreach ($referenced_entities as $referenced_entity) {
          $nested_levels_parameters = NestedArray::getValue($config_data, [
            $entity_type,
            $node_type,
            $field_machine_name,
            $nested_levels,
          ]);
          if (($nested_levels === 'all')
          && !empty($childs = $this->createChildElement($referenced_entity, array_merge($nested_levels_parameters['entity_types'], $config_data['excluded_entity_types']), $nested_levels_parameters['header_color'], $nested_levels_parameters['content_color'], $nested_levels_parameters['levels_depth']))) {
            $field_group['children'][] = array_merge($this->createMapElement(
              $referenced_entity,
              $node,
              $node_type,
              $header_color,
              $content_color,
            ),
              ['children' => $childs]);
          }
          else {
            $field_group['children'][] = $this->createMapElement(
              $referenced_entity,
              $node,
              $node_type,
              $header_color,
              $content_color,
            );
          }
        }
        $tree['children'][] = $field_group;
      }
    }
    return $tree;
  }

  /**
   * {@inheritdoc}
   */
  public function createMapWrapper(string $id,
    string $head,
    string $label,
    string $header_color = '#cccccc',
    string $content_color = '#ffffff'): array {
    return [
      'id' => $id,
      'head' => $head,
      'contents' => $label,
      'head_color' => $header_color,
      'content_color' => $content_color,
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function createMapElement(EntityInterface $entity,
    EntityInterface $parent_entity,
    string $group,
    string $header_color,
    string $content_color,
    bool $forward_reference = TRUE): array {
    try {
      $contents = $entity->toLink(NULL, 'canonical', [
        'attributes' => ['target' => '_blank'],
      ])?->toString();
    }
    catch (\Exception) {
      $contents = $entity->label();
    }
    return [
      'id' => implode('-', [
        $entity->bundle(),
        $entity->id(),
        $parent_entity->id(),
      ]) . ($forward_reference ? '-forward' : '-backward'),
      'head' => $group,
      'head_color' => $header_color,
      'contents' => $contents,
      'content_color' => $content_color,
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function createChildElement(EntityInterface $entity, array $excluded_entity_references, string $header_color, string $content_color, int $max_depth = NULL, int $current_depth = 1): array {
    $children = [];
    $index = 0;
    foreach ($entity->referencedEntities() as $referenced_entity) {
      if (!in_array($referenced_entity->getEntityType()->id(), array_values($excluded_entity_references), TRUE)) {
        $children[] = $this->createMapElement(
          $referenced_entity,
          $entity,
          $entity->bundle(),
          $header_color,
          $content_color,
        );
        if ((empty($max_depth) || $current_depth < $max_depth) && !empty($nested_children = $this->createChildElement($referenced_entity, $excluded_entity_references, $header_color, $content_color, $max_depth, ++$current_depth))) {
          $children[$index]['children'] = $nested_children;
        }
        ++$index;
      }

    }
    return $children;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc