You are here

class WSConnectorSimpleHTTP in Web Service Data 8

Same name and namespace in other branches
  1. 2.0.x src/Plugin/WSConnector/WSConnectorSimpleHTTP.php \Drupal\wsdata\Plugin\WSConnector\WSConnectorSimpleHTTP

HTTP Connector.

Plugin annotation


@WSConnector(
  id = "WSConnectorSimpleHTTP",
  label = @Translation("Simple HTTP connector", context = "WSConnector"),
)

Hierarchy

Expanded class hierarchy of WSConnectorSimpleHTTP

1 file declares its use of WSConnectorSimpleHTTP
WSConnectorSOAP.php in src/Plugin/WSConnector/WSConnectorSOAP.php
1 string reference to 'WSConnectorSimpleHTTP'
wsdata.wsserver.example_server.yml in modules/wsdata_example/config/install/wsdata.wsserver.example_server.yml
modules/wsdata_example/config/install/wsdata.wsserver.example_server.yml

File

src/Plugin/WSConnector/WSConnectorSimpleHTTP.php, line 20

Namespace

Drupal\wsdata\Plugin\WSConnector
View source
class WSConnectorSimpleHTTP extends WSConnectorBase {

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, Client $http_client, Token $token) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $token);
    $this->http_client = $http_client;
    $this->token = $token;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static($configuration, $plugin_id, $plugin_definition, $container
      ->get('http_client'), $container
      ->get('token'));
  }

  /**
   * {@inheritdoc}
   */
  public function getMethods() {
    return [
      'get',
      'post',
      'put',
      'delete',
      'head',
      'options',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getOptions() {
    return [
      'path' => '',
      'method' => [],
      'headers' => [],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function saveOptions($values) {

    // Check how many key values and create the array.
    $header = 0;
    foreach ($values as $key => $value) {
      if (preg_match("/^key_([0-9]+)/", $key, $matches)) {
        if (isset($matches[1]) && !empty($values['key_' . $matches[1]])) {
          $values['headers'][$header] = [
            'key_' . $header => $values['key_' . $matches[1]],
            'value_' . $header => $values['value_' . $matches[1]],
          ];
          unset($values['key_' . $matches[1]]);
          unset($values['value_' . $matches[1]]);
          $header++;
        }
      }
    }
    return parent::saveOptions($values);
  }

  /**
   * {@inheritdoc}
   */
  public function getReplacements(array $options) {
    return $this
      ->findTokens($this->endpoint . '/' . $options['path']);
  }

  /**
   * {@inheritdoc}
   */
  public function getOptionsForm($options = []) {
    $methods = $this
      ->getMethods();
    $form['path'] = [
      '#title' => $this
        ->t('Path'),
      '#description' => $this
        ->t('The final endpoint will be <em>Server Endpoint/Path</em>'),
      '#type' => 'textfield',
      '#maxlength' => 512,
    ];
    $form['method'] = [
      '#title' => $this
        ->t('HTTP Method'),
      '#type' => 'select',
      '#options' => array_combine($methods, $methods),
    ];
    $form['expires'] = [
      '#type' => 'number',
      '#title' => $this
        ->t('Expire'),
      '#description' => $this
        ->t("Cache the response for number of seconds. This values will override the Cache-Control header value if it's set"),
    ];
    if (!isset($options['headers'])) {
      $options['headers'] = [];
    }
    $header_count = count($options['headers']);
    if (isset($options['form_state'])) {
      $input = $options['form_state']
        ->getUserInput();
      if (isset($input['headers_count'])) {
        $header_count = $input['headers_count'] + 1;
      }
    }
    $form['headers'] = [
      '#title' => $this
        ->t('Headers'),
      '#type' => 'fieldset',
      '#attributes' => [
        'id' => 'wsconnector-headers',
      ],
    ];
    $form['headers']['headers_count'] = [
      '#type' => 'hidden',
      '#value' => $header_count,
    ];
    for ($i = 0; $i < $header_count; $i++) {
      $form['headers'][$i] = [
        '#title' => 'header',
        '#type' => 'fieldset',
      ];
      $form['headers'][$i]['key_' . $i] = [
        '#type' => 'textfield',
        '#title' => $this
          ->t('Key'),
      ];
      $form['headers'][$i]['value_' . $i] = [
        '#type' => 'textfield',
        '#title' => $this
          ->t('Value'),
      ];
    }
    if (isset($options['form_state'])) {
      $form['headers']['add_another'] = [
        '#type' => 'submit',
        '#value' => $this
          ->t('Add another'),
        '#ajax' => [
          'callback' => '\\Drupal\\wsdata\\Plugin\\WSConnector\\WSConnectorSimpleHTTP::wsconnectorHttpHeaderAjaxCallback',
          'wrapper' => 'wsconnector-headers',
        ],
        '#limit_validation_errors' => [],
      ];
    }
    return $form;
  }

  /**
   * Ajax callback function.
   */
  public static function wsconnectorHttpHeaderAjaxCallback(array &$form, FormStateInterface $form_state) {
    return $form['options']['wsserveroptions']['headers'];
  }

  /**
   * {@inheritdoc}
   */
  public function call($options, $method, $replacements = [], $data = NULL, array $tokens = []) {
    $this->status = [];
    $token_service = \Drupal::token();
    if (!in_array($method, $this
      ->getMethods())) {
      throw new WSDataInvalidMethodException(sprintf('Invalid method %s on connector type %s', $method, __CLASS__));
    }
    $uri = $this->endpoint . '/' . $options['path'];
    $uri = $this
      ->applyReplacements($uri, $replacements, $tokens);
    $options['http_errors'] = FALSE;

    // Perform the token replace on the headers.
    if (!empty($options['headers'])) {
      for ($i = 0; $i < count($options['headers']); $i++) {
        if (!empty($options['headers'][$i]['key_' . $i])) {
          $options['headers'][$options['headers'][$i]['key_' . $i]] = $token_service
            ->replace($options['headers'][$i]['value_' . $i], $tokens);
        }
        unset($options['headers'][$i]['key_' . $i]);
        unset($options['headers'][$i]['value_' . $i]);
        unset($options['headers'][$i]);
      }
    }
    if (!empty($data)) {
      $options['body'] = $data;
    }
    if (isset($options['body'])) {
      $options['body'] = $token_service
        ->replace($options['body'], $tokens);
    }
    $wscall_cid = $this
      ->getCache() . $method . ':' . $uri;
    $response = FALSE;
    $from_cache = FALSE;
    if ($this
      ->supportsCaching($method)) {
      $cache = \Drupal::cache('wsdata')
        ->get($wscall_cid);
      if ($cache) {
        $response = $cache->data;
        $this->expires = 0;
      }
    }
    if ($response) {
      $from_cache = TRUE;
      $this->status['cache']['cached'] = TRUE;
      $this->status['cache']['debug'] = $this
        ->t('Returning response from cache');
      $options['expires'] = -1;
    }
    else {
      try {
        $result = $this->http_client
          ->request($method, $uri, $options);
        $response = [
          'code' => $result
            ->getStatusCode(),
          'reason' => $result
            ->getReasonPhrase(),
          'expires' => $this
            ->setCacheExpire($result),
          'body' => (string) $result
            ->getBody(),
        ];
        $from_cache = FALSE;
      } catch (\Throwable $e) {
        $this
          ->setError(get_class($e), $e
          ->getMessage());
        return FALSE;
      }
    }
    $this->status['method'] = $method;
    $this->status['uri'] = $uri;
    $this->status['response']['code'] = $response['code'];
    if (\Drupal::state()
      ->get('wsdata_debug_mode')) {
      $this->status['options'] = $options;
      $this->status['response']['body'] = $response['body'];
    }

    // Set the cache expire time.
    if (isset($options['expires']) && !empty($options['expires'])) {
      $this->expires = (int) $options['expires'];
    }
    if ($response['code'] >= 199 and $response['code'] <= 300) {
      if (!$from_cache && $this
        ->supportsCaching($method)) {
        \Drupal::cache('wsdata')
          ->set($wscall_cid, $response, time() + $this->expires + 2, [
          __CLASS__,
        ]);
      }
      return (string) $response['body'];
    }
    $this
      ->setError($response['code'], $response['reason']);
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function supportsCaching($method = NULL) {

    // If the request is a GET support caching.
    if (in_array($method, [
      'get',
    ])) {
      return TRUE;
    }
    else {
      return FALSE;
    }
  }

  /**
   * Sets the expires times based on the response.
   */
  public function setCacheExpire($response) {
    $cache_header = $response
      ->getHeader('Cache-Control');
    foreach ($cache_header as $control_header) {
      if (preg_match("/^max-age=\\d+/", $control_header)) {
        $this->expires = (int) str_replace('max-age=', '', $control_header);
      }
    }
    return $this->expires;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.
WSConnectorBase::$cacheDefaultOverride protected property
WSConnectorBase::$cacheDefaultTime protected property
WSConnectorBase::$endpoint protected property
WSConnectorBase::$error protected property
WSConnectorBase::$expires protected property
WSConnectorBase::$languagePlugins protected property
WSConnectorBase::$staleCache protected property
WSConnectorBase::$status protected property
WSConnectorBase::applyReplacements protected function Internal function for applying replacements.
WSConnectorBase::clearError protected function Clear current error.
WSConnectorBase::defaultCache public function Figure out the overrides for cache times.
WSConnectorBase::expires public function Get the expired time for caching.
WSConnectorBase::findTokens protected function Internal function for finding tokens.
WSConnectorBase::getCache public function Return cache cid for cases cache rules change. 2
WSConnectorBase::getEndpoint public function Getter for the endpoint.
WSConnectorBase::getError public function Return the last error the connector received.
WSConnectorBase::getStatus public function Return the status of the last call.
WSConnectorBase::getSupportedLanguagePlugins public function Return the list of supported language handling plugins.
WSConnectorBase::isDegraded public function Whether the connector is in a dead state and shouldn't be called.
WSConnectorBase::setEndpoint public function Setter for the endpoint.
WSConnectorBase::setError protected function Setter for the connector errors.
WSConnectorSimpleHTTP::call public function Make the connector call. Overrides WSConnectorBase::call 3
WSConnectorSimpleHTTP::create public static function Creates an instance of the plugin. Overrides WSConnectorBase::create 2
WSConnectorSimpleHTTP::getMethods public function Return available methods supported by the connector. Overrides WSConnectorBase::getMethods 2
WSConnectorSimpleHTTP::getOptions public function Return available options supported by the connector. Overrides WSConnectorBase::getOptions 2
WSConnectorSimpleHTTP::getOptionsForm public function Return the settings form provided by the connector. Overrides WSConnectorBase::getOptionsForm 3
WSConnectorSimpleHTTP::getReplacements public function Return an array of replacements. Overrides WSConnectorBase::getReplacements 3
WSConnectorSimpleHTTP::saveOptions public function Saves the options form. Overrides WSConnectorBase::saveOptions
WSConnectorSimpleHTTP::setCacheExpire public function Sets the expires times based on the response.
WSConnectorSimpleHTTP::supportsCaching public function Whether returned data can be cached. Overrides WSConnectorBase::supportsCaching
WSConnectorSimpleHTTP::wsconnectorHttpHeaderAjaxCallback public static function Ajax callback function. 1
WSConnectorSimpleHTTP::__construct public function Constructs a \Drupal\Component\Plugin\PluginBase object. Overrides WSConnectorBase::__construct 2