Current File : /var/www/prestashop/modules/ps_checkout/controllers/admin/AdminAjaxPrestashopCheckoutController.php |
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
use Monolog\Logger;
use PrestaShop\Module\PrestashopCheckout\CommandBus\CommandBusInterface;
use PrestaShop\Module\PrestashopCheckout\Configuration\BatchConfigurationProcessor;
use PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration;
use PrestaShop\Module\PrestashopCheckout\Exception\PayPalException;
use PrestaShop\Module\PrestashopCheckout\ExpressCheckout\ExpressCheckoutConfiguration;
use PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceConfigurationRepository;
use PrestaShop\Module\PrestashopCheckout\FundingSource\FundingSourceTranslationProvider;
use PrestaShop\Module\PrestashopCheckout\Http\MaaslandHttpClient;
use PrestaShop\Module\PrestashopCheckout\Logger\LoggerDirectory;
use PrestaShop\Module\PrestashopCheckout\Logger\LoggerFactory;
use PrestaShop\Module\PrestashopCheckout\Logger\LoggerFileFinder;
use PrestaShop\Module\PrestashopCheckout\Logger\LoggerFileReader;
use PrestaShop\Module\PrestashopCheckout\OnBoarding\Step\LiveStep;
use PrestaShop\Module\PrestashopCheckout\OnBoarding\Step\ValueBanner;
use PrestaShop\Module\PrestashopCheckout\Order\Exception\OrderException;
use PrestaShop\Module\PrestashopCheckout\Order\State\Exception\OrderStateException;
use PrestaShop\Module\PrestashopCheckout\Order\State\OrderStateInstaller;
use PrestaShop\Module\PrestashopCheckout\Order\State\Service\OrderStateMapper;
use PrestaShop\Module\PrestashopCheckout\PayPal\Mode;
use PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\Command\RefundPayPalCaptureCommand;
use PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\Exception\PayPalRefundException;
use PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\Exception\PayPalRefundFailedException;
use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration;
use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalOrderProvider;
use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalPayLaterConfiguration;
use PrestaShop\Module\PrestashopCheckout\Presenter\Order\OrderPresenter;
use PrestaShop\Module\PrestashopCheckout\Repository\PaymentTokenRepository;
use PrestaShop\Module\PrestashopCheckout\Repository\PsAccountRepository;
use PrestaShop\Module\PrestashopCheckout\Settings\RoundingSettings;
use PrestaShop\Module\PrestashopCheckout\Validator\BatchConfigurationValidator;
use PrestaShop\Module\PrestashopCheckout\Webhook\WebhookSecretTokenService;
class AdminAjaxPrestashopCheckoutController extends ModuleAdminController
{
/**
* @var Ps_checkout
*/
public $module;
/**
* @var bool
*/
public $ajax = true;
/**
* @var bool
*/
protected $json = true;
/**
* {@inheritDoc}
*/
public function postProcess()
{
$shopIdRequested = (int) Tools::getValue('id_shop');
$currentShopId = (int) Shop::getContextShopID();
if ($shopIdRequested && $shopIdRequested !== $currentShopId) {
$shopRequested = new Shop($shopIdRequested);
if (Validate::isLoadedObject($shopRequested)) {
Shop::setContext(Shop::CONTEXT_SHOP, $shopIdRequested);
$this->context->shop = $shopRequested;
}
}
return parent::postProcess();
}
/**
* AJAX: Update payment method order
*/
public function ajaxProcessUpdatePaymentMethodsOrder()
{
$paymentOptions = json_decode(Tools::getValue('paymentMethods'), true);
/** @var FundingSourceConfigurationRepository $fundingSourceConfigurationRepository */
$fundingSourceConfigurationRepository = $this->module->getService(FundingSourceConfigurationRepository::class);
foreach ($paymentOptions as $key => $paymentOption) {
$paymentOption['position'] = $key + 1;
$fundingSourceConfigurationRepository->save($paymentOption);
}
$this->ajaxDie(json_encode(true));
}
/**
* AJAX: Update payment mode (LIVE or SANDBOX)
*/
public function ajaxProcessUpdatePaymentMode()
{
/** @var PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration $paypalConfiguration */
$paypalConfiguration = $this->module->getService(PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration::class);
$paypalConfiguration->setPaymentMode(Tools::getValue('paymentMode'));
$this->ajaxDie(json_encode(true));
}
/**
* AJAX: Confirm PS Live Step Banner closed
*/
public function ajaxProcessLiveStepConfirmed()
{
/** @var LiveStep $stepLive */
$stepLive = $this->module->getService(LiveStep::class);
$stepLive->confirmed(true);
$this->ajaxDie(json_encode(true));
}
/**
* AJAX: Confirm PS Live Step fist time
*/
public function ajaxProcessLiveStepViewed()
{
/** @var LiveStep $stepLive */
$stepLive = $this->module->getService(LiveStep::class);
$stepLive->viewed(true);
$this->ajaxDie(json_encode(true));
}
/**
* AJAX: Confirm PS Value Banner closed
*/
public function ajaxProcessValueBannerClosed()
{
/** @var ValueBanner $valueBanner */
$valueBanner = $this->module->getService(ValueBanner::class);
$valueBanner->closed(true);
$this->ajaxDie(json_encode(true));
}
/**
* AJAX: Change prestashop rounding settings
*
* PS_ROUND_TYPE need to be set to 1 (Round on each item)
* PS_PRICE_ROUND_MODE need to be set to 2 (Round up away from zero, wh
*/
public function ajaxProcessEditRoundingSettings()
{
/** @var PayPalConfiguration $paypalConfiguration */
$paypalConfiguration = $this->module->getService(PayPalConfiguration::class);
$paypalConfiguration->setRoundType(RoundingSettings::ROUND_ON_EACH_ITEM);
$paypalConfiguration->setPriceRoundMode(RoundingSettings::ROUND_UP_AWAY_FROM_ZERO);
$this->ajaxDie(json_encode(true));
}
/**
* @deprecated No more used
*/
public function ajaxProcessGetReportingDatas()
{
$this->ajaxDie(
json_encode([
'orders' => [],
'transactions' => [],
])
);
}
/**
* AJAX: Toggle payment option hosted fields availability
*/
public function ajaxProcessTogglePaymentOptionAvailability()
{
$paymentOption = json_decode(Tools::getValue('paymentOption'), true);
/** @var FundingSourceConfigurationRepository $fundingSourceConfigurationRepository */
$fundingSourceConfigurationRepository = $this->module->getService(FundingSourceConfigurationRepository::class);
$fundingSourceConfigurationRepository->save($paymentOption);
$this->ajaxDie(json_encode(true));
}
/**
* AJAX: Update credit card fields (Hosted fields / Smartbutton)
*/
public function ajaxProcessUpdateCreditCardFields()
{
/** @var PayPalConfiguration $paypalConfiguration */
$paypalConfiguration = $this->module->getService(PayPalConfiguration::class);
$paypalConfiguration->setCardPaymentEnabled((bool) Tools::getValue('hostedFieldsEnabled'));
$this->ajaxDie(json_encode(true));
}
/**
* AJAX: Toggle express checkout on order page
*/
public function ajaxProcessToggleECOrderPage()
{
/** @var ExpressCheckoutConfiguration $ecConfiguration */
$ecConfiguration = $this->module->getService(ExpressCheckoutConfiguration::class);
$ecConfiguration->setOrderPage((bool) Tools::getValue('status'));
$this->updateExpressCheckoutSettings();
$this->ajaxDie(json_encode(true));
}
/**
* AJAX: Toggle express checkout on checkout page
*/
public function ajaxProcessToggleECCheckoutPage()
{
/** @var ExpressCheckoutConfiguration $ecConfiguration */
$ecConfiguration = $this->module->getService(ExpressCheckoutConfiguration::class);
$ecConfiguration->setCheckoutPage(Tools::getValue('status') ? true : false);
$this->updateExpressCheckoutSettings();
$this->ajaxDie(json_encode(true));
}
/**
* AJAX: Toggle express checkout on product page
*/
public function ajaxProcessToggleECProductPage()
{
/** @var ExpressCheckoutConfiguration $ecConfiguration */
$ecConfiguration = $this->module->getService(ExpressCheckoutConfiguration::class);
$ecConfiguration->setProductPage(Tools::getValue('status') ? true : false);
$this->updateExpressCheckoutSettings();
$this->ajaxDie(json_encode(true));
}
/**
* @return void
*
* @throws PayPalException
*/
private function updateExpressCheckoutSettings()
{
/** @var PrestaShopConfiguration $configuration */
$configuration = $this->module->getService(PrestaShopConfiguration::class);
/** @var ExpressCheckoutConfiguration $ecConfiguration */
$ecConfiguration = $this->module->getService(ExpressCheckoutConfiguration::class);
/** @var MaaslandHttpClient $maaslandHttpClient */
$maaslandHttpClient = $this->module->getService(MaaslandHttpClient::class);
$maaslandHttpClient->updateSettings([
'settings' => [
'cb' => (bool) $configuration->get('PS_CHECKOUT_CARD_PAYMENT_ENABLED'),
'express_in_product' => (bool) $ecConfiguration->isProductPageEnabled(),
'express_in_cart' => (bool) $ecConfiguration->isOrderPageEnabled(),
'express_in_checkout' => (bool) $ecConfiguration->isCheckoutPageEnabled(),
],
]);
}
/**
* AJAX: Toggle pay later message on order page
*/
public function ajaxProcessTogglePayLaterOrderPageMessage()
{
$this->togglePayLaterConfiguration('setOrderPageMessage');
}
/**
* AJAX: Toggle pay later message on product page
*/
public function ajaxProcessTogglePayLaterProductPageMessage()
{
$this->togglePayLaterConfiguration('setProductPageMessage');
}
/**
* AJAX: Toggle pay later banner on cart page
*/
public function ajaxProcessTogglePayLaterOrderPageBanner()
{
$this->togglePayLaterConfiguration('setOrderPageBanner');
}
/**
* AJAX: Toggle pay later banner on product page
*/
public function ajaxProcessTogglePayLaterProductPageBanner()
{
$this->togglePayLaterConfiguration('setProductPageBanner');
}
/**
* AJAX: Toggle pay later banner on home page
*/
public function ajaxProcessTogglePayLaterHomePageBanner()
{
$this->togglePayLaterConfiguration('setHomePageBanner');
}
/**
* AJAX: Toggle pay later banner on category page
*/
public function ajaxProcessTogglePayLaterCategoryPageBanner()
{
$this->togglePayLaterConfiguration('setCategoryPageBanner');
}
/**
* AJAX: Toggle pay later button on cart page
*/
public function ajaxProcessTogglePayLaterCartPageButton()
{
$this->togglePayLaterConfiguration('setCartPageButton');
}
/**
* AJAX: Toggle pay later button on order page
*/
public function ajaxProcessTogglePayLaterOrderPageButton()
{
$this->togglePayLaterConfiguration('setOrderPageButton');
}
/**
* AJAX: Toggle pay later button on product page
*/
public function ajaxProcessTogglePayLaterProductPageButton()
{
$this->togglePayLaterConfiguration('setProductPageButton');
}
/**
* @todo To be refactored with Service Container
*/
public function ajaxProcessFetchOrder()
{
$isLegacy = (bool) Tools::getValue('legacy');
$id_order = (int) Tools::getValue('id_order');
if (empty($id_order)) {
http_response_code(400);
$this->ajaxDie(json_encode([
'status' => false,
'errors' => [
$this->l('No PrestaShop Order identifier received'),
],
]));
}
$order = new Order($id_order);
if ($order->module !== $this->module->name) {
http_response_code(400);
$this->ajaxDie(json_encode([
'status' => false,
'errors' => [
strtr(
$this->l('This PrestaShop Order [PRESTASHOP_ORDER_ID] is not paid with PrestaShop Checkout'),
[
'[PRESTASHOP_ORDER_ID]' => $order->id,
]
),
],
]));
}
$psCheckoutCartCollection = new PrestaShopCollection('PsCheckoutCart');
$psCheckoutCartCollection->where('id_cart', '=', (int) $order->id_cart);
$psCheckoutCartCollection->orderBy('date_upd', 'ASC');
if (!$psCheckoutCartCollection->count()) {
http_response_code(500);
$this->ajaxDie(json_encode([
'status' => false,
'errors' => [
strtr(
$this->l('Unable to find PayPal Order associated to this PrestaShop Order [PRESTASHOP_ORDER_ID]'),
[
'[PRESTASHOP_ORDER_ID]' => $order->id,
]
),
],
]));
}
$psCheckoutCart = null;
foreach ($psCheckoutCartCollection->getResults() as $psCheckoutCart) {
/** @var PsCheckoutCart $psCheckoutCart */
if ($psCheckoutCart->getPaypalStatus() === PsCheckoutCart::STATUS_COMPLETED) {
break;
}
}
/** @var PayPalConfiguration $configurationPayPal */
$configurationPayPal = $this->module->getService(PayPalConfiguration::class);
if ($configurationPayPal->getPaymentMode() !== $psCheckoutCart->getEnvironment()) {
http_response_code(422);
$this->ajaxDie(json_encode([
'status' => false,
'errors' => [
strtr(
$this->l('PayPal Order [PAYPAL_ORDER_ID] is not in the same environment as PrestaShop Checkout'),
[
'[PAYPAL_ORDER_ID]' => $psCheckoutCart->paypal_order,
]
),
],
]));
}
/** @var PayPalOrderProvider $paypalOrderProvider */
$paypalOrderProvider = $this->module->getService(PayPalOrderProvider::class);
try {
$paypalOrder = $paypalOrderProvider->getById($psCheckoutCart->paypal_order);
} catch (Exception $exception) {
$paypalOrder = [];
}
if ($paypalOrder === false) {
$paypalOrder = [];
}
/** @var FundingSourceTranslationProvider $fundingSourceTranslationProvider */
$fundingSourceTranslationProvider = $this->module->getService(FundingSourceTranslationProvider::class);
$presenter = new OrderPresenter($this->module, $paypalOrder);
$this->context->smarty->assign([
'moduleName' => $this->module->displayName,
'moduleUrl' => $this->context->link->getAdminLink('AdminModules', true, [], ['configure' => 'ps_checkout']),
'orderPayPal' => $presenter->present(),
'orderPayPalBaseUrl' => $this->context->link->getAdminLink('AdminAjaxPrestashopCheckout'),
'moduleLogoUri' => $this->module->getPathUri() . 'logo.png',
'orderPaymentDisplayName' => $fundingSourceTranslationProvider->getPaymentMethodName($psCheckoutCart->paypal_funding),
'orderPaymentLogoUri' => $this->module->getPathUri() . 'views/img/' . $psCheckoutCart->paypal_funding . '.svg',
'psCheckoutCart' => $psCheckoutCart,
'isProductionEnv' => $psCheckoutCart->getEnvironment() === Mode::LIVE,
]);
$this->ajaxDie(json_encode([
'status' => true,
'content' => $isLegacy
? $this->context->smarty->fetch($this->module->getLocalPath() . 'views/templates/admin/ajaxPayPalOrderLegacy.tpl')
: $this->context->smarty->fetch($this->module->getLocalPath() . 'views/templates/admin/ajaxPayPalOrder.tpl'),
]));
}
/**
* @todo To be refactored with Service Container
*/
public function ajaxProcessRefundOrder()
{
$orderPayPalId = Tools::getValue('orderPayPalRefundOrder');
$captureId = Tools::getValue('orderPayPalRefundTransaction');
$amount = Tools::getValue('orderPayPalRefundAmount');
$currency = Tools::getValue('orderPayPalRefundCurrency');
/** @var CommandBusInterface $commandBus */
$commandBus = $this->module->getService('ps_checkout.bus.command');
try {
$commandBus->handle(new RefundPayPalCaptureCommand($orderPayPalId, $captureId, $currency, $amount));
} catch (PayPalRefundFailedException $exception) {
$this->exitWithResponse([
'httpCode' => $exception->getCode(),
'status' => false,
'errors' => [
$this->l('Refund cannot be processed by PayPal.', 'translations'),
],
]);
} catch (PayPalRefundException $invalidArgumentException) {
$error = '';
switch ($invalidArgumentException->getCode()) {
case PayPalRefundException::INVALID_ORDER_ID:
$error = $this->l('PayPal Order is invalid.', 'translations');
break;
case PayPalRefundException::INVALID_TRANSACTION_ID:
$error = $this->l('PayPal Transaction is invalid.', 'translations');
break;
case PayPalRefundException::INVALID_CURRENCY:
$error = $this->l('PayPal refund currency is invalid.', 'translations');
break;
case PayPalRefundException::INVALID_AMOUNT:
$error = $this->l('PayPal refund amount is invalid.', 'translations');
break;
default:
break;
}
$this->exitWithResponse([
'httpCode' => 400,
'status' => false,
'errors' => [$error],
]);
} catch (OrderException $exception) {
if ($exception->getCode() === OrderException::FAILED_UPDATE_ORDER_STATUS) {
$this->exitWithResponse([
'httpCode' => 200,
'status' => true,
'content' => $this->l('Refund has been processed by PayPal, but order status change or email sending failed.', 'translations'),
]);
} elseif ($exception->getCode() !== OrderException::ORDER_HAS_ALREADY_THIS_STATUS) {
$this->exitWithResponse([
'httpCode' => 500,
'status' => false,
'errors' => [
$exception->getMessage(),
],
'error' => $exception->getMessage(),
]);
}
} catch (Exception $exception) {
$this->exitWithResponse([
'httpCode' => 500,
'status' => false,
'errors' => [
$this->l('Refund cannot be processed by PayPal.', 'translations'),
],
'error' => $exception->getMessage(),
]);
}
$this->exitWithResponse([
'httpCode' => 200,
'status' => true,
'content' => $this->l('Refund has been processed by PayPal.', 'translations'),
]);
}
/**
* @todo To be improved in v2.0.0
*/
public function ajaxProcessUpdateLoggerLevel()
{
$levels = [
Logger::DEBUG,
Logger::INFO,
Logger::NOTICE,
Logger::WARNING,
Logger::ERROR,
Logger::CRITICAL,
Logger::ALERT,
Logger::EMERGENCY,
];
$level = (int) Tools::getValue('level');
if (false === in_array($level, $levels, true)) {
http_response_code(400);
$this->ajaxDie(json_encode([
'status' => false,
'errors' => [
'Logger level is invalid',
],
]));
}
if (false === (bool) Configuration::updateGlobalValue(LoggerFactory::PS_CHECKOUT_LOGGER_LEVEL, $level)) {
http_response_code(500);
$this->ajaxDie(json_encode([
'status' => false,
'errors' => [
'Unable to save logger level in PrestaShop Configuration',
],
]));
}
$this->ajaxDie(json_encode([
'status' => true,
'content' => [
'level' => $level,
],
]));
}
/**
* @todo To be improved in v2.0.0
*/
public function ajaxProcessUpdateLoggerHttpFormat()
{
$formats = [
'CLF',
'DEBUG',
'SHORT',
];
$format = Tools::getValue('httpFormat');
if (false === in_array($format, $formats, true)) {
$this->ajaxDie(json_encode([
'status' => false,
'errors' => [
'Logger http format is invalid',
],
]));
}
if (false === (bool) Configuration::updateGlobalValue(LoggerFactory::PS_CHECKOUT_LOGGER_HTTP_FORMAT, $format)) {
$this->ajaxDie(json_encode([
'status' => false,
'errors' => [
'Unable to save logger http format in PrestaShop Configuration',
],
]));
}
$this->ajaxDie(json_encode([
'status' => true,
'content' => [
'httpFormat' => $format,
],
]));
}
/**
* @todo To be improved in v2.0.0
*/
public function ajaxProcessUpdateLoggerHttp()
{
$isEnabled = (bool) Tools::getValue('isEnabled');
if (false === (bool) Configuration::updateGlobalValue(LoggerFactory::PS_CHECKOUT_LOGGER_HTTP, (int) $isEnabled)) {
http_response_code(500);
$this->ajaxDie(json_encode([
'status' => false,
'errors' => [
'Unable to save logger http in PrestaShop Configuration',
],
]));
}
$this->ajaxDie(json_encode([
'status' => true,
'content' => [
'isEnabled' => (int) $isEnabled,
],
]));
}
/**
* @todo To be improved in v2.0.0
*/
public function ajaxProcessUpdateLoggerMaxFiles()
{
$maxFiles = (int) Tools::getValue('maxFiles');
if ($maxFiles < 0 || $maxFiles > 30) {
http_response_code(400);
$this->ajaxDie(json_encode([
'status' => false,
'errors' => [
'Logger max files is invalid',
],
]));
}
if (false === (bool) Configuration::updateGlobalValue(LoggerFactory::PS_CHECKOUT_LOGGER_MAX_FILES, $maxFiles)) {
http_response_code(500);
$this->ajaxDie(json_encode([
'status' => false,
'errors' => [
'Unable to save logger max files in PrestaShop Configuration',
],
]));
}
$this->ajaxDie(json_encode([
'status' => true,
'content' => [
'maxFiles' => $maxFiles,
],
]));
}
/**
* AJAX: Get logs files
*/
public function ajaxProcessGetLogFiles()
{
/** @var LoggerFileFinder $loggerFileFinder */
$loggerFileFinder = $this->module->getService(LoggerFileFinder::class);
header('Content-type: application/json');
$this->ajaxDie(json_encode($loggerFileFinder->getLogFileNames()));
}
/**
* AJAX: Read a log file
*/
public function ajaxProcessGetLogs()
{
header('Content-type: application/json');
$filename = Tools::getValue('file');
$offset = (int) Tools::getValue('offset');
$limit = (int) Tools::getValue('limit');
if (empty($filename) || false === Validate::isFileName($filename)) {
http_response_code(400);
$this->ajaxDie(json_encode([
'status' => false,
'errors' => [
'Filename is invalid.',
],
]));
}
/** @var LoggerDirectory $loggerDirectory */
$loggerDirectory = $this->module->getService(LoggerDirectory::class);
/** @var LoggerFileReader $loggerFileReader */
$loggerFileReader = $this->module->getService(LoggerFileReader::class);
$fileData = [];
try {
$fileData = $loggerFileReader->read(
new SplFileObject($loggerDirectory->getPath() . $filename),
$offset,
$limit
);
} catch (Exception $exception) {
http_response_code(500);
$this->ajaxDie(json_encode([
'status' => false,
'errors' => [
$exception->getMessage(),
],
]));
}
$this->ajaxDie(json_encode([
'status' => true,
'file' => $fileData['filename'],
'offset' => $fileData['offset'],
'limit' => $fileData['limit'],
'currentOffset' => $fileData['currentOffset'],
'eof' => (int) $fileData['eof'],
'lines' => $fileData['lines'],
]));
}
/**
* AJAX: Save PayPal button configuration
*/
public function ajaxProcessSavePaypalButtonConfiguration()
{
/** @var PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration $paypalConfiguration */
$paypalConfiguration = $this->module->getService(PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration::class);
$paypalConfiguration->setButtonConfiguration(json_decode(Tools::getValue('configuration')));
$this->ajaxDie(json_encode(true));
}
/**
* AJAX: Get or refresh token for CDN application
*/
public function ajaxProcessGetOrRefreshToken()
{
/** @var PsAccountRepository $psAccountRepository */
$psAccountRepository = $this->module->getService(PsAccountRepository::class);
try {
$this->exitWithResponse([
'httpCode' => 200,
'status' => true,
'token' => $psAccountRepository->getIdToken(),
'shopId' => $psAccountRepository->getShopUuid(),
'isAccountLinked' => $psAccountRepository->isAccountLinked(),
]);
} catch (Exception $exception) {
$this->exitWithResponse([
'httpCode' => 500,
'status' => false,
'error' => sprintf(
'%s %d : %s',
get_class($exception),
$exception->getCode(),
$exception->getMessage()
),
]);
}
}
/**
* {@inheritdoc}
*/
public function initCursedPage()
{
http_response_code(401);
exit;
}
/**
* {@inheritdoc}
*/
public function init()
{
if (!isset($this->context->employee) || !$this->context->employee->isLoggedBack()) {
// Avoid redirection to Login page because Ajax doesn't support it
$this->initCursedPage();
}
parent::init();
}
/**
* {@inheritdoc}
*/
protected function isAnonymousAllowed()
{
return false;
}
/**
* {@inheritdoc}
*/
public function display()
{
if ($this->errors) {
http_response_code(400);
$this->ajaxDie(json_encode([
'status' => false,
'errors' => $this->errors,
]));
}
parent::display();
}
private function togglePayLaterConfiguration($method)
{
/** @var PayPalPayLaterConfiguration $payLaterConfiguration */
$payLaterConfiguration = $this->module->getService(PayPalPayLaterConfiguration::class);
$payLaterConfiguration->$method(Tools::getValue('status') ? true : false);
$this->ajaxDie(json_encode(true));
}
public function ajaxProcessUpsertSecretToken()
{
/** @var WebhookSecretTokenService $webhookSecretTokenService */
$webhookSecretTokenService = $this->module->getService(WebhookSecretTokenService::class);
$secret = (string) Tools::getValue('body');
$response = [];
try {
$status = $webhookSecretTokenService->upsertSecretToken($secret);
} catch (Exception $exception) {
$status = false;
$response['errors'] = $exception->getMessage();
}
http_response_code($status ? 204 : 500);
$response['status'] = $status;
$this->ajaxDie(json_encode($response));
}
public function ajaxProcessCheckConfiguration()
{
$response = [];
$query = new DbQuery();
$query->select('name, value, date_add, date_upd');
$query->from('configuration');
$query->where('name LIKE "PS_CHECKOUT_%"');
/** @var int|null $shopId When multishop is disabled, it returns null, so we don't have to restrict results by shop */
$shopId = Shop::getContextShopID(true);
// When ShopId is not NULL, we have to retrieve global values with id_shop = NULL and shop values with id_shop = ShopId
if ($shopId) {
$query->where('id_shop IS NULL OR id_shop = ' . (int) $shopId);
}
$configurations = Db::getInstance()->executeS($query);
$response['status'] = !empty($configurations);
foreach ($configurations as $configuration) {
$response['configuration'][] = [
'name' => $configuration['name'],
'value' => !empty($configuration['value']),
];
}
$this->exitWithResponse($response);
}
public function ajaxProcessFetchConfiguration()
{
$query = new DbQuery();
$query->select('name, value, date_add, date_upd');
$query->from('configuration');
$query->where('name LIKE "PS_CHECKOUT_%"');
/** @var int|null $shopId When multishop is disabled, it returns null, so we don't have to restrict results by shop */
$shopId = Shop::getContextShopID(true);
// When ShopId is not NULL, we have to retrieve global values with id_shop = NULL and shop values with id_shop = ShopId
if ($shopId) {
$query->where('id_shop IS NULL OR id_shop = ' . (int) $shopId);
}
$configurations = Db::getInstance()->executeS($query);
$response = [
'httpCode' => 200,
'status' => !empty($configurations),
'configuration' => array_map(function ($configuration) {
return [
'name' => $configuration['name'],
'value' => $configuration['value'],
];
}, $configurations),
];
$this->exitWithResponse($response);
}
public function ajaxProcessGetMappedOrderStates()
{
/** @var OrderStateMapper $orderStateMapper */
$orderStateMapper = $this->module->getService(OrderStateMapper::class);
$mappedOrderStates = [];
try {
$mappedOrderStates = $orderStateMapper->getMappedOrderStates();
} catch (OrderStateException $exception) {
if ($exception->getCode() === OrderStateException::INVALID_MAPPING) {
(new OrderStateInstaller())->install();
}
$this->exitWithResponse([
'httpCode' => 500,
'status' => false,
'error' => $exception->getMessage(),
]);
}
$this->exitWithResponse([
'status' => true,
'mappedOrderStates' => $mappedOrderStates,
]);
}
public function ajaxProcessBatchSaveConfiguration()
{
/** @var BatchConfigurationValidator $configurationValidator */
$configurationValidator = $this->module->getService(BatchConfigurationValidator::class);
/** @var BatchConfigurationProcessor $batchConfigurationProcessor */
$batchConfigurationProcessor = $this->module->getService(BatchConfigurationProcessor::class);
$configuration = json_decode(Tools::getValue('configuration'), true);
try {
$configurationValidator->validateAjaxBatchConfiguration($configuration);
$batchConfigurationProcessor->saveBatchConfiguration($configuration);
$this->exitWithResponse([
'status' => true,
]);
} catch (Exception $exception) {
$this->exitWithResponse([
'httpCode' => 500,
'status' => false,
'error' => $exception->getMessage(),
]);
}
}
public function ajaxProcessGetOrderStates()
{
$orderStates = OrderState::getOrderStates($this->context->language->id);
$this->exitWithResponse([
'status' => true,
'orderStates' => $orderStates,
]);
}
public function ajaxProcessGetPaymentTokenCount()
{
/** @var PaymentTokenRepository $paymentTokenRepository */
$paymentTokenRepository = $this->module->getService(PaymentTokenRepository::class);
/** @var PayPalConfiguration $payPalConfiguration */
$payPalConfiguration = $this->module->getService(PayPalConfiguration::class);
$this->exitWithResponse([
'status' => true,
'count' => $paymentTokenRepository->getCount(null, $payPalConfiguration->getMerchantId()),
]);
}
/**
* @param array $response
*
* @return void
*/
private function exitWithResponse(array $response)
{
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
header('Content-Type: application/json;charset=utf-8');
header('X-Robots-Tag: noindex, nofollow');
if (isset($response['httpCode'])) {
http_response_code($response['httpCode']);
unset($response['httpCode']);
}
if (!empty($response)) {
echo json_encode($response);
}
exit;
}
public function ajaxProcessDownloadLogs()
{
$filename = Tools::getValue('file');
if (empty($filename) || false === Validate::isFileName($filename)) {
$this->exitWithResponse([
'status' => false,
'httpCode' => 400,
'errors' => [
'Filename is invalid.',
],
]);
}
/** @var LoggerDirectory $loggerDirectory */
$loggerDirectory = $this->module->getService(LoggerDirectory::class);
$file = new SplFileObject($loggerDirectory->getPath() . $filename);
if (false === $file->isReadable()) {
$this->exitWithResponse([
'status' => false,
'httpCode' => 500,
'errors' => [
'File is not readable.',
],
]);
}
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename . '.log"');
header('Content-Length: ' . $file->getSize());
readfile($file->getRealPath());
exit;
}
}