google_json_api-1.0.0-rc2/src/Plugin/Search/GoogleJsonApiSearch.php

src/Plugin/Search/GoogleJsonApiSearch.php
<?php

namespace Drupal\google_json_api\Plugin\Search;

use Drupal\Core\Utility\Token;
use Drupal\Core\Pager\PagerManagerInterface;
use Drupal\Core\Url;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\search\Plugin\ConfigurableSearchPluginBase;
use Drupal\search\SearchPageRepositoryInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

/**
 * Handles searching for node entities using the Search module index.
 *
 * @SearchPlugin(
 *   id = "google_json_api_search",
 *   title = @Translation("Google JSON API Search")
 * )
 */
class GoogleJsonApiSearch extends ConfigurableSearchPluginBase {

  /**
   * Config Factory Service.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * Guzzle HTTP client.
   *
   * @var \Guzzle\Client
   */
  protected $httpClient;

  /**
   * Search Page Repository Service.
   *
   * @var \Drupal\search\SearchPageRepositoryInterface
   */
  private $searchPageRepository;

  /**
   * RequestStack object for getting requests.
   *
   * @var \Symfony\Component\HttpFoundation\RequestStack
   */
  private $requestStack;

  /**
   * The token service.
   *
   * @var \Drupal\Core\Utility\Token
   */
  private $tokenManager;

  /**
   * PagerManager service object.
   *
   * @var \Drupal\Core\Pager\PagerManagerInterface
   */
  protected $pagerManager;

  /**
   * Logger service object.
   *
   * @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
   */
  protected $logger;

  /**
   * Constructor.
   *
   * @param array $configuration
   *   Configuration array containing information about search page.
   * @param string $plugin_id
   *   Identifier of custom plugin.
   * @param array $plugin_definition
   *   Provides definition of search plugin.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
   *   Plugin definition.
   * @param \GuzzleHttp\Client $httpClient
   *   Client for managing http requests.
   * @param \Drupal\search\SearchPageRepositoryInterface $searchPageRepository
   *   Repository for the search page.
   * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
   *   For retrieving information about the request.
   * @param \Drupal\Core\Utility\Token $tokenManager
   *   For managing Tokens.
   * @param \Drupal\Core\Pager\PagerManagerInterface $pagerManager
   *   Pager Manager.
   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $loggerFactory
   *   Logger for logging.
   */
  public function __construct(
      array $configuration,
      $plugin_id,
      array $plugin_definition,
      ConfigFactoryInterface $configFactory,
      Client $httpClient,
      SearchPageRepositoryInterface $searchPageRepository,
      RequestStack $requestStack,
      Token $tokenManager,
      PagerManagerInterface $pagerManager,
      LoggerChannelFactoryInterface $loggerFactory
      ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->requestStack = $requestStack;
    $this->configFactory = $configFactory;
    $this->httpClient = $httpClient;
    $this->searchPageRepository = $searchPageRepository;
    $this->tokenManager = $tokenManager;
    $this->pagerManager = $pagerManager;
    $this->logger = $loggerFactory->get('google_json_api');
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('config.factory'),
      $container->get('http_client'),
      $container->get('search.search_page_repository'),
      $container->get('request_stack'),
      $container->get('token'),
      $container->get('pager.manager'),
      $container->get('logger.factory')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function execute() {

    $page = 0;
    $sort = '';
    $items_per_page = $this->configuration['resultsperpage'];
    $response = [];
    $responseitems = [];

    // Retrieve sort value from query string if present.
    if ($this->requestStack->getCurrentRequest()->query->has('sort')) {
      $sort = $this->requestStack->getCurrentRequest()->query->get('sort');
    }

    // Retrieve page number value from query string if present.
    if ($this->requestStack->getCurrentRequest()->query->has('page')) {
      $page = $this->requestStack->getCurrentRequest()->query->get('page');
    }

    // Calculate the start index for the API request.
    // 100 is the max due to constraint of Google Programmable Search.
    $start = min(100, ($page * $items_per_page) + 1);

    // $items_per_page is a multiple of 10.
    for ($i = $items_per_page; $i > 0; $i = $i - 10) {

      $query = [
        'q' => $this->getKeywords(),
        'sort' => $sort,
        'cx' => $this->configuration['cx'],
        'key' => $this->configuration['apikey'],
        'start' => $start,
      ];

      $url = Url::fromUri($this->configuration['apiendpointurl'], ['query' => $query])->toString();

      // Get the JSON response from the Google API.
      try {
        $nextresponse = json_decode($this->getResponse($url), TRUE);

        // If nextresponse has items, make it the official response array and
        // append additonal items to items from previous responses.
        if (!empty($nextresponse['items']) && count($nextresponse['items'])) {
          $response = $nextresponse;
          $responseitems = array_merge($responseitems, $response['items']);
          $start = (($start + 10) > $response['queries']['request'][0]['totalResults']) ? -1 : $start + 10;
        }
        else {
          // No new items found.
          $start = -1;
        }

      }
      catch (\Exception $e) {
        $this->logger->error('Exception in GoogleJsonApiSearch::execute(): @message', ['@message' => $e->getMessage()]);
        return ['error' => TRUE];
      }

      // Break Google Programmable Search JSON API request loop if no new items
      // or $start is beyond Google Programmable Search 100 item response limit.
      if ($start == -1 || $start > 100) {
        break;
      }

    }

    // Update response array with all results.
    $response['items'] = $responseitems;

    // Retrieve total result count provided by Google Programmable Search.
    // This is an estimate from Google of all results, but Google
    // Programmable Search will only return up to 100 results.
    $totalresults = (!empty($response['queries']['request'][0]['totalResults'])) ?
      $response['queries']['request'][0]['totalResults'] : 0;

    // Create a pager customized for Google's limitation of 100.
    if (!empty($response['queries']['nextPage']) || !empty($response['queries']['previousPage'])) {
      $this->createSearchPager($totalresults, $items_per_page);
    }

    return $response;

  }

  /**
   * Wrapper function to create a pager.
   *
   * @param int $totalresults
   *   Total number of search results.
   * @param int $items_per_page
   *   Number of results on a search page.
   */
  protected function createSearchPager($totalresults, $items_per_page) {

    $this->pagerManager->createGooglePager(
      $totalresults,
      $items_per_page,
    );

  }

  /**
   * {@inheritdoc}
   */
  public function buildResults() {
    $results = $this->execute();

    $output = [];

    if (!empty($results['items'])) {

      // Determine the sort used in the request.
      $sortvalues = [
        'date:d' => 'Newest First',
        'date:a' => 'Oldest First',
        '' => 'Relevance',
      ];
      $sortvalue = (!empty($results['queries']['request'][0]['sort'])) ?
        $results['queries']['request'][0]['sort'] : '';
      $sortvalue = (!empty($sortvalues[$sortvalue])) ? $sortvalues[$sortvalue] : 'Unknown';

      // Retrieve the total results estimate from Google.
      $googletotalresults = (!empty($results['queries']['request'][0]['totalResults'])) ?
        $results['queries']['request'][0]['totalResults'] : 0;

      // Retrieve the starting result count and ending count for the page.
      $page = 0;
      if ($this->requestStack->getCurrentRequest()->query->has('page')) {
        $page = $this->requestStack->getCurrentRequest()->query->get('page');
      }
      $startcount = ($page * $this->configuration['resultsperpage']) + 1;
      $endcount = $startcount + count($results['items']) - 1;

      // Populate the data array used to populate Google JSON API custom tokens.
      $tokens['google_json_api'] = [
        'google_total_results' => $googletotalresults,
        'google_json_api_search_keywords' => $this->getKeywords(),
        'google_json_api_result_start' => $startcount,
        'google_json_api_result_end' => $endcount,
        'google_json_api_sort_value' => $sortvalue,
        'google_json_api_search_page' => $this->configuration['label'],
      ];

      // Display the results count message - configurable on the search page.
      $resultsmessage = $this->tokenManager->replace($this->configuration['results_message'], $tokens);

      if (count($results['items']) == 1 && !empty($this->configuration['results_message_singular'])) {

        $resultsmessage = $this->tokenManager->replace($this->configuration['results_message_singular'], $tokens);

      }

      $output[] = [
        '#theme' => 'google_json_api_results_message',
        '#message' => $resultsmessage,
        '#term' => $this->getKeywords(),
        '#plugin_id' => $this->getPluginId(),
        '#attached' => [
          'library' => [
            'google_json_api/googlejsonapiresults',
          ],
        ],
      ];

      // Display Google results limitation message from search page config.
      if ($googletotalresults > 100 && !empty($this->configuration['results_limitation_message'])) {

        $limitationmessage = $this->tokenManager->replace($this->configuration['results_limitation_message'], $tokens);

        $output[] = [
          '#theme' => 'google_json_api_results_limitation_message',
          '#message' => $limitationmessage,
          '#term' => $this->getKeywords(),
          '#plugin_id' => $this->getPluginId(),
          '#attached' => [
            'library' => [
              'google_json_api/googlejsonapiresults',
            ],
          ],
        ];

      }

      // Display Last Page Message.
      if (!empty($results['queries']['previousPage']) && empty($results['queries']['nextPage'])) {

        $lastpagemessage = $this->tokenManager->replace($this->configuration['results_last_page_message'], $tokens);

        $output[] = [
          '#theme' => 'google_json_api_results_last_page_message',
          '#message' => $lastpagemessage,
          '#term' => $this->getKeywords(),
          '#plugin_id' => $this->getPluginId(),
          '#attached' => [
            'library' => [
              'google_json_api/googlejsonapiresults',
            ],
          ],
        ];

      }

      // Display any promoted results for the search.
      if (!empty($results['promotions'])) {
        foreach ($results['promotions'] as $promo) {
          $output[] = [
            '#theme' => 'google_json_api_promoted_result',
            '#term' => $this->getKeywords(),
            '#promotion' => $promo,
            '#plugin_id' => $this->getPluginId(),
            '#attached' => [
              'library' => [
                'google_json_api/googlejsonapiresults',
              ],
            ],
          ];
        }
      }

      // Display spelling corrections/suggestions if they exist.
      if (!empty($results['spelling'])) {
        $url = Url::fromRoute('<current>', [
          'keys' => $results['spelling']['correctedQuery'],
        ]);

        $output[] = [
          '#theme' => 'google_json_api_spelling_correction',
          '#spelling' => $results['spelling'],
          '#url' => $url,
          '#term' => $this->getKeywords(),
          '#plugin_id' => $this->getPluginId(),
          '#attached' => [
            'library' => [
              'google_json_api/googlejsonapiresults',
            ],
          ],
        ];
      }

      // Display the normal results.
      foreach ($results['items'] as $result) {
        // Remove the domain if the feature is enabled.
        if (isset($this->configuration['removedomain']) && $this->configuration['removedomain']) {
          $url_parts = parse_url($result['link']);
          $new_link = str_replace($url_parts['scheme'] . '://' . $url_parts['host'], '', $result['link']);
          $result['link'] = $new_link;
        }

        $output[] = [
          '#theme' => 'google_json_api_result',
          '#result' => $result,
          '#term' => $this->getKeywords(),
          '#plugin_id' => $this->getPluginId(),
          '#attached' => [
            'library' => [
              'google_json_api/googlejsonapiresults',
            ],
          ],
        ];
      }

    }

    return $output;
  }

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

    unset($form['basic']);

    if (!$this->configuration['displaysearchform']) {
      return;
    }

    $form['#attributes']['class'][] = 'google-json-api-search-box-form';
    $form['#attributes']['id'] = 'google-json-api-search-box-form';
    $form['#theme'] = 'google_json_api_search_page_form';
    $form['#attached']['library'][] = 'google_json_api/googlejsonapiformselect';

    // Search term element.
    $form['keys'] = [
      '#type' => 'search',
      '#title' => $this->t('Search'),
      '#title_display' => 'none',
      '#default_value' => $this->getKeywords(),
    ];

    if (!empty($this->configuration['classsearchkeys'])) {
      $form['keys']['#attributes']['class'][] = $this->configuration['classsearchkeys'];
    }

    if (!empty($this->configuration['searchinputarialabel'])) {
      $form['keys']['#attributes']['aria-label'] = $this->configuration['searchinputarialabel'];
    }

    // Programmable search page select element.
    if ($this->configuration['displaysearchpageselection']) {
      $searchpageoptions = [];
      $active_search_pages = $this->searchPageRepository->getActiveSearchPages();
      foreach ($this->searchPageRepository->sortSearchPages($active_search_pages) as $entity) {
        if ($entity->get('plugin') == 'google_json_api_search') {
          $searchpageoptions[$entity->get('path')] = $entity->label();
        }
      }
      if (count($searchpageoptions) > 1) {
        $form['searchpage'] = [
          '#type' => 'select',
          '#title' => $this->t('Search Page'),
          '#title_display' => 'none',
          '#options' => $searchpageoptions,
          '#default_value' => $this->configuration['path'],
        ];
      }

      if (!empty($this->configuration['classsearchpageselect'])) {
        $form['searchpage']['#attributes']['class'][] = $this->configuration['classsearchpageselect'];
      }

    };

    // Sort select element.
    $attributes = [];
    if (!empty($this->getKeywords())) {
      $attributes['onchange'] = 'this.form.submit()';
    }

    if ($this->configuration['displaysort']) {

      $parameters = $this->getParameters();
      $form['sort'] = [
        '#type' => 'select',
        '#title' => $this->t('Sort Order'),
        '#title_display' => 'none',
        '#options' => [
          NULL => $this->t('Relevance'),
          'date:d' => $this->t('Newest First'),
          'date:a' => $this->t('Oldest First'),
        ],
        '#default_value' => ($parameters['sort']) ?? NULL,
        '#weight' => -10,
        '#attributes' => $attributes,
      ];

      if (!empty($this->configuration['classsearchsort'])) {
        $form['sort']['#attributes']['class'][] = $this->configuration['classsearchsort'];
      }
    }

    // Search submit element.
    $form['submit'] = [
      '#type' => 'submit',
      '#value' => 'Search',
    ];

    if (!empty($this->configuration['classsearchsubmit'])) {
      $form['submit']['#attributes']['class'][] = $this->configuration['classsearchsubmit'];
    }

    if (!empty($this->configuration['searchsubmitarialabel'])) {
      $form['submit']['#attributes']['aria-label'] = $this->configuration['searchsubmitarialabel'];
    }

  }

  /**
   * {@inheritdoc}
   */
  public function buildSearchUrlQuery(FormStateInterface $form_state) {
    return [
      'keys' => $form_state->getValue('keys'),
      'sort' => $form_state->getValue('sort'),
      'searchpage' => $form_state->getValue('searchpage'),
    ];
  }

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

    $jsonapiconfig = $this->configFactory->getEditable('google_json_api.settings');
    $jsonapidocumentation = $jsonapiconfig->get('google_programmable_search_documentation');
    $controlpanel = $jsonapiconfig->get('google_programmable_search_control_panel');

    $form['google_config_info'] = [
      '#title' => $this->t('Google Programmable Search Connection Information'),
      '#type' => 'details',
      '#open' => TRUE,
    ];

    $form['google_config_info']['cx'] = [
      '#title' => $this->t('Google Programmable Search Engine ID'),
      '#type' => 'textfield',
      '#default_value' => $this->configuration['cx'] ?? '',
      '#description' => $this->t('Enter your <a href=":url">Programmable Search Engine ID</a>
        (retrieve from the control panel).', [
          ':url' => $controlpanel,
        ]),
      '#required' => TRUE,
    ];

    $form['google_config_info']['apikey'] = [
      '#title' => $this->t('Google Programmable Search JSON API Key'),
      '#type' => 'textfield',
      '#maxlength' => 50,
      '#size' => 60,
      '#default_value' => $this->configuration['apikey'] ?? '',
      '#description' => $this->t('Refer to <a href=":jsonapioverview">Google Programmable Search
        JSON API Overview</a>.',
        [':jsonapioverview' => $jsonapidocumentation]),
      '#required' => TRUE,
    ];

    $endpointoptions = [
      'search_json_endpoint' => $this->t('Google Programmable Search JSON API endpoint'),
      'search_site_restricted_json_endpoint' => $this->t('Google Programmable Search Site Restricted JSON API endpoint'),
    ];

    $form['google_config_info']['apiendpoint'] = [
      '#title' => $this->t('Google Programmable Search JSON API Endpoint'),
      '#type' => 'radios',
      '#options' => $endpointoptions,
      '#default_value' => $this->configuration['apiendpoint'] ?? '',
      '#description' => $this->t('The Programmable Search JSON API has a daily limit for search queries.
        The Programmable Search Site Restricted JSON API allows for an unlimited number of queries if the
        Programmable Search Engine meets certain criteria.  For costs and query limit information read the
        <a href=":jsonapioverview">Google Programmable Search JSON API Documentation</a>.',
        [':jsonapioverview' => $jsonapidocumentation]),
      '#required' => TRUE,
    ];

    $form['google_serp_options'] = [
      '#title' => $this->t('Search Results Page Display Options'),
      '#type' => 'details',
      '#open' => TRUE,
    ];

    $form['google_serp_options']['resultsperpage'] = [
      '#title' => $this->t('Number of results per page'),
      '#type' => 'select',
      '#options' => [
        10 => 10,
        20 => 20,
        30 => 30,
        40 => 40,
        50 => 50,
      ],
      '#default_value' => $this->configuration['resultsperpage'] ?? '',
    ];

    $form['google_serp_options']['removedomain'] = [
      '#title' => $this->t('Remove Domain from Result Link URLs'),
      '#type' => 'checkbox',
      '#default_value' => $this->configuration['removedomain'] ?? '',
      '#description' => $this->t('Removing the domain makes all search results relative links, instead of pointing to the production domain. Useful when working with non-production domains.'),
    ];

    $form['google_serp_options']['displaysearchform'] = [
      '#title' => $this->t('Display Search Form on results page'),
      '#type' => 'checkbox',
      '#default_value' => $this->configuration['displaysearchform'] ?? '',
    ];

    $form['google_serp_options']['classsearchkeys'] = [
      '#title' => $this->t('Keywords Input Class'),
      '#type' => 'textfield',
      '#default_value' => $this->configuration['classsearchkeys'] ?? '',
      '#description' => $this->t('Add optional class to the keywords input element.'),
      '#states' => [
        'visible' => [
          ':input[name="displaysearchform"]' => ['checked' => TRUE],
        ],
      ],
    ];

    $form['google_serp_options']['searchinputarialabel'] = [
      '#title' => $this->t('Keywords Input Aria Label'),
      '#type' => 'textfield',
      '#default_value' => $this->configuration['searchinputarialabel'] ?? '',
      '#description' => $this->t('Add optional aria-label attribute the keywords input element.'),
      '#states' => [
        'visible' => [
          ':input[name="displaysearchform"]' => ['checked' => TRUE],
        ],
      ],
    ];

    $form['google_serp_options']['classsearchsubmit'] = [
      '#title' => $this->t('Submit Input Class'),
      '#type' => 'textfield',
      '#default_value' => $this->configuration['classsearchsubmit'] ?? '',
      '#description' => $this->t('Add optional class to the submit input element.'),
      '#states' => [
        'visible' => [
          ':input[name="displaysearchform"]' => ['checked' => TRUE],
        ],
      ],
    ];

    $form['google_serp_options']['searchsubmitarialabel'] = [
      '#title' => $this->t('Submit Input Aria Label'),
      '#type' => 'textfield',
      '#default_value' => $this->configuration['searchsubmitarialabel'] ?? '',
      '#description' => $this->t('Add optional aria-label attribute the submit input element.'),
      '#states' => [
        'visible' => [
          ':input[name="displaysearchform"]' => ['checked' => TRUE],
        ],
      ],
    ];

    $form['google_serp_options']['displaysearchpageselection'] = [
      '#title' => $this->t('Display search page selection on results page'),
      '#type' => 'checkbox',
      '#default_value' => $this->configuration['displaysearchpageselection'] ?? '',
      '#description' => $this->t('Allow selection of other search pages from search box on results page.'),
      '#states' => [
        'visible' => [
          ':input[name="displaysearchform"]' => ['checked' => TRUE],
        ],
      ],
    ];

    $form['google_serp_options']['classsearchpageselect'] = [
      '#title' => $this->t('Search Page Select Class'),
      '#type' => 'textfield',
      '#default_value' => $this->configuration['classsearchpageselect'] ?? '',
      '#description' => $this->t('Add optional class to search page select element.'),
      '#states' => [
        'visible' => [
          ':input[name="displaysearchpageselection"]' => ['checked' => TRUE],
        ],
      ],
    ];

    $form['google_serp_options']['displaysort'] = [
      '#title' => $this->t('Display Sort Options on results page'),
      '#type' => 'checkbox',
      '#default_value' => $this->configuration['displaysort'] ?? '',
      '#states' => [
        'visible' => [
          ':input[name="displaysearchform"]' => ['checked' => TRUE],
        ],
      ],
    ];

    $form['google_serp_options']['classsearchsort'] = [
      '#title' => $this->t('Sort Select Class'),
      '#type' => 'textfield',
      '#default_value' => $this->configuration['classsearchsort'] ?? '',
      '#description' => $this->t('Add optional class to the search sort select element.'),
      '#states' => [
        'visible' => [
          ':input[name="displaysort"]' => ['checked' => TRUE],
        ],
      ],
    ];

    $form['google_serp_messages'] = [
      '#title' => $this->t('Search Results Page Messages'),
      '#type' => 'details',
      '#open' => TRUE,
      '#description' => $this->t('Tokens may be used in any of the results-related messages.'),
    ];

    $form['google_serp_messages']['token_browser'] = [
      '#theme' => 'token_tree_link',
      '#token_types' => ['google_json_api', 'google_json_api_search_keywords'],
      '#global_types' => FALSE,
    ];

    $form['google_serp_messages']['results_message'] = [
      '#title' => $this->t('Results message'),
      '#type' => 'textarea',
      '#default_value' => $this->configuration['results_message'] ?? '',
      '#description' => $this->t('Message to display when results are returned.'),
    ];

    $form['google_serp_messages']['results_message_singular'] = [
      '#title' => $this->t('Results message (singular)'),
      '#type' => 'textarea',
      '#default_value' => $this->configuration['results_message_singular'] ?? '',
      '#description' => $this->t('Message to display when only a single result is returned.  Normal results message will be default.'),
    ];

    $form['google_serp_messages']['results_limitation_message'] = [
      '#title' => $this->t('Google results limitation message.'),
      '#type' => 'textarea',
      '#default_value' => $this->configuration['results_limitation_message'] ?? '',
      '#description' => $this->t('Google Programmable Search will only return 100 results.
      This message will appear when Google finds more than 100 results to explain that only the first 100 results are presented.'),
    ];

    $form['google_serp_messages']['results_last_page_message'] = [
      '#title' => $this->t('Last Page Message'),
      '#type' => 'textarea',
      '#default_value' => $this->configuration['results_last_page_message'] ?? '',
      '#description' => $this->t('Message to display on the last page of search results.'),
    ];

    $form['google_serp_messages']['no_results_message'] = [
      '#title' => $this->t('No results message'),
      '#type' => 'textarea',
      '#default_value' => $this->configuration['no_results_message'] ?? '',
      '#description' => $this->t('Message to display when there are no search results returned.'),
    ];

    $form['google_serp_messages']['no_keywords_message'] = [
      '#title' => $this->t('No keywords specified message'),
      '#type' => 'textarea',
      '#default_value' => $this->configuration['no_keywords_message'] ?? '',
      '#description' => $this->t('Message to display when arriving at search page without specifying keywords on which to search.'),
    ];

    return $form;
  }

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

    // Set the search page configuration values.
    $values = $form_state->getValues();
    $this->configuration['page_id'] = $values['id'];
    $this->configuration['path'] = $values['path'];
    $this->configuration['label'] = $values['label'];
    $this->configuration['cx'] = $values['cx'];
    $this->configuration['apikey'] = $values['apikey'];
    $this->configuration['apiendpoint'] = $values['apiendpoint'];
    $this->configuration['resultsperpage'] = $values['resultsperpage'];
    $this->configuration['displaysearchform'] = $values['displaysearchform'];
    $this->configuration['displaysearchpageselection'] = $values['displaysearchpageselection'];
    $this->configuration['displaysort'] = $values['displaysort'];
    $this->configuration['results_message'] = $values['results_message'];
    $this->configuration['results_message_singular'] = $values['results_message_singular'];
    $this->configuration['results_limitation_message'] = $values['results_limitation_message'];
    $this->configuration['no_results_message'] = $values['no_results_message'];
    $this->configuration['no_keywords_message'] = $values['no_keywords_message'];
    $this->configuration['results_last_page_message'] = $values['results_last_page_message'];
    $this->configuration['classsearchkeys'] = $values['classsearchkeys'];
    $this->configuration['classsearchsubmit'] = $values['classsearchsubmit'];
    $this->configuration['searchinputarialabel'] = $values['searchinputarialabel'];
    $this->configuration['classsearchpageselect'] = $values['classsearchpageselect'];
    $this->configuration['searchsubmitarialabel'] = $values['searchsubmitarialabel'];
    $this->configuration['classsearchsort'] = $values['classsearchsort'];
    $this->configuration['removedomain'] = $values['removedomain'];

    // The apiendpointurl depends on chosen apiendpoint on Search Page Config.
    // Retrieve the corrent url from the module settings.
    $jsonapiconfig = $this->configFactory->getEditable('google_json_api.settings');
    $this->configuration['apiendpointurl'] = $jsonapiconfig->get($values['apiendpoint']);

  }

  /**
   * Gets a response from a Google API URL.
   *
   * @param string $url
   *   The Google URL to query.
   *
   * @return string
   *   The response from Google.
   *
   * @throws \http\Exception
   */
  private function getResponse(string $url) {
    $options = [
      'connect_timeout' => 30,
      'headers' => [
        'Content-Type' => 'text/json',
      ],
    ];

    try {
      $request = $this->httpClient->request('GET', $url, $options);
    }
    catch (GuzzleException $e) {
      throw new \Exception('Error when making request to the JSON API: ' . $e->getMessage());
    }

    if ($request->getStatusCode() != 200) {
      throw new \Exception('Got status code other than 200: ' . $request->getStatusCode());
    }

    return $request->getBody();
  }

}

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

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