File: /home4/cca63905/public_html/nueva/modules/pmproductvideoreviews/lib/RecReviews/Client.php
<?php
/**
* rec.reviews
*
* @author Presta-Module.com <support@presta-module.com> - https://www.presta-module.com
* @copyright Presta-Module - https://www.presta-module.com
* @license see file: LICENSE.txt
*
* ____ __ __
* | _ \ | \/ |
* | |_) | | |\/| |
* | __/ | | | |
* |_| |_| |_|
*/
namespace RecReviews;
if (!defined('_PS_VERSION_')) {
exit;
}
class Client
{
const WEBSITE_URL = 'https://recreviews.com/';
const API_URL = 'https://dashboard.recreviews.com/';
const ONBOARDING_URL = 'https://dashboard.recreviews.com/onboarding';
const MODULE_SOURCE = 'addons';
const CLIENT_ID = '9627cf77-6413-4b48-aa3e-5d903b774598';
const SECRET_ID = 'T7BY4Eb3VWXic25m8Ls7YR2IhROTcsVGdY50ZDO';
const RBM_PATH = 'https://billing-api.distribution.prestashop.net/v1/customers/';
const RBM_TOKEN = 'EVKsZ5puh0mt6A1hV8VSQ10LfAE18ot5';
/**
* The access token to use to authentify requests
*
* @var string
*/
private $access_token;
private function __construct()
{
}
public static function getClient()
{
static $client = null;
if ($client === null) {
$client = new static();
}
return $client;
}
/**
* Retrieve CURL Handle
*
* @param string $access_token
* @param string $url
* @param string $method
* @param array $params
* @param array $addHeaders
*
* @return resource
*/
private static function getCurlHandle($access_token, $url, $method = 'GET', $params = [], $addHeaders = [])
{
// initialize curl library
$curlHandle = curl_init();
$headers = [
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $access_token,
'Content-type' => 'application/json',
'X-Platform' => 'Prestashop',
];
// Combine headers, prevent override of original headers
$headers = ($headers + $addHeaders);
$curlHeaders = [];
foreach ($headers as $key => $value) {
$curlHeaders[] = $key . ': ' . $value;
}
curl_setopt($curlHandle, CURLOPT_HTTPHEADER, $curlHeaders);
curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curlHandle, CURLOPT_ENCODING, '');
curl_setopt($curlHandle, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($curlHandle, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($curlHandle, CURLOPT_URL, $url);
curl_setopt($curlHandle, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($curlHandle, CURLOPT_TIMEOUT, 30);
curl_setopt($curlHandle, CURLOPT_NOSIGNAL, 1);
curl_setopt($curlHandle, CURLOPT_FAILONERROR, false);
if ($method == 'GET') {
curl_setopt($curlHandle, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($curlHandle, CURLOPT_HTTPGET, true);
curl_setopt($curlHandle, CURLOPT_POST, false);
} elseif ($method == 'POST') {
curl_setopt($curlHandle, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($curlHandle, CURLOPT_POST, true);
// Content type is set to JSON so we can encode our form data this way
curl_setopt($curlHandle, CURLOPT_POSTFIELDS, json_encode($params));
}
return $curlHandle;
}
/**
* Retrieve response regarding a query
*
* @param string $access_token
* @param string $path
* @param array $params
* @param array $addHeaders
*
* @return object
*
* @throws Exception
*/
public static function getResponse($access_token, $path, $method = 'GET', $params = [], $addHeaders = [], $module_source = 'prestamodule')
{
if ($module_source == 'prestamodule') {
// Create URL
$url = self::API_URL . $path;
} elseif ($module_source == 'addons') {
$url = $path;
}
if (count($params) && $method == 'GET') {
$url .= '?' . http_build_query($params);
}
// Retrieve CURL handle
$curlHandle = self::getCurlHandle($access_token, $url, $method, $params, $addHeaders);
$errorNb = $errorMessage = null;
$response = curl_exec($curlHandle);
$httpCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
if ($response === false) {
$errorNb = curl_errno($curlHandle);
$errorMessage = curl_error($curlHandle);
curl_close($curlHandle);
} else {
$response = json_decode($response);
}
if ($httpCode == 200 || ($module_source = 'addons' && $httpCode == 404)) { // we have to test 404 for use case when customer doesn't exist or subscription doesn't exist
return $response;
} elseif ($httpCode == 429) {
throw new \Exception('Error Processing Request - Too many requests', 2);
} elseif ($httpCode == 403) {
return $httpCode;
} elseif ($httpCode == 419) {
throw new \Exception('Error Processing CSRF Token Request - Server error', 4);
} elseif ($httpCode == 500) {
throw new \Exception('Error Processing Request - Server error', 5);
} elseif ($httpCode == 504) {
throw new \Exception('Error Processing Request - Timeout', 6);
} elseif (empty($httpCode)) {
throw new \Exception(sprintf('Error Processing Request - Unknown - %s', $errorMessage), 7);
} elseif ($httpCode == 401) { // Happen when the Oauth didn't work
// Attempt to refresh the token if it's expired
$refreshedToken = self::refreshToken();
if ($refreshedToken === false) {
\Configuration::updateValue('PVR_OAUTH', []);
\Configuration::updateValue('PVR_RBM_SUB_ID', null);
\Configuration::updateValue('PVR_API_SHOP_ID', null);
return \Tools::redirectAdmin(\Context::getContext()->link->getAdminLink('AdminModules') . '&configure=pmproductvideoreviews');
}
// If we were able to refresh the token, try again
return self::getResponse($refreshedToken, $path, $method, $params, $addHeaders, $module_source);
}
throw new \Exception("Error Processing Request - HTTP Code $httpCode", 1);
}
/**
* Update configuration
*
* @param string $access_token
* @param array $configuration
*
* @return object
*/
public static function updateModuleConfigurationForGis($access_token, $aConfiguration)
{
if (empty($access_token)) {
return false;
}
$response = self::getResponse($access_token, 'api/module/configuration', 'POST', $aConfiguration);
if (!empty($response->result)) {
return true;
}
return false;
}
/**
* Send data to Gis
*
* @param string $access_token
* @param string $data
*
* @return object
*/
public static function sendReviewData($access_token, $data)
{
if (empty($access_token)) {
return false;
}
$response = self::getResponse($access_token, 'api/reviews', 'POST', $data);
if (!empty($response->result)) {
return $response->recorderUrl;
}
return true;
}
/**
* get the review data from apo
*
* @param string $access_token
* @param string $data
*
* @return object
*/
public static function getReviewData($access_token, $data = [])
{
if (empty($access_token)) {
return false;
}
$response = self::getResponse($access_token, 'api/reviews', 'GET', $data);
if (isset($response->reviews)) {
return $response->reviews;
}
return [];
}
/**
* Update review data on our API
*
* @param string $access_token
* @param string $reviewIdApi
* @param string $data
*
* @return object
*/
public static function updateReviewData($access_token, $reviewIdApi, $data)
{
if (empty($access_token)) {
return false;
}
$response = self::getResponse($access_token, 'api/reviews/' . $reviewIdApi, 'POST', $data);
if (!empty($response->result)) {
return true;
}
return true;
}
/**
* get the Api shop
*
* @param string $access_token
*
* @return object
*/
public static function getShop($access_token, $data = [])
{
if (empty($access_token)) {
return false;
}
$response = self::getResponse($access_token, 'api/shop', 'GET', $data);
if (!empty($response->result)) {
return $response->shop;
}
return false;
}
/**
* Update review data on our API
*
* @param string $access_token
* @param string $reviewIdApi
* @param string $data
*
* @return object
*/
public static function getUpdatedReview($access_token, $reviewIdApi, $data)
{
if (empty($access_token)) {
return false;
}
$response = self::getResponse($access_token, 'api/reviews/updated/' . $reviewIdApi, 'GET', $data);
if (!empty($response->result)) {
return $response->review;
}
return true;
}
/**
* Send publish review to api
*
* @param string $access_token
* @param string $reviewIdApi
* @param string $data
*
* @return object
*/
public static function getReview($access_token, $reviewIdApi, $data = [])
{
if (empty($access_token)) {
return false;
}
$response = self::getResponse($access_token, 'api/reviews/' . $reviewIdApi, 'GET', $data);
if (!empty($response->review)) {
return $response->review;
}
return true;
}
/**
* Send publish review to api
*
* @param string $access_token
* @param string $reviewIdApi
* @param string $data
*
* @return object
*/
public static function publishReview($access_token, $reviewIdApi, $data = [])
{
if (empty($access_token)) {
return false;
}
$response = self::getResponse($access_token, 'api/reviews/' . $reviewIdApi . '/publish', 'POST', $data);
if (!empty($response->result)) {
return true;
}
return true;
}
/**
* Send unpublish review to api
*
* @param string $access_token
* @param string $reviewIdApi
* @param string $data
*
* @return object
*/
public static function unpublishReview($access_token, $reviewIdApi, $data = [])
{
if (empty($access_token)) {
return false;
}
$response = self::getResponse($access_token, 'api/reviews/' . $reviewIdApi . '/unpublish', 'POST', $data);
if (!empty($response->result)) {
return true;
}
return true;
}
/**
* Send data to Gis on update status
*
* @param string $access_token
* @param string $data
*
* @return object
*/
public static function sendUpdateStatus($access_token, $data)
{
if (empty($access_token)) {
return false;
}
$response = self::getResponse($access_token, 'api/orders/status', 'POST', $data);
if (!empty($response->result)) {
return true;
}
return true;
}
/**
* Send data to Gis on voucher information
*
* @param string $access_token
* @param string $data
*
* @return object
*/
public static function sendVoucher($access_token, $data)
{
if (empty($access_token)) {
return false;
}
$response = self::getResponse($access_token, 'api/orders/voucher', 'POST', $data);
if (!empty($response->result)) {
return true;
}
return true;
}
/**
* Send data the order data information to handle email scheduler
*
* @param string $access_token
* @param string $data
*
* @return object
*/
public static function sendOrderData($access_token, $data)
{
if (empty($access_token)) {
return false;
}
$response = self::getResponse($access_token, 'api/orders', 'POST', $data);
if (!empty($response->result)) {
return true;
}
return true;
}
/**
* Send data the order data information to handle email scheduler
*
* @param string $access_token
* @param string $data
*
* @return object
*/
public static function getOrderData($access_token, $data)
{
if (empty($access_token)) {
return false;
}
$response = self::getResponse($access_token, 'api/orders', 'GET', $data);
if (!empty($response->orders)) {
return $response->orders;
}
return [];
}
/**
* Revoke the access token
*
* @param string $access_token
* @param string $data
*
* @return object
*/
public static function revoke($access_token, $data)
{
if (empty($access_token)) {
return false;
}
$response = self::getResponse($access_token, 'api/module/revoke', 'POST', $data);
if (!empty($response->result)) {
return true;
}
return false;
}
/**
* Generates our code verifier for the oAuth process
*
* @param int $length
*
* @return string
*/
public static function codeVerifierGen($length = 128)
{
$bytes = openssl_random_pseudo_bytes($length);
$position = 0;
$result = '';
$str = 'abcdefghijkmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~';
for ($i = 0; $i < $length; ++$i) {
$position = ($position + ord($bytes[$i])) % strlen($str);
$result .= $str[$position];
}
return $result;
}
/**
* Creates a code challenge based on the provided verifier string
*
* @param string $verifier
*
* @return string
*/
public static function createCodeChallengeFromVerifier($verifier)
{
return strtr(rtrim(base64_encode(hash('sha256', $verifier, true)), '='), '+/', '-_');
}
/**
* Setter for the access token
*
* @param string $access_token
*
* @return $this
*/
public function setAccessToken($access_token)
{
$this->access_token = $access_token;
return $this;
}
/**
* Get the access token
*
* @param string $authorizationCode
* @param string $redirectUri
* @param string $clientId
* @param string $codeVerifier
*
* @return object|null
*/
public function getAccessToken($authorizationCode, $redirectUri, $clientId, $codeVerifier)
{
$response = $this->getResponse($this->access_token, 'oauth/token', 'POST', [
'grant_type' => 'authorization_code',
'client_id' => $clientId,
'code_verifier' => $codeVerifier,
'redirect_uri' => $redirectUri,
'code' => $authorizationCode,
]);
if (!empty($response) && !empty($response->token_type && !empty($response->access_token))) {
return $response;
}
return null;
}
/**
* Refreshes the oAuth token using the stored refresh token
*
* @return bool
*/
public static function refreshToken()
{
$oAuthConfig = json_decode(\Configuration::get('PVR_OAUTH'), true);
if (empty($oAuthConfig)
|| empty($oAuthConfig['refresh_token'])
|| empty($oAuthConfig['clientId'])
|| empty($oAuthConfig['codeVerifier'])
) {
return false;
}
$response = self::getResponse('', 'oauth/token', 'POST', [
'grant_type' => 'refresh_token',
'refresh_token' => $oAuthConfig['refresh_token'],
'client_id' => $oAuthConfig['clientId'],
'code_verifier' => $oAuthConfig['codeVerifier'],
]);
if (!empty($response) && !empty($response->token_type && !empty($response->access_token))) {
// Store new values
$oAuthConfig['access_token'] = $response->access_token;
$oAuthConfig['expires_in'] = time() + $response->expires_in;
$oAuthConfig['refresh_token'] = $response->refresh_token;
$oAuthConfig['token_type'] = $response->token_type;
\Configuration::updateValue('PVR_OAUTH', json_encode($oAuthConfig));
return $response->access_token;
}
return false;
}
/**
* Get the access token
*
* @param string $rbmSubscriptionId
*
* @return object|null
*/
public function getAccessTokenRbm($rbmSubscriptionId)
{
$response = '';
if (self::MODULE_SOURCE == 'addons') {
$response = $this->getResponse('', 'oauth/token', 'POST', [
'grant_type' => 'client_credentials',
'client_id' => self::CLIENT_ID,
'client_secret' => self::SECRET_ID,
'rbmSubscriptionId' => $rbmSubscriptionId,
]);
}
if (!empty($response) && !empty($response->token_type && !empty($response->access_token))) {
return $response;
}
return null;
}
/**
* Get rbm subscription id
*
* @param string $psToken
* @param string $psCustomerId
*
* @return int
*/
public static function getRmbSubscriptionId($psToken, $psCustomerId)
{
$response = '';
if (self::MODULE_SOURCE == 'addons') {
$response = self::getResponse($psToken, self::RBM_PATH . $psCustomerId . '/subscriptions/pmproductvideoreviews', 'GET', [], [], 'addons');
}
if (!empty($response->id)) {
return $response->id;
}
return null;
}
/**
* Performs the request to create a limited trial subscription to our API
*
* @param array $data
*
* @return mixed
*/
public function createLimitedTrialSubscription($data)
{
if (self::MODULE_SOURCE != 'addons') {
return;
}
$response = $this->getResponse('', 'api/rbm/subscription/initTrial', 'POST', array_merge(['token' => self::RBM_TOKEN], $data));
if (!empty($response->result) && !empty($response->subscription) && !empty($response->shop)) {
return [
'subscription' => $response->subscription,
'shop' => $response->shop,
];
}
return null;
}
}