uc_gc_client-8.x-1.x-dev/src/Controller/GoCardlessPartner.php

src/Controller/GoCardlessPartner.php
<?php

namespace Drupal\uc_gc_client\Controller;

use Drupal\Core\Controller\ControllerBase;
use GuzzleHttp\Exception\RequestException;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;

/**
 * Functions for communicating with the GoCardless partner: Seamless-CMS.co.uk.
 */
class GoCardlessPartner extends ControllerBase {

  /**
   * The module settings and payment method settings.
   *
   * @var array
   */
  public $settings;

  /**
   * The logger.
   *
   * @var \Psr\Log\LoggerInterface
   */
  private $logger;

  /**
   * The currently active request object.
   *
   * @var \Symfony\Component\HttpFoundation\Session\Session
   */
  protected $session;

  /**
   * The httpClient service.
   *
   * @var \GuzzleHttp\Psr7\Response
   */
  protected $httpClient;

  /**
   * Constructs the GoCardlessPartner object.
   */
  public function __construct() {
    $this->settings = $this->getSettings();
    $this->logger = $this->getLogger('uc_gc_client');
    $this->session = \Drupal::request()->getSession();
    $this->httpClient = \Drupal::httpClient();
  }

  /**
   * Gets the GoCardless webhook password.
   *
   * @return string
   *   The password, depending on if the payment method is in live or sandbox
   *   mode.
   */
  public static function getPartnerWebhook() {
    return GoCardlessPartner::getSettings()['partner_webhook'];
  }

  /**
   * Gets the module and the payment gateway settings combined.
   *
   * @return array
   *   The settings.
   */
  public static function getSettings() {
    $config_id = \Drupal::state()->get('uc_gc_client_payment_method_id');
    if (!is_null($config_id)) {
      $settings = \Drupal::config($config_id)->get('settings');
      $default_settings = \Drupal::config('uc_gc_client.settings');
      $settings['config_id'] = explode('.', $config_id)[2];
      $default_settings->get('sandbox') ? $settings['sandbox'] = 1 : $settings['sandbox'] = 0;
      $default_settings->get('sandbox') ? $ext = '_sandbox' : $ext = '_live';
      $settings['partner_user'] = $default_settings->get('partner_user' . $ext);
      $settings['partner_pass'] = $default_settings->get('partner_pass' . $ext);
      $settings['partner_webhook'] = $default_settings->get('partner_webhook' . $ext);
      $settings['org_id'] = $default_settings->get('org_id' . $ext);
      $settings['partner_url'] = $default_settings->get('partner_url');
      return $settings;
    }
  }

  /**
   * Handles session authentication with GC Partner site.
   *
   * @return mixed
   *   If the site is already connected to the Partner site then the status
   *   code 200 is returned as an integer. If a new connection is attempted,
   *   and suceeds, the respose code (200) from the Partner site is returned,
   *   and if the attempt fails FALSE is returned. If the username and / or
   *   password are not set then a string is returned.
   */
  protected function authenticate() {
    if (isset($_SESSION['uc_gc_client_cookie_created']) && $_SESSION['uc_gc_client_cookie_created'] < REQUEST_TIME - 1800) {
      unset($_SESSION['uc_gc_client_cookie']);
      unset($_SESSION['uc_gc_client_cookie_created']);
    }

    if (!isset($_SESSION['uc_gc_client_cookie_created'])) {
      $user_name = $this->settings['partner_user'];
      $user_pass = $this->settings['partner_pass'];

      // Attempt session authentication if user name and password set.
      if (isset($user_name) && isset($user_pass)) {
        $data = [
          'username' => $user_name,
          'password' => $user_pass,
        ];
        $data = json_encode($data);
        $uri = $this->settings['partner_url'] . '/gc_connect/user/login';
        try {
          $result = $this->httpClient
            ->post($uri, [
              'headers' => ['Content-Type' => 'application/json'],
              'body' => $data,
            ]
          );
          $result_data = (string) $result->getBody();
          if (empty($result_data)) {
            return FALSE;
          }
          $result_data = json_decode($result_data);
        }
        catch (RequestException $e) {
          return FALSE;
        }

        if ($result->getStatusCode() == 200) {
          // Get X-CRSF token, and save cookie and token.
          $_SESSION['uc_gc_client_cookie'] = $result_data->session_name . '=' . $result_data->sessid;
          $_SESSION['uc_gc_client_cookie_created'] = REQUEST_TIME;

          $xcrf_uri = $this->settings['partner_url'] . '/services/session/token';
          try {
            $xcrf_result = $this->httpClient
              ->get($xcrf_uri, [
                'headers' => ['Cookie' => $_SESSION['uc_gc_client_cookie']],
              ]
            );
            $xcrf_result_data = (string) $xcrf_result->getBody();
            if (empty($xcrf_result_data)) {
              return FALSE;
            }
            $_SESSION['uc_gc_client_token'] = $xcrf_result_data;
          }
          catch (RequestException $e) {
            return FALSE;
          }
        }
        return $result->getStatusCode();
      }
      else {
        return $result = 'User name and password not set';
      }
    }
    else {
      // Already logged in.
      return $result = 200;
    }
  }

  /**
   * Performs a GET request on the the Partner site.
   */
  public function get($data = NULL) {
    $auth = $this->authenticate();
    if ($auth != 200) {
      return $auth;
    }

    $this->settings['sandbox'] ? $data['environment'] = 'SANDBOX' : $data['environment'] = 'LIVE';
    $headers = [
      'Content-Type' => 'application/json',
      'Cookie' => $_SESSION['uc_gc_client_cookie'],
      'X-CSRF-Token' => $_SESSION['uc_gc_client_token'],
    ];
    $data = json_encode($data);
    $uri = $this->settings['partner_url'] . '/gc/client/' . $this->settings['org_id'];
    try {
      $response = $this->httpClient->get($uri, [
        'headers' => $headers,
        'body' => $data,
      ]);
      $response_data = (string) $response->getBody();
      if (empty($response_data)) {
        return FALSE;
      }
      return $response_data = json_decode($response_data);
    }
    catch (RequestException $e) {
      return FALSE;
    }
  }

  /**
   * Callback function: Saves key variables for connecting with Partner site.
   *
   * Variables are posted here from Partner site, following completion of
   * GoCardless OAuth flow.
   *
   * @return object
   *   A new Symfony\Component\HttpFoundation\Response.
   */
  public static function connect() {
    if (isset($_POST['environ'])) {
      $settings = \Drupal::service('config.factory')->getEditable('uc_gc_client.settings');
      $_POST['environ'] == 'SANDBOX' ? $ext = '_sandbox' : $ext = '_live';
      if (isset($_POST['id'])) {
        $settings->set('org_id' . $ext, $_POST['id'])->save();
      }
      if (isset($_POST['name'])) {
        $settings->set('partner_user' . $ext, $_POST['name'])->save();
      }
      if (isset($_POST['pass'])) {
        $settings->set('partner_pass' . $ext, $_POST['pass'])->save();
      }
    }
    return new Response();
  }

  /**
   * Redirects user to GC settings page upon completion of OAuth flow.
   *
   * @return object
   *   A new Symfony\Component\HttpFoundation\RedirectResponse.
   */
  public static function connectComplete() {
    if (isset($_GET['status'])) {
      if ($_GET['status'] == 'insecure') {
        drupal_set_message(t('Connection cannot be created because site must be secure (https) to use LIVE environment'), 'error');
      }
      elseif ($_GET['status'] == 'connected') {
        drupal_set_message(t('You have connected successfully with GoCardless'));
      }
    }
    $config_id = \Drupal::state()->get('uc_gc_client_payment_method_id');
    $config_id = explode('.', $config_id)[2];
    return new RedirectResponse('/admin/store/config/payment/method/' . $config_id);
  }

  /**
   * Handles API requests to GC Partner site, and optionally logs results.
   *
   * @params array
   *   The parameters for the request.
   *
   * @return mixed
   *   If authentication fails then the result from the authentication attempt
   *   is returned. If authentication is successfull then:
   *   - if the request succeeds and the response is successful, the response
   *     is returned as an array;
   *   - if the request succeeds but the response is an error, a string is
   *     returned containing the error code and message.
   *   - if the request succeeds but the response is empty, return FALSE;
   *   - if the request fails the RequestException error code is returned;
   */
  public function api($params) {
    $auth = $this->authenticate();
    if ($auth == 200) {
      $headers = [
        'Content-Type' => 'application/json',
        'Cookie' => $_SESSION['uc_gc_client_cookie'],
        'X-CSRF-Token' => $_SESSION['uc_gc_client_token'],
      ];
      $this->settings['sandbox'] ? $params['environment'] = 'SANDBOX' : $params['environment'] = 'LIVE';
      $uri = $this->settings['partner_url'] . '/gc/client/' . $this->settings['org_id'];

      try {
        $response = $this->httpClient
          ->post($uri, [
            'headers' => $headers,
            'body' => json_encode($params),
          ]
        );
        $result = (string) $response->getBody();
        if (empty($result)) {
          return FALSE;
        }
        $result = json_decode($result);
        if (isset($result->error)) {
          $message = $this->t('Error code @code (@error)', ['@code' => $result->code, '@error' => $result->error]);
          drupal_set_message($message, 'error');
          if ($this->settings['log_api']) {
            $this->logger->error('<pre>' . $message . '<br />' . print_r($result, TRUE) . '</pre>', []);
          }
          return $message;
        }
        elseif ($this->settings['log_api']) {
          $this->logger->notice('<pre>GoCardless API response: <br />' . print_r($result, TRUE) . '</pre>', []);
        }
        return $result;
      }
      catch (RequestException $e) {
        return $e->getCode();
      }
    }
    else {
      drupal_set_message($this->t('Error @code connecting with partner site', ['@code' => $auth]), 'error');
      if ($this->settings['log_api']) {
        $this->logger->error('<pre>' . print_r($auth, TRUE) . '</pre>', []);
      }
      return $auth;
    }
  }

}

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

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