diff --git a/controllers/front/token.php b/controllers/front/token.php index e315d37be..c6e69beb6 100644 --- a/controllers/front/token.php +++ b/controllers/front/token.php @@ -18,66 +18,37 @@ * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 */ +use PrestaShop\Module\PrestashopCheckout\CommandBus\CommandBusInterface; use PrestaShop\Module\PrestashopCheckout\Controller\AbstractFrontController; -use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalClientTokenProvider; +use PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\Query\GetPayPalGetUserIdTokenQuery; +use PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\Query\GetPayPalGetUserIdTokenQueryResult; +use Psr\Log\LoggerInterface; /** - * This controller receive ajax call to retrieve a PayPal Client Token + * This controller receive ajax call to retrieve a PayPal User Id Token */ class Ps_CheckoutTokenModuleFrontController extends AbstractFrontController { - /** - * @var Ps_checkout - */ - public $module; - /** * @see FrontController::postProcess() - * - * @todo Move logic to a Service and refactor */ public function postProcess() { try { - if (false === Validate::isLoadedObject($this->context->cart)) { - $this->exitWithResponse([ - 'httpCode' => 400, - 'body' => 'No cart found.', - ]); - } - - /** @var PayPalClientTokenProvider $clientTokenProvider */ - $clientTokenProvider = $this->module->getService('ps_checkout.paypal.provider.client_token'); - - /** @var \PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository $psCheckoutCartRepository */ - $psCheckoutCartRepository = $this->module->getService('ps_checkout.repository.pscheckoutcart'); - - /** @var PsCheckoutCart|false $psCheckoutCart */ - $psCheckoutCart = $psCheckoutCartRepository->findOneByCartId((int) $this->context->cart->id); - - if (false === $psCheckoutCart) { - $psCheckoutCart = new PsCheckoutCart(); - $psCheckoutCart->id_cart = (int) $this->context->cart->id; - } - - if ($psCheckoutCart->isPaypalClientTokenExpired()) { - $psCheckoutCart->paypal_order = ''; - $psCheckoutCart->paypal_token = $clientTokenProvider->getPayPalClientToken(); - $psCheckoutCart->paypal_token_expire = (new DateTime())->modify('+3550 seconds')->format('Y-m-d H:i:s'); - $psCheckoutCartRepository->save($psCheckoutCart); - } + /** @var CommandBusInterface $commandBus */ + $commandBus = $this->module->getService('ps_checkout.bus.command'); + /** @var GetPayPalGetUserIdTokenQueryResult $getPayPalGetUserIdTokenQueryResult */ + $getPayPalGetUserIdTokenQueryResult = $commandBus->handle(new GetPayPalGetUserIdTokenQuery($this->getCustomerId())); $this->exitWithResponse([ 'status' => true, 'httpCode' => 200, 'body' => [ - 'token' => $psCheckoutCart->paypal_token, + 'token' => $getPayPalGetUserIdTokenQueryResult->getUserIdToken(), ], - 'exceptionCode' => null, - 'exceptionMessage' => null, ]); } catch (Exception $exception) { - /* @var \Psr\Log\LoggerInterface logger */ + /** @var LoggerInterface $logger */ $logger = $this->module->getService('ps_checkout.logger'); $logger->error( sprintf( diff --git a/src/Controller/AbstractFrontController.php b/src/Controller/AbstractFrontController.php index f58cb7169..a3b9a7919 100644 --- a/src/Controller/AbstractFrontController.php +++ b/src/Controller/AbstractFrontController.php @@ -22,11 +22,15 @@ use Exception; use ModuleFrontController; +use PrestaShop\Module\PrestashopCheckout\Customer\Exception\CustomerException; +use PrestaShop\Module\PrestashopCheckout\Customer\ValueObject\CustomerId; +use Ps_checkout; +use Tools; class AbstractFrontController extends ModuleFrontController { /** - * @var \Ps_checkout + * @var Ps_checkout */ public $module; @@ -68,4 +72,30 @@ protected function exitWithResponse(array $response = []) exit; } + + /** + * @return CustomerId|null + * + * @throws CustomerException + */ + protected function getCustomerId() + { + return $this->context->customer->isLogged() ? new CustomerId($this->context->customer->id) : null; + } + + /** + * @return int + */ + protected function getPageSize() + { + return (int) Tools::getValue('pageSize', 10); + } + + /** + * @return int + */ + protected function getPageNumber() + { + return (int) Tools::getValue('pageNumber', 1); + } } diff --git a/src/Database/TableManager.php b/src/Database/TableManager.php index 501385036..319b4a790 100644 --- a/src/Database/TableManager.php +++ b/src/Database/TableManager.php @@ -80,6 +80,20 @@ public function createTable() PRIMARY KEY (`name`, `id_shop`), INDEX (`id_shop`) ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; + ') && $this->db->execute(' + CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pscheckout_customer` ( + `id_customer` int unsigned NOT NULL, + `paypal_customer_id` varchar(50) NOT NULL, + PRIMARY KEY (`id_customer`, `paypal_customer_id`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; + ') && $this->db->execute(' + CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pscheckout_payment_token` ( + `id` varchar(50) NOT NULL, + `paypal_customer_id` varchar(50) NOT NULL, + `payment_source` varchar(50) NOT NULL, + `data` text NOT NULL, + PRIMARY KEY (`id_customer`, `paypal_customer_id`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; '); $this->checkTable(); diff --git a/src/PayPal/Customer/PayPalCustomerRepository.php b/src/PayPal/Customer/PayPalCustomerRepository.php new file mode 100644 index 000000000..2fad8188b --- /dev/null +++ b/src/PayPal/Customer/PayPalCustomerRepository.php @@ -0,0 +1,88 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\Customer; + +use Db; +use DbQuery; +use Exception; +use PrestaShop\Module\PrestashopCheckout\Customer\ValueObject\CustomerId; +use PrestaShop\Module\PrestashopCheckout\PayPal\Customer\ValueObject\PayPalCustomerId; + +class PayPalCustomerRepository +{ + /** + * @var Db + */ + private $db; + + /** + * @param Db $db + */ + public function __construct(Db $db) + { + $this->db = $db; + } + + /** + * @param CustomerId $customerId + * + * @return PayPalCustomerId|null + * + * @throws Exception + */ + public function findPayPalCustomerIdByCustomerId(CustomerId $customerId) + { + try { + $query = new DbQuery(); + $query->select('`paypal_customer_id`'); + $query->from('pscheckout_customer'); + $query->where('`id_customer` = ' . (int) $customerId->getValue()); + $customerIdPayPal = $this->db->getValue($query); + + return $customerIdPayPal ? new PayPalCustomerId($customerIdPayPal) : null; + } catch (Exception $exception) { + throw new Exception('Failed to find PayPal Customer ID', 0, $exception); + } + } + + /** + * @param CustomerId $customerId + * @param PayPalCustomerId $paypalCustomerId + * + * @return void + * + * @throws Exception + */ + public function save(CustomerId $customerId, PayPalCustomerId $paypalCustomerId) + { + try { + $this->db->insert( + 'pscheckout_customer', + [ + 'id_customer' => (int) $customerId->getValue(), + 'paypal_customer_id' => pSQL($paypalCustomerId->getValue()), + ] + ); + } catch (Exception $exception) { + throw new Exception('Failed to save PayPal Customer ID', 0, $exception); + } + } +} diff --git a/src/PayPal/OAuth/OAuthService.php b/src/PayPal/OAuth/OAuthService.php new file mode 100644 index 000000000..cba28d6c3 --- /dev/null +++ b/src/PayPal/OAuth/OAuthService.php @@ -0,0 +1,66 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\OAuth; + +use Exception; +use GuzzleHttp\Psr7\Request; +use PrestaShop\Module\PrestashopCheckout\PayPal\Customer\ValueObject\PayPalCustomerId; + +class OAuthService +{ + private $httpClient; + + public function __construct($httpClient) + { + $this->httpClient = $httpClient; + } + + /** + * @param PayPalCustomerId|null $customerId + * + * @return string + * + * @throws Exception + */ + public function getUserIdToken(PayPalCustomerId $customerId = null) + { + try { + $body = 'grant_type=client_credentials&response_type=id_token'; + + if ($customerId) { + $body .= '&target_customer_id=' . $customerId->getValue(); + } + + $request = new Request('POST', '', [], $body); + $response = $this->httpClient->sendRequest($request); + + $data = json_decode($response->getBody()->getContents(), true); + + if (empty($data['id_token'])) { + throw new Exception('Failed to get PayPal User ID token from response.'); + } + + return $data['id_token']; + } catch (Exception $exception) { + throw new Exception('Failed to get PayPal User ID token.', 0, $exception); + } + } +} diff --git a/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQuery.php b/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQuery.php new file mode 100644 index 000000000..5d94ff131 --- /dev/null +++ b/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQuery.php @@ -0,0 +1,47 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\Query; + +use PrestaShop\Module\PrestashopCheckout\Customer\ValueObject\CustomerId; + +class GetPayPalGetUserIdTokenQuery +{ + /** + * @var CustomerId|null + */ + private $customerId; + + /** + * @param CustomerId|null $customerId + */ + public function __construct(CustomerId $customerId = null) + { + $this->customerId = $customerId; + } + + /** + * @return CustomerId|null + */ + public function getCustomerId() + { + return $this->customerId; + } +} diff --git a/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQueryHandler.php b/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQueryHandler.php new file mode 100644 index 000000000..cd410218e --- /dev/null +++ b/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQueryHandler.php @@ -0,0 +1,62 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\Query; + +use Exception; +use PrestaShop\Module\PrestashopCheckout\PayPal\Customer\PayPalCustomerRepository; +use PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\OAuthService; + +class GetPayPalGetUserIdTokenQueryHandler +{ + /** + * @var OAuthService + */ + private $OAuthService; + + /** + * @var PayPalCustomerRepository + */ + private $customerRepository; + + /** + * @param OAuthService $OAuthService + * @param PayPalCustomerRepository $customerRepository + */ + public function __construct(OAuthService $OAuthService, PayPalCustomerRepository $customerRepository) + { + $this->OAuthService = $OAuthService; + $this->customerRepository = $customerRepository; + } + + /** + * @param GetPayPalGetUserIdTokenQuery $query + * + * @return GetPayPalGetUserIdTokenQueryResult + * + * @throws Exception + */ + public function handle(GetPayPalGetUserIdTokenQuery $query) + { + $customerIdPayPal = $query->getCustomerId() ? $this->customerRepository->findPayPalCustomerIdByCustomerId($query->getCustomerId()) : null; + + return new GetPayPalGetUserIdTokenQueryResult($this->OAuthService->getUserIdToken($customerIdPayPal)); + } +} diff --git a/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQueryResult.php b/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQueryResult.php new file mode 100644 index 000000000..e3a3f4a9b --- /dev/null +++ b/src/PayPal/OAuth/Query/GetPayPalGetUserIdTokenQueryResult.php @@ -0,0 +1,45 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PrestaShop\Module\PrestashopCheckout\PayPal\OAuth\Query; + +class GetPayPalGetUserIdTokenQueryResult +{ + /** + * @var string + */ + private $userIdToken; + + /** + * @param string $userIdToken + */ + public function __construct($userIdToken) + { + $this->userIdToken = $userIdToken; + } + + /** + * @return string + */ + public function getUserIdToken() + { + return $this->userIdToken; + } +}