gatsby_endpoints-8.x-1.0-alpha1/src/GatsbyEndpointGenerator.php

src/GatsbyEndpointGenerator.php
<?php

namespace Drupal\gatsby_endpoints;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\gatsby_endpoints\Entity\GatsbyEndpointInterface;

/**
 * Class GatsbyEndpointGenerator.
 *
 * Generates JSON:API links for a Gatsby Endpoint.
 */
class GatsbyEndpointGenerator {

  /**
   * Drupal\Core\Entity\EntityTypeManagerInterface definition.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Drupal\Core\Entity\EntityFieldManagerInterface definition.
   *
   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
   */
  protected $entityFieldManager;

  /**
   * Constructs a new GatsbyEndpointManager object.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager,
      EntityFieldManagerInterface $entity_field_manager) {
    $this->entityTypeManager = $entity_type_manager;
    $this->entityFieldManager = $entity_field_manager;
  }

  /**
   * Generates JSON:API links for a specific Gatsby Endpoint.
   */
  public function getEndpointLinks(GatsbyEndpointInterface $endpoint) {
    $build_types = $endpoint->getBuildEntityTypes();
    $links = [];

    foreach ($build_types as $build_type) {
      if (empty($build_type) || empty($build_type['entity_type'])) {
        continue;
      }

      $include_types = $endpoint->getIncludedEntityTypes($build_type);

      // Check if this has bundles.
      foreach ($build_type['entity_bundles'] as $bundle_id => $bundle_label) {
        if ($bundle_label === $bundle_id) {
          $params = $this->getUrlParameters($build_type['entity_type'], $bundle_id, $endpoint, $include_types);
          $entity_key = $build_type['entity_type'] . '--' . $bundle_id;
          $links[$entity_key] = $build_type['entity_type'] . '/' . $bundle_id . $params;
        }
      }

    }

    return $links;
  }

  /**
   * Gets the correct JSON:API url parameters string.
   */
  private function getUrlParameters($entity_type, $bundle, GatsbyEndpointInterface $endpoint, $include_types) {
    $url_params = $this->loadUrlFiltersAndIncludes($entity_type,
      $bundle, $endpoint, $include_types);

    $param_string = '';

    if (!empty($url_params['filter'])) {
      $param_string .= $url_params['filter'] . '&';
    }

    if (!empty($url_params['include'])) {
      $param_string .= 'include=' . implode(',', $url_params['include']);
    }

    // Add the starting "?" if parameters are needed.
    return $param_string ? '?' . $param_string : $param_string;
  }

  /**
   * Gets the includes and filter parameters for a JSON:API url.
   */
  private function loadUrlFiltersAndIncludes($entity_type, $bundle, GatsbyEndpointInterface $endpoint, $include_types, $current_field = FALSE) {
    $definitions = $this->entityFieldManager->getFieldDefinitions($entity_type, $bundle);
    $core_reference_fields = ['comments', 'file', 'image'];
    $params = [];

    // Images are a special kind of file, so make sure include_types
    // include images if they have files added. Without this core image fields
    // will not work.
    if (in_array('file', $include_types)) {
      $include_types[] = 'image';
    }

    foreach ($definitions as $field) {
      $field_name = $field->getName();

      // Only check manually created fields.
      if (empty($field_name) || !$field instanceof FieldConfig) {
        continue;
      }

      $field_type = $field->getType();
      if ($field_type == 'gatsby_endpoint_reference') {
        $params['filter'] = 'filter[' . $field_name . '.meta.drupal_internal__target_id]=' . $endpoint->id();
      }
      elseif (in_array($field_type, $core_reference_fields)) {

        // Check if this field references an included entity type.
        if (in_array($field_type, $include_types)) {
          if ($current_field) {
            $field_name = $current_field . '.' . $field_name;
          }
          $params['include'][] = $field_name;
        }
      }
      elseif (in_array($field_type, [
        'entity_reference',
        'entity_reference_revisions',
      ])) {
        // Check if this field references an included entity type.
        $handler = $field->getSetting('handler');
        $reference_type = explode(':', $handler);
        if (!empty($reference_type[1]) && in_array($reference_type[1], $include_types)) {
          // Continue building out the JSON:API path to this related field.
          if ($current_field) {
            $field_name = $current_field . '.' . $field_name;
          }
          $params['include'][] = $field_name;

          // Now we need to recursively traverse this reference field to ensure
          // to include all the necessary related entity fields.
          $handler_settings = $field->getSetting('handler_settings');
          if (!empty($handler_settings['target_bundles'])) {
            foreach ($handler_settings['target_bundles'] as $target_bundle) {
              $reference_params = $this->loadUrlFiltersAndIncludes($reference_type[1],
                $target_bundle,
                $endpoint,
                $include_types,
                $field_name);

              if (!empty($reference_params['include'])) {
                $params['include'] = array_merge($params['include'], $reference_params['include']);
              }
            }
          }
        }
      }
    }

    return $params;
  }

}

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

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