external_entities-8.x-2.x-dev/src/Serialization/JsonApi.php

src/Serialization/JsonApi.php
<?php

namespace Drupal\external_entities\Serialization;

use Drupal\Component\Serialization\Json;

/**
 * Denormalizes the json:api response.
 *
 * This is handled via a Serialization handler as this is the first opportunity
 * to handle raw responses fetched by the RestClient. Which means the processing
 * applies to _all_ types of requests single & multiple load scenarios.
 *
 * The denormalization is necessary because json:api normalizes data references
 * into the "included" property which is outside the actual data set.
 * However, jsonpath does not provide a sane way to access this included data
 * bits from the result item itself.
 * So this recursive handling will put _all_ included data into each result as
 * well as adds the related included data to the relationships referencing the
 * data.
 * Allowing relative simple jsonPath expressions like:
 * $.relationships.field_taxonomy_terms.data.included.attributes.field_body
 *
 * @todo See if there's any way the existing jsonapi denormalizer can be used:
 * \Drupal\jsonapi\Serializer\Serializer::denormalize().
 */
class JsonApi extends Json {

  /**
   * {@inheritdoc}
   */
  public static function getFileExtension() {
    return 'xnttjson';
  }

  /**
   * Denormalizes the json:api response.
   *
   * @param string $string
   *   The json:api response string.
   *
   * @return mixed
   *   The denormalized data.
   */
  public static function decode($string) {
    $decoded_data = parent::decode($string);

    if (!empty($decoded_data['data']) && !empty($decoded_data['included'])) {
      foreach ($decoded_data['data'] as $i => $result) {
        $decoded_data['data'][$i]['included'] = $decoded_data['included'];
        if (!empty($result['relationships'])) {
          static::resolveRelationships($decoded_data['data'][$i]);
        }
      }
    }

    return $decoded_data;
  }

  /**
   * Resolves relationships by mapping included data.
   *
   * @param array $result
   *   The result item containing relationships and included data.
   */
  protected static function resolveRelationships(array &$result): void {
    // Collect all includes and index them by type and id.
    $includedRegistry = [];
    foreach ($result['included'] as $included_entry) {
      $included_id = ($included_entry['type'] ?? NULL) . ':' . $included_entry['id'];
      $includedRegistry[$included_id] = $included_entry;
    }
    static::resolveRelationsRecursive($result['relationships'], $includedRegistry);
  }

  /**
   * Recursively resolves relationships.
   *
   * @param array $relationships
   *   The relationships to resolve.
   * @param array $includedRegistry
   *   The registry of included data, indexed by type:id.
   */
  private static function resolveRelationsRecursive(
    array &$relationships,
    array $includedRegistry,
  ): void {
    foreach ($relationships as $field => $relationship) {
      if (!empty($relationship['data'])) {
        // Relationships can be single or multi-value.
        if (isset($relationship['data']['id'])) {
          static::mapRelationshipData($relationships[$field]['data'], $includedRegistry);
        }
        else {
          foreach ($relationship['data'] as $i => $data) {
            static::mapRelationshipData($relationships[$field]['data'][$i], $includedRegistry);
          }
        }
      }
    }
  }

  /**
   * Maps the included data to the relationship data.
   *
   * @param array $data
   *   The relationship data.
   * @param array $includedRegistry
   *   The registry of included data, indexed by type:id.
   */
  private static function mapRelationshipData(
    array &$data,
    array $includedRegistry,
  ): void {
    if (isset($data['id'])) {
      $included_id = ($data['type'] ?? NULL) . ':' . $data['id'];
      if (isset($includedRegistry[$included_id])) {
        $data['included'] = $includedRegistry[$included_id];
      }
      if (!empty($data['relationships'])) {
        static::resolveRelationsRecursive($data['relationships'], $includedRegistry);
      }
    }
  }

}

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

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