external_entities-8.x-2.x-dev/src/Plugin/ExternalEntities/PropertyMapper/JsonPath.php

src/Plugin/ExternalEntities/PropertyMapper/JsonPath.php
<?php

namespace Drupal\external_entities\Plugin\ExternalEntities\PropertyMapper;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\external_entities\FieldMapper\FieldMapperInterface;
use Drupal\external_entities\PropertyMapper\PropertyMapperBase;
use JsonPath\InvalidJsonException;
use JsonPath\InvalidJsonPathException;
use JsonPath\JsonObject;

/**
 * A field mapper that uses JSONPath expressions.
 *
 * Multi-valued fields should be mapped using JSONPath expressions that result
 * in an array of values being returned.
 *
 * @PropertyMapper(
 *   id = "jsonpath",
 *   label = @Translation("JSONPath"),
 *   description = @Translation("Maps a property to raw data fields based on JSONPath expressions."),
 *   field_properties = {
 *     "*:*"
 *   }
 * )
 */
class JsonPath extends PropertyMapperBase {

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(
    array $form,
    FormStateInterface $form_state,
  ) {
    $form += parent::buildConfigurationForm($form, $form_state);

    $links = [
      Link::fromTextAndUrl(
        $this->t('JSONPath syntax and limitation'),
        Url::fromUri(
          'https://github.com/Galbar/JsonPath-PHP#jsonpath-language'
        )
      ),

      Link::fromTextAndUrl(
        $this->t('JSONPath examples'),
        Url::fromUri(
          'https://support.smartbear.com/alertsite/docs/monitors/api/endpoint/jsonpath.html'
        )
      ),
    ];

    $form['help']['jsonpath'] = [
      '#theme' => 'item_list',
      '#type' => 'ul',
      '#prefix' => '<p>' . $this->t('See these documentation links:') . '</p>',
      '#items' => array_map(function (Link $link) {
        return $link->toRenderable();
      }, $links),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function getMappedSourceFieldName() :?string {
    if ($this->isProcessed()) {
      return NULL;
    }
    $source_field = NULL;
    if (preg_match('/^\$\.(\w+)$/', $this->getConfiguration()['mapping'], $matches)
      || preg_match('/^\$\[[\'"]?(\w+)[\'"]?\]$/', $this->getConfiguration()['mapping'], $matches)
    ) {
      $source_field = $matches[1];
    }
    return $source_field;
  }

  /**
   * {@inheritdoc}
   */
  public function extractPropertyValuesFromRawData(
    array $raw_data,
    array &$context = [],
  ) :array {
    $mapping = $this->getConfiguration()['mapping'] ?? NULL;
    if (empty($mapping)) {
      return [];
    }

    if (empty($context['jsonpath']['object'])) {
      $context['jsonpath']['object'] = new JsonObject($raw_data);
    }
    try {
      $values = $context['jsonpath']['object']->get($mapping) ?: [];
    }
    catch (InvalidJsonException | InvalidJsonPathException $e) {
      $this->logger->warning(
        "Invalid JSONPath: " . $e
      );
      $values = [];
    }
    return $this->processData($values);
  }

  /**
   * {@inheritdoc}
   */
  public function addPropertyValuesToRawData(
    array $property_values,
    array &$raw_data,
    array &$context,
  ) {
    $mapping = $this->getConfiguration()['mapping'] ?? NULL;
    if (empty($mapping)) {
      return;
    }
    // Reverse data processing.
    if (empty($context['jsonpath']['original'])) {
      $context['jsonpath']['original'] = new JsonObject(
        $context[FieldMapperInterface::CONTEXT_SOURCE_KEY] ?? []
      );
    }
    try {
      $original_data =
        $context['jsonpath']['original']->get($mapping)
        ?: [];
    }
    catch (InvalidJsonException | InvalidJsonPathException $e) {
      $this->logger->warning(
        "Invalid JSONPath: " . $e
      );
      $original_data = [];
    }
    $property_values = $this->reverseDataProcessing(
      $property_values,
      $original_data,
    );

    // Prepare JSONPath object on current data.
    if (empty($context['jsonpath']['object'])) {
      $context['jsonpath']['object'] = new JsonObject($raw_data);
    }

    $xntt_type_id = $this->externalEntityType->getDerivedEntityTypeId();
    $field_definition = $this
      ->entityFieldManager
      ->getFieldDefinitions($xntt_type_id, $xntt_type_id)[$this->fieldName]
      ?? NULL;

    if ($field_definition) {
      $field_cardinality = $field_definition
        ->getFieldStorageDefinition()
        ->getCardinality();
    }
    else {
      $field_cardinality = 0;
    }

    // Unwrap the singleton array if the cardinality of the field is 1.
    if ($field_cardinality === 1) {
      $property_values = array_shift($property_values);
    }

    if (isset($property_values)) {
      try {
        $context['jsonpath']['object']->set($mapping, $property_values);
      }
      catch (InvalidJsonPathException $e) {
        $this->logger->warning(
          "Invalid JSONPath: " . $e
        );
      }
    }

    // The JSONPath object holds previous $raw_data with newly added values.
    $raw_data = $context['jsonpath']['object']->getValue();
  }

}

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

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