dvf-2.x-dev/dvf_json/src/Plugin/Visualisation/Source/JsonFile.php

dvf_json/src/Plugin/Visualisation/Source/JsonFile.php
<?php

namespace Drupal\dvf_json\Plugin\Visualisation\Source;

use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\File\FileUrlGeneratorInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\dvf\DvfHelpers;
use Drupal\dvf\Plugin\VisualisationInterface;
use Drupal\dvf\Plugin\Visualisation\Source\VisualisationSourceBase;
use Flow\JSONPath\JSONPath;
use Psr\Log\LoggerInterface;
use GuzzleHttp\Client;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Plugin implementation of the 'dvf_json_file' visualisation source.
 *
 * @VisualisationSource(
 *   id = "dvf_json_file",
 *   label = @Translation("JSON file"),
 *   category = @Translation("JSON"),
 *   visualisation_types = {
 *     "dvf_file",
 *     "dvf_url"
 *   }
 * )
 */
class JsonFile extends VisualisationSourceBase implements ContainerFactoryPluginInterface {

  /**
   * The cache backend.
   *
   * @var \Drupal\Core\Cache\CacheBackendInterface
   */
  protected $cache;

  /**
   * The JSON file fields.
   *
   * @var array
   */
  protected $fields;

  /**
   * The JSON file records.
   *
   * @var array
   */
  protected $records;

  /**
   * DVF Helpers.
   *
   * @var \Drupal\dvf\DvfHelpers
   */
  protected $dvfHelpers;

  /**
   * Constructs a new JsonFile.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\dvf\Plugin\VisualisationInterface $visualisation
   *   The visualisation context in which the plugin will run.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   * @param \Psr\Log\LoggerInterface $logger
   *   Instance of the logger object.
   * @param \GuzzleHttp\Client $http_client
   *   The HTTP client.
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache
   *   The cache backend.
   * @param \Drupal\dvf\DvfHelpers $dvf_helpers
   *   The DVF helpers.
   * @param \Drupal\Core\File\FileUrlGeneratorInterface $file_url_generator
   *   The file URL generator.
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    VisualisationInterface $visualisation = NULL,
    ModuleHandlerInterface $module_handler,
    LoggerInterface $logger,
    Client $http_client,
    CacheBackendInterface $cache,
    DvfHelpers $dvf_helpers,
    FileUrlGeneratorInterface $file_url_generator
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $visualisation, $module_handler, $logger, $http_client, $file_url_generator);
    $this->cache = $cache;
    $this->dvfHelpers = $dvf_helpers;
  }

  /**
   * Creates an instance of the plugin.
   *
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   The container to pull out services used in the plugin.
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin ID for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\dvf\Plugin\VisualisationInterface $visualisation
   *   The visualisation context in which the plugin will run.
   *
   * @return static
   *   Returns an instance of this plugin.
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, VisualisationInterface $visualisation = NULL) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $visualisation,
      $container->get('module_handler'),
      $container->get('logger.channel.dvf'),
      $container->get('http_client'),
      $container->get('cache.dvf_json'),
      $container->get('dvf.helpers'),
      $container->get('file_url_generator')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return [
      'json' => [
        'expression' => '$[*]',
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state) {
    $form['json'] = [
      '#type' => 'details',
      '#title' => $this->t('JSON file settings'),
      '#open' => TRUE,
      '#tree' => TRUE,
    ];

    $form['json']['expression'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Expression'),
      '#description' => $this->t('JSONPath expression used to extract the data. Default is $[*] which represents the root of the document. Visit the <a href="https://github.com/govCMS/dvf/tree/8.x-1.x/dvf_json">online documentation</a> for more information on how to use JSONPath expressions.'),
      '#default_value' => $this->config('json', 'expression'),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function getFields() {
    // Retrieves the fields available in the data provided by the source.
    $fields = [];
    $data = $this->getData();

    if (is_array($data) && !empty($data)) {
      $fields = array_keys(array_shift($data));
      $fields = array_combine($fields, $fields);
    }

    return $fields;
  }

  /**
   * {@inheritdoc}
   */
  public function getRecords() {
    $records = [];

    // Retrieves and structures records based on the configured JSON expression.
    try {
      $json = new JSONPath($this->getData());
      $json = $json->find($this->config('json', 'expression'));
    }
    catch (\Exception $e) {
      $this->messenger()->addError('Unable to parse JSON file');
      $this->logger->error($this->t('Error parsing JSON file :error',
        [':error' => $e->getMessage()]));
      return $records;
    }

    // Loop through each field defined by getFields(), associating the field
    // labels with their corresponding values in the parsed JSON. The resulting
    // records are stored in the $records array, organized by record ID.
    foreach ($this->getFields() as $field_key => $field_label) {
      foreach ($json->getData() as $record_id => $record) {
        if (!isset($records[$record_id])) {
          $records[$record_id] = new \stdClass();
        }
        $records[$record_id]->{$field_label} = array_key_exists($field_key, $record) ? $record[$field_key] : '';
      }
    }

    return $records;
  }

  /**
   * Returns the JSON data.
   *
   * @return array
   *   An array of JSON records.
   */
  public function getData() {
    $cache_key = $this->getCacheKey();
    $cache_object = $this->cache->get($cache_key);

    // Retrieves data, either from cache or by fetching it and caching it.
    if (is_object($cache_object)) {
      $data = $cache_object->data;
    }
    else {
      $data = $this->fetchData();
      $this->cache->set($cache_key, $data, $this->getCacheExpiry());
    }

    return json_decode($data, TRUE);
  }

  /**
   * Fetches the JSON data.
   * It also validates the retrieved data returns NULL if there any errors.
   *
   * @return string
   *   A string containing the JSON file data.
   */
  protected function fetchData() {
    try {
      $uri = $this->config('uri');
      $response = $this->getContentFromUri($uri);
    }
    catch (\Exception $e) {
      $this->messenger()->addError('Unable to read JSON');
      $this->logger->error($this->t('Error reading JSON file :error',
        [':error' => $e->getMessage()]));
      $response = NULL;
    }

    $data = '{}';

    if ($response) {
      if (!$this->dvfHelpers->validateJson($response)) {
        $this->messenger()->addError('Invalid JSON file provided');
        $this->logger->error($this->t('Unable to parse this json file :url',
          [':url' => $uri]));
      }
      $data = $response;
    }

    return $data;
  }

  /**
   * Gets a cache key for this plugin.
   *
   * @return string
   *   The cache key.
   */
  protected function getCacheKey() {
    $plugin_id = hash('sha256', $this->getPluginId());
    $uri = $this->config('uri');

    return $plugin_id . ':' . $uri;
  }

}

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

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