filefield_sources_jsonapi-8.x-1.0-beta9/src/Form/ModalBrowserForm.php

src/Form/ModalBrowserForm.php
<?php

namespace Drupal\filefield_sources_jsonapi\Form;

use Drupal\Core\Form\FormBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Component\Utility\Html;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CloseModalDialogCommand;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Form\FormStateInterface;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\filefield_sources_jsonapi\Entity\FileFieldSourcesJSONAPI;
use GuzzleHttp\Client;
use Drupal\Core\Url;

/**
 * Implements the ModalBrowserForm form controller.
 */
class ModalBrowserForm extends FormBase {

  /**
   * Entity form display storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $entityFormDisplayStorage;

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

  /**
   * {@inheritdoc}
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager'),
      $container->get('entity_field.manager')
    );
  }

  /**
   * BulkMediaUploadForm constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   Entity type manager.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entityFieldManager
   *   Entity field manager.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function __construct(
    EntityTypeManagerInterface $entityTypeManager,
    EntityFieldManagerInterface $entityFieldManager
  ) {
    $this->entityFormDisplayStorage = $entityTypeManager->getStorage('entity_form_display');
    $this->entityFieldManager = $entityFieldManager;
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'filefield_sources_jsonapi_browser_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, $entity_type = NULL, $bundle = NULL, $form_mode = NULL, $field_name = NULL, $wrapper = '') {
    static $settings;

    $form['#attached']['library'][] = 'filefield_sources_jsonapi/modal';
    $form['#prefix'] = '<div id="filefield-sources-jsonapi-browser-form">';
    $form['#suffix'] = '</div>';

    if ($form_state->get('fetched_file') && $form_state->get('form_type') === 'insert') {
      return $this->buildInsertForm($form, $form_state);
    }

    $user_input = $form_state->getUserInput();

    /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display */
    $display = $this->entityFormDisplayStorage->load($entity_type . '.' . $bundle . '.' . $form_mode);
    $field_widget_settings = $display->getComponent($field_name);

    if (!$settings) {
      $settings = $field_widget_settings['third_party_settings']['filefield_sources']['filefield_sources']['source_remote_jsonapi'];
    }
    $settings['sources'] = FileFieldSourcesJSONAPI::getSettingsOptionList($settings['sources']);
    $settings['field_name'] = $field_name;
    $settings['wrapper'] = $wrapper;

    $settings['type'] = $field_widget_settings['type'];
    // @todo Refactor.
    if ('image_widget_crop' === $settings['type']) {
      $settings['type'] = 'image_image';
    }

    $settings['cardinality'] = FieldStorageConfig::loadByName($entity_type, $field_name)
      ->getCardinality();
    $field_settings = $this->entityFieldManager->getFieldDefinitions($entity_type, $bundle)[$field_name]->getSettings();
    $settings['field_settings'] = $field_settings;

    $actual_config = $settings['actual_config'] ?? NULL;
    if (isset($user_input['type'])) {
      $actual_config = FileFieldSourcesJSONAPI::load($user_input['type']);
    }
    if (!$actual_config) {
      $actual_config_id = array_keys($settings['sources'])[0];
      $actual_config = FileFieldSourcesJSONAPI::load($actual_config_id);
    }

    if ($sort_option_list = trim($actual_config->getSortOptionList())) {
      foreach (explode("\n", $sort_option_list) as $sort_option) {
        [$key, $label] = explode('|', $sort_option);
        $settings['sort_options'][$key] = $label;
      }
    }

    if ($search_filter = trim($actual_config->getSearchFilter())) {
      $settings['search_filter'] = explode(",", $search_filter);
    }

    $settings['actual_config'] = $actual_config;
    $form_state->set('jsonapi_settings', $settings);

    $rest_api_url = $actual_config->getApiUrl();
    $query = $this->bulidJsonApiQuery($actual_config);

    $page = $form_state->get('page');
    if ($page === NULL) {
      $form_state->set('page', 0);
      $page = 0;
    }
    $query['page[limit]'] = $actual_config->getItemsPerPage();
    $query['page[offset]'] = $page * $query['page[limit]'];

    // Add browser form data to JSON API query.
    if (!empty($settings['search_filter']) && isset($user_input['name']) && !empty($user_input['name'])) {
      $query['filter[or-group][group][conjunction]'] = 'OR';
      foreach ($settings['search_filter'] as $delta => $field_path) {
        $filterName = 'filter-' . $delta;
        $query['filter[' . $filterName . '][condition][path]'] = $field_path;
        $query['filter[' . $filterName . '][condition][operator]'] = 'CONTAINS';
        $query['filter[' . $filterName . '][condition][value]'] = $user_input['name'];
        $query['filter[' . $filterName . '][condition][memberOf]'] = 'or-group';
      }
    }
    if (isset($user_input['sort']) && !empty($user_input['sort'])) {
      $query['sort'] = $user_input['sort'];
    }
    else {
      if (isset($settings['sort_options'])) {
        $sort = array_keys($settings['sort_options']);
        $query['sort'] = reset($sort);
      }
    }

    $query_str = UrlHelper::buildQuery($query);
    $rest_api_url = $rest_api_url . '?' . $query_str;

    $response = $this->getJsonApiCall($rest_api_url);
    if (200 === $response->getStatusCode()) {
      $response = json_decode($response->getBody());
      $form['filefield_filesources_jsonapi_form'] = $this->renderFormElements($response, $form_state);
    }

    return $form;
  }

  /**
   * Builds the insert form.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   *
   * @return array
   *   The render array defining the elements of the form.
   */
  public function buildInsertForm(array &$form, FormStateInterface $form_state) {
    $file = $form_state->get('fetched_file');
    $settings = $form_state->get('jsonapi_settings');
    /** @var \Drupal\filefield_sources_jsonapi\FileFieldSourcesJSONAPIInterface $actual_config */
    $actual_config = $settings['actual_config'];
    $basic_auth = $actual_config->getBasicAuthentication();

    $form['title'] = [
      '#type' => 'item',
      '#title' => $this->t('Insert selected'),
    ];

    $form['wrapper'] = [
      '#type' => 'container',
      '#attributes' => ['class' => ['insert-wrapper']],
    ];
    if ($file['thumbnail_url']) {
      if ($basic_auth) {
        $uri = Url::fromRoute('filefield_sources_jsonapi.get_remote_file', ['url' => $file['thumbnail_url']])->toString();
      }
      else {
        $uri = $file['thumbnail_url'];
      }
      $form['wrapper']['image'] = [
        '#theme' => 'image',
        '#uri' => $uri,
        '#width' => '400',
      ];
    }
    $form['wrapper']['detail'] = [
      '#type' => 'container',
      '#attributes' => ['class' => ['details-wrapper']],
    ];
    if (isset($settings['field_settings']['title_field']) && $settings['field_settings']['title_field']) {
      $form['wrapper']['detail']['title'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Title'),
        '#default_value' => $file['title'],
        '#required' => $settings['field_settings']['title_field_required'] ? TRUE : FALSE,
      ];
    }
    if (isset($settings['field_settings']['alt_field']) && $settings['field_settings']['alt_field']) {
      $form['wrapper']['detail']['alt'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Alt'),
        '#default_value' => $file['alt'],
        '#required' => $settings['field_settings']['alt_field_required'] ? TRUE : FALSE,
      ];
    }
    if (isset($settings['field_settings']['description_field']) && $settings['field_settings']['description_field']) {
      $form['wrapper']['detail']['description'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Description'),
        '#default_value' => $file['title'],
      ];
    }

    $form['actions'] = [
      '#type' => 'actions',
    ];

    $form['actions']['cancel'] = [
      '#type' => 'submit',
      '#value' => $this->t('Cancel'),
      '#submit' => ['::cancelSelectedSubmit'],
      '#ajax' => [
        'callback' => '::ajaxInsertCallback',
        'wrapper' => 'filefield-sources-jsonapi-browser-form',
      ],
      '#attributes' => ['class' => ['cancel-button']],
      '#weight' => 1,
    ];

    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#name' => 'insert',
      '#value' => $this->t('Insert'),
      '#ajax' => [
        'callback' => '::ajaxSubmitForm',
        'event' => 'click',
      ],
      '#attributes' => ['class' => ['insert-button']],
      '#weight' => 2,
    ];

    return $form;
  }

  /**
   * Provides custom submission handler for change form to insert.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   */
  public function insertSelectedSubmit(array &$form, FormStateInterface $form_state) {
    $form_state
      ->set('form_type', 'insert')
      ->setRebuild(TRUE);
  }

  /**
   * Provides custom submission handler for change form to basic.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   */
  public function cancelSelectedSubmit(array &$form, FormStateInterface $form_state) {
    $form_state
      ->set('form_type', 'form')
      ->setRebuild(TRUE);
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    if ($form_state->getTriggeringElement()['#name'] === 'insert_selected' && isset($form_state->getUserInput()['media_id_select'])) {
      $selected_media = array_values(array_filter($form_state->getUserInput()['media_id_select']));

      $file = NULL;
      if ($media_id = $selected_media[0]) {
        $settings = $form_state->get('jsonapi_settings');

        $rest_api_url = $settings['actual_config']->getApiUrl() . '/' . $media_id;
        $query = $this->bulidJsonApiQuery($settings['actual_config']);
        $query_str = UrlHelper::buildQuery($query);
        $rest_api_url = $rest_api_url . '?' . $query_str;

        $response = $this->getJsonApiCall($rest_api_url);
        if (200 === $response->getStatusCode()) {
          $response = json_decode($response->getBody());
          $api_url_base = $this->getApiBaseUrl($settings['actual_config']->getApiUrl());
          $file['url'] = $this->getJsonApiDatabyPath($response, $settings['actual_config']->getUrlAttributePath());
          if (!UrlHelper::isExternal($file['url'])) {
            $file['url'] = $api_url_base . $file['url'];
          }
          if ('image_image' === $settings['type']) {
            $file['thumbnail_url'] = $file['url'];
          }
          else {
            $file['thumbnail_url'] = $this->getJsonApiDatabyPath($response, $settings['actual_config']->getThumbnailUrlAttributePath());
            if (!empty($file['thumbnail_url']) && !UrlHelper::isExternal($file['thumbnail_url'])) {
              $file['thumbnail_url'] = $api_url_base . $file['thumbnail_url'];
            }
            else {
              $file['thumbnail_url'] = $file['url'];
            }
          }
          if ($alt_attribute_path = $settings['actual_config']->getAltAttributePath()) {
            $file['alt'] = $this->getJsonApiDatabyPath($response, $alt_attribute_path);
          }
          if ($title_attribute_path = $settings['actual_config']->getTitleAttributePath()) {
            $file['title'] = $this->getJsonApiDatabyPath($response, $title_attribute_path);
          }
        }

        if (!isset($file['url']) || !curl_init($file['url'])) {
          $form_state->setErrorByName('', $this->t("Can't fetch file from remote server."));
          $this->getLogger('filefield_sources_jsonapi')->warning("Can't fetch file (@url) from remote server.", ['@url' => $file['url']]);
        }
        $form_state->set('fetched_file', $file);
      }
      else {
        $form_state->setErrorByName('', $this->t("No file was selected."));
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
  }

  /**
   * Implements the filter submit handler for the ajax call.
   */
  public function ajaxSubmitFilterForm(array &$form, FormStateInterface $form_state) {
    $form_state->set('page', 0);
    $form_state->setRebuild();
  }

  /**
   * Implements the pager submit handler for the ajax call.
   */
  public function ajaxSubmitPagerNext(array &$form, FormStateInterface $form_state) {
    $page = $form_state->get('page');
    $form_state->set('page', ($page + 1));
    $form_state->setRebuild();
  }

  /**
   * Implements the pager submit handler for the ajax call.
   */
  public function ajaxSubmitPagerPrev(array &$form, FormStateInterface $form_state) {
    $page = $form_state->get('page');
    $form_state->set('page', ($page - 1));
    $form_state->setRebuild();
  }

  /**
   * Implements the pager submit handler for the ajax call.
   */
  public function ajaxPagerCallback(array &$form, FormStateInterface $form_state) {
    return $form['filefield_filesources_jsonapi_form']['lister'];
  }

  /**
   * Implements the insert submit handler for the ajax call.
   */
  public function ajaxInsertCallback(array &$form, FormStateInterface $form_state) {
    return $form;
  }

  /**
   * Implements the submit handler for the ajax call.
   *
   * @param array $form
   *   Render array representing from.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   Current form state.
   *
   * @return \Drupal\Core\Ajax\AjaxResponse
   *   Array of ajax commands to execute on submit of the modal form.
   */
  public function ajaxSubmitForm(array &$form, FormStateInterface $form_state) {
    $settings = $form_state->get('jsonapi_settings');
    $actual_config = $settings['actual_config'];

    // We begin building a new ajax response.
    $response = new AjaxResponse();
    if ($form_state->getErrors()) {
      unset($form['#prefix'], $form['#suffix']);
      $form['status_messages'] = [
        '#type' => 'status_messages',
        '#weight' => -10,
      ];
      $response->addCommand(new HtmlCommand('#filefield-sources-jsonapi-browser-form', $form));
    }
    else {
      $user_input = $form_state->getUserInput();
      $settings = $form_state->get('jsonapi_settings');
      $wrapper = $settings['wrapper'] ? $settings['wrapper'] . '-' : '';
      $selector = '.field--name-' . Html::getClass($settings['field_name']) . "[data-drupal-selector='edit-" . $wrapper . Html::getClass($settings['field_name']) . "-wrapper'] .filefield-source-remote_jsonapi";
      $file = $form_state->get('fetched_file');
      $response->addCommand(new InvokeCommand($selector . " input[name$='[filefield_remote_jsonapi][url]']", 'val', [$file['url']]));
      if (isset($user_input['alt'])) {
        $response->addCommand(new InvokeCommand($selector . " input[name$='[filefield_remote_jsonapi][alt]']", 'val', [$user_input['alt']]));
      }
      if (isset($user_input['title'])) {
        $response->addCommand(new InvokeCommand($selector . " input[name$='[filefield_remote_jsonapi][title]']", 'val', [$user_input['title']]));
      }
      if (isset($user_input['description'])) {
        $response->addCommand(new InvokeCommand($selector . " input[name$='[filefield_remote_jsonapi][description]']", 'val', [$user_input['description']]));
      }
      $response->addCommand(new InvokeCommand($selector . " input[name$='[filefield_remote_jsonapi][source]']", 'val', [$actual_config->id()]));
      $response->addCommand(new InvokeCommand($selector . " input[type=submit]", 'mousedown'));
      $response->addCommand(new CloseModalDialogCommand());
    }
    return $response;
  }

  /**
   * Render form elements.
   */
  private function renderFormElements($response, FormStateInterface $form_state) {
    $settings = $form_state->get('jsonapi_settings');
    /** @var \Drupal\filefield_sources_jsonapi\FileFieldSourcesJSONAPIInterface $actual_config */
    $actual_config = $settings['actual_config'];
    $api_url_base = $this->getApiBaseUrl($actual_config->getApiUrl());
    $basic_auth = $actual_config->getBasicAuthentication();

    $render = [];
    $render['top'] = [
      '#type' => 'container',
      '#attributes' => [
        'id' => 'filefield_filesources_jsonapi_top',
        'class' => ['browser-top'],
      ],
    ];
    if ((!empty($settings['sources']) && count($settings['sources'])) > 1
      || (!empty($settings['sort_options']) && count($settings['sort_options']) > 1)
      || !empty($settings['search_filter'])) {
      $render['top']['filter'] = [
        '#type' => 'container',
        '#attributes' => [
          'id' => 'filefield_filesources_jsonapi_filter',
          'class' => ['browser-filter', 'inline'],
        ],
      ];
      if (!empty($settings['sources']) && count($settings['sources']) > 1) {
        $render['top']['filter']['type'] = [
          '#title' => $this->t('Type'),
          '#type' => 'select',
          '#options' => $settings['sources'],
          '#attributes' => ['class' => ['type', 'inline']],
          '#submit' => ['::ajaxSubmitFilterForm'],
          '#ajax' => [
            'callback' => '::ajaxPagerCallback',
            'wrapper' => 'filefield_filesources_jsonapi_lister',
          ],
        ];
      }
      if (!empty($settings['sort_options'])) {
        $render['top']['filter']['sort'] = [
          '#title' => $this->t('Sort'),
          '#type' => 'select',
          '#options' => $settings['sort_options'],
          '#attributes' => ['class' => ['sort-by', 'inline']],
          '#submit' => ['::ajaxSubmitFilterForm'],
          '#ajax' => [
            'callback' => '::ajaxPagerCallback',
            'wrapper' => 'filefield_filesources_jsonapi_lister',
          ],
        ];
        if (count($settings['sort_options']) < 2) {
          $render['top']['filter']['sort']['#printed'] = TRUE;
        }
      }
      if (!empty($settings['search_filter'])) {
        $render['top']['filter']['name'] = [
          '#type' => 'textfield',
          '#attributes' => [
            'class' => ['file-name'],
            'placeholder' => $this->t('Search'),
          ],
        ];
        $render['top']['filter']['submit'] = [
          '#type' => 'submit',
          '#value' => $this->t('Apply'),
          '#limit_validation_errors' => [],
          '#submit' => ['::ajaxSubmitFilterForm'],
          '#ajax' => [
            'callback' => '::ajaxPagerCallback',
            'wrapper' => 'filefield_filesources_jsonapi_lister',
          ],
          '#attributes' => ['class' => ['visually-hidden']],
        ];
      }
    }

    // If cardinality is 1, don't render submit button - autosubmit on select.
    $render['top']['action'] = [
      '#type' => 'container',
      '#attributes' => [
        'id' => 'filefield_filesources_jsonapi_action',
        'class' => ['browser-action'],
      ],
    ];
    $render['top']['action']['submit'] = [
      '#type' => 'submit',
      '#name' => 'insert_selected',
      '#value' => $this->t('Insert selected'),
      '#submit' => ['::insertSelectedSubmit'],
      '#ajax' => [
        'callback' => '::ajaxSubmitForm',
        'wrapper' => 'filefield-sources-jsonapi-browser-form',
      ],
      '#attributes' => ['class' => ['insert-button', 'visually-hidden']],
    ];
    // Navigate to 2nd step if there are alt/title/description field enabled.
    if (('image_image' === $settings['type'] && ($settings['field_settings']['alt_field'] || $settings['field_settings']['title_field']))
      || (isset($settings['field_settings']['description_field']) && $settings['field_settings']['description_field'])) {
      $render['top']['action']['submit']['#ajax']['callback'] = '::ajaxInsertCallback';
    }

    $render['lister'] = [
      '#type' => 'container',
      '#attributes' => ['class' => ['browser-lister']],
      '#prefix' => '<div id="filefield_filesources_jsonapi_lister">',
      '#suffix' => '</div>',
    ];

    $render['lister']['media'] = [
      '#type' => 'container',
      '#attributes' => ['class' => ['media-lister']],
    ];
    foreach ($response->data as $data) {
      $media_id = $data->id;
      $thumbnail_url_attribute_path = $actual_config->getThumbnailUrlAttributePath() ?: $actual_config->getUrlAttributePath();
      $thumbnail_url = $this->getJsonApiDatabyPath($response, $thumbnail_url_attribute_path, $data);
      if ($media_id && $thumbnail_url) {
        $render['lister']['media'][$media_id] = [
          '#type' => 'container',
          '#attributes' => ['class' => ['media-row']],
        ];
        $checkbox = [
          '#type' => 'checkbox',
          '#title' => $this->t('Select this item'),
          '#title_display' => 'invisible',
          '#return_value' => $media_id,
          '#id' => $media_id,
          '#attributes' => ['name' => "media_id_select[$media_id]"],
          '#default_value' => NULL,
        ];
        // Auto trigger on cardinality 1 - doesn't work.
        if ($settings['cardinality'] === 1) {
          $checkbox['#ajax'] = [
            'trigger_as' => ['name' => 'insert_selected'],
            'callback' => '::ajaxInsertCallback',
            'wrapper' => 'filefield-sources-jsonapi-browser-form',
            'event' => 'click',
          ];
        }
        if ($basic_auth) {
          $url = UrlHelper::isExternal($thumbnail_url) ? $thumbnail_url : $api_url_base . $thumbnail_url;
          $uri = Url::fromRoute('filefield_sources_jsonapi.get_remote_file', ['url' => $url])->toString();
        }
        else {
          $uri = UrlHelper::isExternal($thumbnail_url) ? $thumbnail_url : $api_url_base . $thumbnail_url;
        }
        $img = [
          '#theme' => 'image',
          '#uri' => $uri,
          '#width' => '120',
        ];
        $render['lister']['media'][$media_id]['media_id'] = [
          '#theme' => 'browser_media_box',
          '#checkbox' => $checkbox,
          '#checkbox_id' => $media_id,
          '#img' => $img,
          '#title' => $this->getJsonApiDatabyPath($response, $actual_config->getTitleAttributePath(), $data),
        ];
      }
    }
    if (empty($response->data)) {
      $render['lister']['media']['empty'] = [
        '#markup' => $this->t('No results.'),
        '#attributes' => ['class' => ['no-result']],
      ];
    }

    // Add navigation buttons.
    if (isset($response->links->prev)) {
      $render['lister']['prev'] = [
        '#type' => 'submit',
        '#value' => $this->t('« Prev'),
        '#limit_validation_errors' => [],
        '#submit' => ['::ajaxSubmitPagerPrev'],
        '#ajax' => [
          'callback' => '::ajaxPagerCallback',
          'wrapper' => 'filefield_filesources_jsonapi_lister',
        ],
      ];
    }
    if (isset($response->links->next)) {
      $render['lister']['next'] = [
        '#type' => 'submit',
        '#value' => $this->t('Next »'),
        '#limit_validation_errors' => [],
        '#submit' => ['::ajaxSubmitPagerNext'],
        '#ajax' => [
          'callback' => '::ajaxPagerCallback',
          'wrapper' => 'filefield_filesources_jsonapi_lister',
        ],
      ];
    }

    return $render;
  }

  /**
   * Helper function to get base url of api uri.
   */
  private function getApiBaseUrl($url) {
    $api_url_parsed = parse_url($url);

    $api_url_base = $api_url_parsed['scheme'] . '://' . $api_url_parsed['host'] . (isset($api_url_parsed['port']) ? ':' . $api_url_parsed['port'] : '');

    return $api_url_base;
  }

  /**
   * Build JSON API query based on settings.
   */
  private function bulidJsonApiQuery($config) {
    foreach (explode("\n", trim($config->getParams())) as $param) {
      [$key, $value] = explode('|', $param);
      if (preg_match('/(.*)\[\]$/', $key, $matches)) {
        $key = $matches[1];
        $query[$key][] = trim($value);
      }
      else {
        $query[$key] = trim($value);
      }
    }
    return $query;
  }

  /**
   * Do JSON API call with $rest_api_url.
   *
   * @param string $rest_api_url
   *   Url with query params.
   *
   * @return mixed
   *   JSON API response.
   */
  private function getJsonApiCall($rest_api_url) {
    $client = new Client();
    $myConfig = $this->configFactory()->get('filefield_sources_jsonapi');
    $username = $myConfig->get('username');
    $password = $myConfig->get('password');

    $response = $client->get($rest_api_url, [
      'headers' => ['Authorization' => 'Basic ' . base64_encode("$username:$password")],
    ]);

    return $response;
  }

  /**
   * Get data from JSON API response by path.
   *
   * @param object $response
   *   Full JSON API response with data, included.
   * @param string $pathString
   *   Attribute's path string, e.g.:
   *   data->attributes->title
   *   data->attributes->field_image->attributes->data->url.
   * @param object $data
   *   Actual response data - optional.
   *
   * @return mixed
   *   Data from JSON API response.
   */
  public function getJsonApiDatabyPath($response, $pathString, $data = NULL) {
    if (!empty($data)) {
      $attribute_data = $data;
      $pathString = preg_replace('/^data->/', '', $pathString);
    }
    else {
      $attribute_data = $response;
    }
    $value = NULL;
    if (FALSE !== strpos($pathString, '->included->')) {
      [$data_path, $included_path] = explode('->included->', $pathString);
    }
    else {
      $data_path = $pathString;
      $included_path = NULL;
    }
    foreach (explode('->', $data_path) as $property) {
      if (isset($attribute_data->{$property})) {
        $attribute_data = $attribute_data->{$property};
      }
      else {
        $attribute_data = NULL;
      }
    }
    if (!empty($included_path)) {
      foreach ($response->included as $included) {
        $included_data = $included;
        if ($attribute_data->data->type === $included->type && $attribute_data->data->id === $included->id) {
          foreach (explode('->', $included_path) as $property) {
            $included_data = $included_data->{$property};
          }
          $value = $included_data;
          break;
        }
      }
    }
    else {
      $value = $attribute_data;
    }

    return $value;
  }

}

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

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