commerce_gc_client-8.x-1.9/src/GoCardlessPartner.php
src/GoCardlessPartner.php
<?php
namespace Drupal\commerce_gc_client;
use Drupal\Component\Serialization\Json;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Logger\LoggerChannelFactory;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\StringTranslation\TranslationManager;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Functions for communicating with the GoCardless partner: Seamless-CMS.co.uk.
*/
class GoCardlessPartner {
/**
* The module settings, and (optionally) payment gateway settings.
*
* @var array
*/
public $settings;
/**
* The payment gateway's mode: LIVE or SANDBOX.
*
* @var string
*/
protected $mode;
/**
* An array of parameters to define the API request.
*
* @var array
*/
protected $params;
/**
* The currently active request object.
*
* @var \Symfony\Component\HttpFoundation\Session\Session
*/
protected $session;
/**
* The httpClient service.
*
* @var \GuzzleHttp\Psr7\Response
*/
protected $httpClient;
/**
* The time service.
*
* @var \Drupal\Component\Datetime\TimeInterface
*/
protected $time;
/**
* The Config Factory interface.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* The Logger Channel factory.
*
* @var \Drupal\Core\Logger\LoggerChannelFactory
*/
protected $logger;
/**
* The Messenger service.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;
/**
* Constructs the GoCardlessPartner object.
*
* @param \GuzzleHttp\Client $httpClient
* The GuzzleHttp client service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory.
* @param \Drupal\Component\Datetime\TimeInterface $time
* The time service.
* @param \Drupal\Core\Logger\LoggerChannelFactory $loggerChannel
* The Logger Channel factory.
* @param \Drupal\Core\Messenger\MessengerInterface $messengerInterface
* The messenger interface.
* @param Symfony\Component\HttpFoundation\RequestStack $request_stack
* The Symfony request stack component.
*/
public function __construct(Client $httpClient, ConfigFactoryInterface $configFactory, TimeInterface $time, LoggerChannelFactory $loggerChannel, MessengerInterface $messengerInterface, RequestStack $request_stack) {
$this->settings = $configFactory->get('commerce_gc_client.settings')->get();
$this->configFactory = $configFactory;
$this->httpClient = $httpClient;
$this->logger = $loggerChannel->get('commerce_gc_client');
$this->session = $request_stack->getCurrentRequest()->getSession();
$this->time = $time;
$this->messenger = $messengerInterface;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('http_client'),
$container->get('config.factory'),
$container->get('datetime.time'),
$container->get('logger.factory'),
$container->get('messenger'),
$container->get('request_stack')
);
}
/**
* Obtains the config parameters for an order's payment gateway.
*
* @param string $gateway_id
* The payment gateway Id.
*/
public function setGateway($gateway_id) {
$this->settings += $this->configFactory->get('commerce_payment.commerce_payment_gateway.' . $gateway_id)->get();
}
/**
* Handles API posts to GC Partner site, and optionally logs results.
*/
public function api($params) {
$this->params = $params;
if (isset($params['mode'])) {
$this->mode = $params['mode'];
}
elseif (isset($this->settings['configuration'])) {
$this->mode = $this->settings['configuration']['mode'];
}
if (isset($this->mode)) {
$this->params['environment'] = strtoupper($this->mode);
}
$auth = $this->authenticate();
if ($auth == 200) {
if (isset($params['method']) && $params['method'] == 'get') {
$result = $this->get();
}
else {
if ($result = $this->post()) {
$result = json_decode($result);
}
}
if (isset($result->error)) {
$message = t('Error calling GoCardless API, code @code (@error)', [
'@code' => $result->code,
'@error' => $result->error,
]);
$this->messenger->addError($message);
if ($this->settings['configuration']['log_api']) {
$this->logger->error('<pre>' . $message . '<br />' . print_r($result, TRUE) . '</pre>', []);
}
$result->response = new \stdClass();
$result->response->status_code = $result->code;
return $result;
}
else {
if (isset($this->settings['configuration']) && $this->settings['configuration']['log_api']) {
$this->logger->notice('<pre>GoCardless API response: <br />' . print_r($result, TRUE) . '</pre>', []);
}
return $result;
}
}
else {
$this->messenger->addError(
t('Error @code connecting with GoCardless.', [
'@code' => $auth,
]
)
);
if (isset($this->settings['configuration']) && $this->settings['configuration']['log_api']) {
$this->logger->error('<pre>' . print_r($auth, TRUE) . '</pre>', []);
}
return $auth;
}
}
/**
* Handles session authentication with GC Partner site.
*/
protected function authenticate() {
if ($this->session->get('commerce_gc_client_cookie_created') && $this->session->get('commerce_gc_client_cookie_created') < $this->time->getRequestTime() - 1800) {
$this->session->remove('commerce_gc_client_cookie');
$this->session->remove('commerce_gc_client_cookie_created');
}
if (!$this->session->get('commerce_gc_client_cookie_created')) {
// Attempt session authentication if user name and password set.
$user_name = $this->settings['partner_user_' . $this->mode];
$user_pass = $this->settings['partner_pass_' . $this->mode];
if (isset($user_name) && isset($user_pass)) {
// Login first.
$body = [
'name' => $user_name,
'pass' => $user_pass,
];
$body = Json::encode($body);
$url = $this->settings['partner_url'] . '/user/login?_format=json';
try {
$result = $this->httpClient->post($url, [
'headers' => ['Content-Type' => 'application/json'],
'body' => $body,
]);
$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) {
// Set cookie and CSRF token as session variables.
$headers = $result->getHeaders();
if (isset($headers['set-cookie']) && isset($result_data->csrf_token)) {
$this->session->set('commerce_gc_client_cookie', $headers['set-cookie'][0]);
$this->session->set('commerce_gc_client_csrf_token', $result_data->csrf_token);
$this->session->set('commerce_gc_client_cookie_created', $this->time->getRequestTime());
}
else {
return false;
}
}
return $result->getStatusCode();
}
else {
$message = t('User name and password not set for @mode', [
'@mode' => $this->mode,
]);
$this->messenger->addError($message);
return FALSE;
}
}
else {
// Already logged in.
return 200;
}
}
/**
* Handles HTTP GET requests to GC Partner site.
*/
private function get() {
$url = $this->settings['partner_url'];
switch ($this->params['endpoint']) {
case 'connection':
if ($name = $this->settings['partner_user_' . $this->params['mode']]) {
$url .= '/user/connection/' . $name;
}
break;
case 'webhook_secret':
$url .= '/webhook_secret';
break;
}
if ($url !== $this->settings['partner_url']) {
try {
$response = $this->httpClient->get($url . '?_format=json', [
'headers' => [
'Content-Type' => 'application/json',
'Cookie' => $this->session->get('commerce_gc_client_cookie'),
]]);
$body = (string) $response->getBody();
if (empty($body)) {
return false;
}
return Json::decode($body);
}
catch (RequestException $e) {
return false;
}
}
}
/**
* Handles HTTP POST requests to GC Partner site.
*/
private function post() {
$url = $this->settings['partner_url'] . '/' . $this->params['endpoint'];
try {
$response = $this->httpClient->post($url . '?_format=json', [
'headers' => [
'Content-Type' => 'application/json',
'Cookie' => $this->session->get('commerce_gc_client_cookie'),
'X-CSRF-Token' => $this->session->get('commerce_gc_client_csrf_token'),
],
'body' => Json::encode($this->params),
]);
$body = (string) $response->getBody();
if (empty($body)) {
return FALSE;
}
return Json::decode($body);
}
catch (RequestException $e) {
$this->logger->error($e->getMessage());
return FALSE;
}
if (isset($response->error)) {
return $response;
}
}
}
