diff --git a/composer.json b/composer.json index cd10dd9a1..27aa2a13d 100755 --- a/composer.json +++ b/composer.json @@ -21,13 +21,17 @@ "php": "5.6" } }, - "repositories": [ - { + "repositories": { + "knapsack": { + "type": "vcs", + "url": "https://github.com/Invertus/Knapsack.git" + }, + "lock": { "type": "vcs", "url": "https://github.com/Invertus/lock.git", "no-api": true } - ], + }, "require": { "vlucas/phpdotenv": "^3.6", "symfony/expression-language": "^3.4", @@ -37,7 +41,8 @@ "apimatic/unirest-php": "^2.3", "symfony/yaml": "^3.4", "league/container": "2.5.0", - "invertus/lock": "^1.0.0" + "invertus/lock": "^1.0.0", + "invertus/knapsack": "^10.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "*", diff --git a/controllers/admin/AdminSaferPayOfficialLogsController.php b/controllers/admin/AdminSaferPayOfficialLogsController.php index e20dcbb8b..290cdf584 100755 --- a/controllers/admin/AdminSaferPayOfficialLogsController.php +++ b/controllers/admin/AdminSaferPayOfficialLogsController.php @@ -21,20 +21,62 @@ *@license SIX Payment Services */ +use Invertus\SaferPay\Adapter\LegacyContext; +use Invertus\SaferPay\Config\SaferPayConfig; +use Invertus\Saferpay\Context\GlobalShopContext; +use Invertus\SaferPay\Controller\AbstractAdminSaferPayController; +use Invertus\SaferPay\Enum\PermissionType; +use Invertus\SaferPay\Logger\Formatter\LogFormatter; +use Invertus\SaferPay\Logger\LoggerInterface; +use Invertus\SaferPay\Repository\SaferPayLogRepository; +use Invertus\SaferPay\Utility\ExceptionUtility; +use Invertus\SaferPay\Utility\VersionUtility; +use Invertus\SaferPay\Logger\Logger; +use Invertus\SaferPay\Adapter\Tools; + if (!defined('_PS_VERSION_')) { exit; } -class AdminSaferPayOfficialLogsController extends ModuleAdminController +class AdminSaferPayOfficialLogsController extends AbstractAdminSaferPayController { + const FILE_NAME = 'AdminSaferPayOfficialLogsController'; + + const LOG_INFORMATION_TYPE_REQUEST = 'request'; + + const LOG_INFORMATION_TYPE_RESPONSE = 'response'; + + const LOG_INFORMATION_TYPE_CONTEXT = 'context'; + public function __construct() { - parent::__construct(); - $this->className = SaferPayLog::class; - $this->table = SaferPayLog::$definition['table']; + $this->table = 'log'; + $this->className = 'PrestaShopLogger'; $this->bootstrap = true; - $this->list_no_link = true; + $this->lang = false; + $this->noLink = true; + $this->allow_export = true; + + parent::__construct(); + + $this->toolbar_btn = []; + $this->initList(); + + $this->_select .= ' + REPLACE(a.`message`, "' . LogFormatter::SAFERPAY_LOG_PREFIX . '", "") as message, + spl.request, spl.response, spl.context + '; + + $shopIdCheck = ''; + + if (VersionUtility::isPsVersionGreaterOrEqualTo('1.7.8.0')) { + $shopIdCheck = ' AND spl.id_shop = a.id_shop'; + } + + $this->_join .= ' JOIN ' . _DB_PREFIX_ . SaferPayLog::$definition['table'] . ' spl ON (spl.id_log = a.id_log' . $shopIdCheck . ' AND a.object_type = "' . pSQL(Logger::LOG_OBJECT_TYPE) . '")'; + $this->_use_found_rows = false; + $this->list_no_link = true; } public function initContent() @@ -42,29 +84,58 @@ public function initContent() if ($this->module instanceof SaferPayOfficial) { $this->content .= $this->module->displayNavigationTop(); } + + $this->content .= $this->displaySeverityInformation(); + parent::initContent(); } public function initList() { $this->fields_list = [ - 'id_saferpay_log' => [ - 'title' => $this->l('ID'), - 'align' => 'center', + 'id_log' => [ + 'title' => $this->module->l('ID', self::FILE_NAME), + 'align' => 'text-center', + 'class' => 'fixed-width-xs', + ], + 'severity' => [ + 'title' => $this->module->l('Severity (1-4)', self::FILE_NAME), + 'align' => 'text-center', + 'class' => 'fixed-width-xs', + 'callback' => 'printSeverityLevel', + ], + 'request' => [ + 'title' => $this->module->l('Request', self::FILE_NAME), + 'align' => 'text-center', + 'callback' => 'printRequestButton', + 'orderby' => false, + 'search' => false, + 'remove_onclick' => true, ], - 'payload' => [ - 'title' => $this->l('Payload'), - 'align' => 'center', - 'class' => 'saferpay-text-break', + 'response' => [ + 'title' => $this->module->l('Response', self::FILE_NAME), + 'align' => 'text-center', + 'callback' => 'printResponseButton', + 'orderby' => false, + 'search' => false, + 'remove_onclick' => true, ], 'message' => [ - 'align' => 'center', - 'title' => $this->l('Message'), - 'class' => 'saferpay-text-break', + 'title' => $this->module->l('Message', self::FILE_NAME), + ], + 'context' => [ + 'title' => $this->module->l('Context', self::FILE_NAME), + 'align' => 'text-center', + 'callback' => 'printContextButton', + 'orderby' => false, + 'search' => false, + 'remove_onclick' => true, ], 'date_add' => [ - 'title' => $this->l('Date'), + 'title' => $this->module->l('Date', self::FILE_NAME), + 'align' => 'right', 'type' => 'datetime', + 'filter_key' => 'a!date_add', ], ]; @@ -77,12 +148,258 @@ public function initList() public function renderList() { unset($this->toolbar_btn['new']); + return parent::renderList(); } public function setMedia($isNewTheme = false) { - $this->addCSS("{$this->module->getPathUri()}views/css/admin/logs_tab.css"); parent::setMedia($isNewTheme); + + /** @var LegacyContext $context */ + $context = $this->module->getService(LegacyContext::class); + + Media::addJsDef([ + 'saferpayofficial' => [ + 'logsUrl' => $context->getAdminLink(SaferPayOfficial::ADMIN_LOGS_CONTROLLER), + ], + ]); + + $this->addCSS("{$this->module->getPathUri()}views/css/admin/logs_tab.css"); + $this->addJS($this->module->getPathUri() . 'views/js/admin/log.js', false); + } + + public function displaySeverityInformation() + { + return $this->context->smarty->fetch( + "{$this->module->getLocalPath()}views/templates/admin/logs/severity_levels.tpl" + ); + } + + public function printSeverityLevel($level) + { + $this->context->smarty->assign([ + 'log_severity_level' => $level, + 'log_severity_level_informative' => defined('\PrestaShopLogger::LOG_SEVERITY_LEVEL_INFORMATIVE') ? + PrestaShopLogger::LOG_SEVERITY_LEVEL_INFORMATIVE : + SaferPayConfig::LOG_SEVERITY_LEVEL_INFORMATIVE, + 'log_severity_level_warning' => defined('\PrestaShopLogger::LOG_SEVERITY_LEVEL_WARNING') ? + PrestaShopLogger::LOG_SEVERITY_LEVEL_WARNING : + SaferPayConfig::LOG_SEVERITY_LEVEL_WARNING, + 'log_severity_level_error' => defined('\PrestaShopLogger::LOG_SEVERITY_LEVEL_ERROR') ? + PrestaShopLogger::LOG_SEVERITY_LEVEL_ERROR : + SaferPayConfig::LOG_SEVERITY_LEVEL_ERROR, + 'log_severity_level_major' => defined('\PrestaShopLogger::LOG_SEVERITY_LEVEL_MAJOR') ? + PrestaShopLogger::LOG_SEVERITY_LEVEL_MAJOR : + SaferPayConfig::LOG_SEVERITY_LEVEL_MAJOR, + ]); + + return $this->context->smarty->fetch( + "{$this->module->getLocalPath()}views/templates/admin/logs/severity_level_column.tpl" + ); + } + + public function getDisplayButton($logId, $data, $logInformationType) + { + $unserializedData = json_decode($data); + + if (empty($unserializedData)) { + return '--'; + } + + $this->context->smarty->assign([ + 'log_id' => $logId, + 'log_information_type' => $logInformationType, + ]); + + return $this->context->smarty->fetch( + "{$this->module->getLocalPath()}views/templates/admin/logs/log_modal.tpl" + ); + } + + /** + * @param string $request + * @param array $data + * + * @return false|string + * + * @throws SmartyException + */ + public function printRequestButton($request, $data) + { + return $this->getDisplayButton($data['id_log'], $request, self::LOG_INFORMATION_TYPE_REQUEST); + } + + public function printResponseButton($response, $data) + { + return $this->getDisplayButton($data['id_log'], $response, self::LOG_INFORMATION_TYPE_RESPONSE); + } + + public function printContextButton($context, $data) + { + return $this->getDisplayButton($data['id_log'], $context, self::LOG_INFORMATION_TYPE_CONTEXT); + } + + public function displayAjaxGetLog() + { + if (!$this->ensureHasPermissions([PermissionType::EDIT, PermissionType::VIEW], true)) { + return; + } + + /** @var Invertus\SaferPay\Adapter\Tools $tools */ + $tools = $this->module->getService(Tools::class); + + /** @var Invertus\SaferPay\Repository\SaferPayLogRepository $logRepository */ + $logRepository = $this->module->getService(SaferPayLogRepository::class); + + /** @var Invertus\SaferPay\Context\GlobalShopContext $shopContext */ + $globalShopContext = $this->module->getService(GlobalShopContext::class); + + $logId = $tools->getValueAsInt('log_id'); + + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + + try { + /** @var \SaferPayLog|null $log */ + $log = $logRepository->findOneBy([ + 'id_log' => $logId, + 'id_shop' => $globalShopContext->getShopId(), + ]); + } catch (Exception $exception) { + $logger->error($exception->getMessage(), [ + 'context' => [ + 'id_log' => $logId, + 'id_shop' => $globalShopContext->getShopId(), + ], + 'exceptions' => ExceptionUtility::getExceptions($exception), + ]); + + $this->ajaxResponse(json_encode([ + 'error' => true, + 'message' => $this->module->l('Failed to find log.', self::FILE_NAME), + ])); + } + + if (!isset($log)) { + $logger->error('No log information found.', [ + 'context' => [ + 'id_log' => $logId, + 'id_shop' => $globalShopContext->getShopId(), + ], + 'exceptions' => [], + ]); + + $this->ajaxRender(json_encode([ + 'error' => true, + 'message' => $this->module->l('No log information found.', self::FILE_NAME), + ])); + } + + $this->ajaxResponse(json_encode([ + 'error' => false, + 'log' => [ + self::LOG_INFORMATION_TYPE_REQUEST => $log->request, + self::LOG_INFORMATION_TYPE_RESPONSE => $log->response, + self::LOG_INFORMATION_TYPE_CONTEXT => $log->context, + ], + ])); + } + + public function processExport($textDelimiter = '"') + { + // clean buffer + if (ob_get_level() && ob_get_length() > 0) { + ob_clean(); + } + + header('Content-type: text/csv'); + header('Content-Type: application/force-download; charset=UTF-8'); + header('Cache-Control: no-store, no-cache'); + header('Content-disposition: attachment; filename="' . $this->table . '_' . date('Y-m-d_His') . '.csv"'); + + $fd = fopen('php://output', 'wb'); + + /** @var Configuration $configuration */ + $configuration = $this->module->getService(Configuration::class); + + /** @var LegacyContext $context */ + $context = $this->module->getService(LegacyContext::class); + + $storeInfo = [ + 'PrestaShop Version' => _PS_VERSION_, + 'PHP Version' => phpversion(), + 'Module Version' => $this->module->version, + 'MySQL Version' => \Db::getInstance()->getVersion(), + 'Shop URL' => $context->getShopDomain(), + 'Shop Name' => $context->getShopName(), + ]; + + $moduleConfigurations = [ + 'Test mode' => SaferPayConfig::isTestMode() ? 'Yes' : 'No', + ]; + + $psSettings = [ + 'Default country' => $configuration->get('PS_COUNTRY_DEFAULT'), + 'Default currency' => $configuration->get('PS_CURRENCY_DEFAULT'), + 'Default language' => $configuration->get('PS_LANG_DEFAULT'), + 'Round mode' => $configuration->get('PS_PRICE_ROUND_MODE'), + 'Round type' => $configuration->get('PS_ROUND_TYPE'), + 'Current theme name' => $context->getShopThemeName(), + 'PHP memory limit' => ini_get('memory_limit'), + ]; + + $moduleConfigurationsInfo = "**Module configurations:**\n"; + foreach ($moduleConfigurations as $key => $value) { + $moduleConfigurationsInfo .= "- $key: $value\n"; + } + + $psSettingsInfo = "**Prestashop settings:**\n"; + foreach ($psSettings as $key => $value) { + $psSettingsInfo .= "- $key: $value\n"; + } + + fputcsv($fd, array_keys($storeInfo), ';', $textDelimiter); + fputcsv($fd, $storeInfo, ';', $textDelimiter); + fputcsv($fd, [], ';', $textDelimiter); + + fputcsv($fd, [$moduleConfigurationsInfo], ';', $textDelimiter); + fputcsv($fd, [$psSettingsInfo], ';', $textDelimiter); + + $query = new \DbQuery(); + + $query + ->select('spl.id_log, l.severity, l.message, spl.request, spl.response, spl.context, spl.date_add') + ->from('saferpay_log', 'spl') + ->leftJoin('log', 'l', 'spl.id_log = l.id_log') + ->orderBy('spl.id_log DESC') + ->limit(1000); + + $result = \Db::getInstance()->executeS($query); + + $firstRow = $result[0]; + $headers = []; + + foreach ($firstRow as $key => $value) { + $headers[] = strtoupper($key); + } + + $fd = fopen('php://output', 'wb'); + + fputcsv($fd, $headers, ';', $textDelimiter); + + $content = !empty($result) ? $result : []; + + foreach ($content as $row) { + $rowValues = []; + foreach ($row as $key => $value) { + $rowValues[] = $value; + } + + fputcsv($fd, $rowValues, ';', $textDelimiter); + } + + @fclose($fd); + die; } } diff --git a/controllers/admin/AdminSaferPayOfficialPaymentController.php b/controllers/admin/AdminSaferPayOfficialPaymentController.php index 5a85cc654..5a89702d4 100755 --- a/controllers/admin/AdminSaferPayOfficialPaymentController.php +++ b/controllers/admin/AdminSaferPayOfficialPaymentController.php @@ -51,6 +51,7 @@ public function __construct() public function setMedia($isNewTheme = false) { parent::setMedia($isNewTheme); + $this->addCSS("{$this->module->getPathUri()}views/css/admin/payment_method.css"); $this->addJS("{$this->module->getPathUri()}views/js/admin/chosen_countries.js"); $this->addJS("{$this->module->getPathUri()}views/js/admin/payment_method_all.js"); diff --git a/controllers/admin/AdminSaferPayOfficialSettingsController.php b/controllers/admin/AdminSaferPayOfficialSettingsController.php index 3b310c5cb..421d6c123 100755 --- a/controllers/admin/AdminSaferPayOfficialSettingsController.php +++ b/controllers/admin/AdminSaferPayOfficialSettingsController.php @@ -402,6 +402,13 @@ private function displayConfigurationSettings() 'desc' => 'This description is visible in payment page also in payment confirmation email', 'class' => 'fixed-width-xxl', ], + SaferPayConfig::SAFERPAY_DEBUG_MODE => [ + 'title' => $this->module->l('Debug mode', self::FILE_NAME), + 'validation' => 'isBool', + 'cast' => 'intval', + 'type' => 'bool', + 'desc' => $this->module->l('Enable debug mode to see more information in logs', self::FILE_NAME), + ], ], 'buttons' => [ 'save_and_connect' => [ diff --git a/controllers/front/ajax.php b/controllers/front/ajax.php index 34a66a144..5b6528dba 100755 --- a/controllers/front/ajax.php +++ b/controllers/front/ajax.php @@ -25,7 +25,9 @@ use Invertus\SaferPay\Controller\Front\CheckoutController; use Invertus\SaferPay\Core\Payment\DTO\CheckoutData; use Invertus\SaferPay\Enum\ControllerName; +use Invertus\SaferPay\Logger\LoggerInterface; use Invertus\SaferPay\Repository\SaferPayOrderRepository; +use Invertus\SaferPay\Utility\ExceptionUtility; if (!defined('_PS_VERSION_')) { exit; @@ -40,6 +42,11 @@ class SaferPayOfficialAjaxModuleFrontController extends ModuleFrontController public function postProcess() { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + + $logger->debug(sprintf('%s - Controller called', self::FILE_NAME)); + switch (Tools::getValue('action')) { case 'submitHostedFields': $this->submitHostedFields(); @@ -75,6 +82,10 @@ protected function processGetStatus() ])); } + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + $logger->debug(sprintf('%s - Controller action ended', self::FILE_NAME)); + $this->ajaxDie(json_encode([ 'saferpayOrder' => json_encode($saferPayOrder), 'isFinished' => $saferPayOrder->authorized || $saferPayOrder->captured || $saferPayOrder->pending, @@ -123,6 +134,9 @@ private function getSuccessControllerName($isBusinessLicence, $fieldToken) private function submitHostedFields() { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + try { if (Order::getOrderByCartId($this->context->cart->id)) { $this->ajaxDie(json_encode([ @@ -151,11 +165,18 @@ private function submitHostedFields() $redirectUrl = $this->getRedirectionToControllerUrl('successHosted'); } + $logger->debug(sprintf('%s - Controller action ended', self::FILE_NAME)); + $this->ajaxDie(json_encode([ 'error' => false, 'url' => $redirectUrl, ])); } catch (Exception $e) { + $logger->error($e->getMessage(), [ + 'context' => [], + 'exceptions' => ExceptionUtility::getExceptions($e), + ]); + $this->ajaxDie(json_encode([ 'error' => true, 'message' => $e->getMessage(), diff --git a/controllers/front/creditCards.php b/controllers/front/creditCards.php index 3d1a5d58e..30d48df82 100755 --- a/controllers/front/creditCards.php +++ b/controllers/front/creditCards.php @@ -23,6 +23,7 @@ use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Controller\AbstractSaferPayController; +use Invertus\SaferPay\Logger\LoggerInterface; use Invertus\SaferPay\Repository\SaferPayCardAliasRepository; if (!defined('_PS_VERSION_')) { @@ -54,6 +55,7 @@ public function display() private function initCardList() { $customerId = $this->context->customer->id; + /** @var SaferPayCardAliasRepository $cardAliasRep */ $cardAliasRep = $this->module->getService(SaferPayCardAliasRepository::class); $savedCustomerCards = $cardAliasRep->getSavedCardsByCustomerId($customerId); @@ -83,6 +85,11 @@ private function initCardList() public function postProcess() { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + + $logger->debug(sprintf('%s - Controller called', self::FILE_NAME)); + $selectedCard = Tools::getValue('saved_card_id'); if ($selectedCard) { $cardAlias = new SaferPayCardAlias($selectedCard); @@ -92,6 +99,9 @@ public function postProcess() } $this->errors[] = $this->module->l('Failed to removed credit card', self::FILENAME); } + + $logger->debug(sprintf('%s - Controller action ended', self::FILE_NAME)); + parent::postProcess(); } diff --git a/controllers/front/creditCards16.php b/controllers/front/creditCards16.php index 5463e4706..52aa7e611 100755 --- a/controllers/front/creditCards16.php +++ b/controllers/front/creditCards16.php @@ -23,6 +23,7 @@ use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Controller\AbstractSaferPayController; +use Invertus\SaferPay\Logger\LoggerInterface; use Invertus\SaferPay\Repository\SaferPayCardAliasRepository; if (!defined('_PS_VERSION_')) { @@ -91,6 +92,11 @@ private function initCardList() public function postProcess() { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + + $logger->debug(sprintf('%s - Controller called', self::FILE_NAME)); + $selectedCard = Tools::getValue('saved_card_id'); if ($selectedCard) { $cardAlias = new SaferPayCardAlias($selectedCard); @@ -100,6 +106,9 @@ public function postProcess() } $this->errors[] = $this->module->l('Failed to removed credit card', self::FILENAME); } + + $logger->debug(sprintf('%s - Controller action ended', self::FILE_NAME)); + parent::postProcess(); } diff --git a/controllers/front/fail.php b/controllers/front/fail.php index 19530f8b8..24bce5046 100755 --- a/controllers/front/fail.php +++ b/controllers/front/fail.php @@ -24,6 +24,7 @@ use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Controller\AbstractSaferPayController; use Invertus\SaferPay\Service\CartDuplicationService; +use Invertus\SaferPay\Logger\LoggerInterface; use PrestaShop\PrestaShop\Adapter\Order\OrderPresenter; if (!defined('_PS_VERSION_')) { @@ -93,6 +94,11 @@ public function initContent() { parent::initContent(); + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + + $logger->debug(sprintf('%s - Controller called', self::FILE_NAME)); + $orderLink = $this->context->link->getPageLink( 'order', true, @@ -100,6 +106,8 @@ public function initContent() ); $this->warning[] = $this->module->l('We couldn\'t authorize your payment. Please try again.', self::FILENAME); + $logger->debug(sprintf('%s - Controller action ended', self::FILE_NAME)); + if (!SaferPayConfig::isVersion17()) { $this->redirectWithNotifications($orderLink); } diff --git a/controllers/front/failIFrame.php b/controllers/front/failIFrame.php index c96b44a61..44b71025f 100755 --- a/controllers/front/failIFrame.php +++ b/controllers/front/failIFrame.php @@ -24,6 +24,7 @@ use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Controller\AbstractSaferPayController; use Invertus\SaferPay\Enum\ControllerName; +use Invertus\SaferPay\Logger\LoggerInterface; if (!defined('_PS_VERSION_')) { exit; @@ -48,22 +49,31 @@ public function initContent() { parent::initContent(); + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + + $logger->debug(sprintf('%s - Controller called', self::FILE_NAME)); + $orderLink = $this->context->link->getPageLink( 'order', true, null ); + $logger->debug(sprintf('%s - Controller action ended', self::FILE_NAME)); + if (SaferPayConfig::isVersion17()) { $this->setTemplate(SaferPayConfig::SAFERPAY_TEMPLATE_LOCATION . '/front/loading.tpl'); return; } + $this->context->smarty->assign([ 'cssUrl' => "{$this->module->getPathUri()}views/css/front/loading.css", 'jsUrl' => "{$this->module->getPathUri()}views/js/front/saferpay_iframe.js", 'redirectUrl' => $orderLink, ]); $this->setTemplate('loading_16.tpl'); + } public function setMedia() diff --git a/controllers/front/failValidation.php b/controllers/front/failValidation.php index 90951a60e..0572dc065 100755 --- a/controllers/front/failValidation.php +++ b/controllers/front/failValidation.php @@ -22,6 +22,7 @@ */ use Invertus\SaferPay\Controller\AbstractSaferPayController; +use Invertus\SaferPay\Logger\LoggerInterface; use Invertus\SaferPay\Repository\SaferPayOrderRepository; use Invertus\SaferPay\Service\CartDuplicationService; @@ -35,6 +36,11 @@ class SaferPayOfficialFailValidationModuleFrontController extends AbstractSaferP public function postProcess() { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + + $logger->debug(sprintf('%s - Controller called', self::FILE_NAME)); + $cartId = Tools::getValue('cartId'); $orderId = Tools::getValue('orderId'); $secureKey = Tools::getValue('secureKey'); @@ -86,6 +92,8 @@ public function postProcess() true ); + $logger->debug(sprintf('%s - Controller action ended', self::FILE_NAME)); + Tools::redirect($failUrl); } } diff --git a/controllers/front/hostedIframe.php b/controllers/front/hostedIframe.php index b03306371..85b044f5d 100755 --- a/controllers/front/hostedIframe.php +++ b/controllers/front/hostedIframe.php @@ -22,6 +22,7 @@ */ use Invertus\SaferPay\Config\SaferPayConfig; +use Invertus\SaferPay\Logger\LoggerInterface; use PrestaShop\PrestaShop\Core\Checkout\TermsAndConditions; if (!defined('_PS_VERSION_')) { @@ -34,6 +35,11 @@ class SaferPayOfficialHostedIframeModuleFrontController extends ModuleFrontContr public function initContent() { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + + $logger->debug(sprintf('%s - Controller called', self::FILENAME)); + parent::initContent(); $paymentMethod = Tools::getValue('saved_card_method'); @@ -49,6 +55,8 @@ public function initContent() 'saferpay_selected_card' => $selectedCard, ]); + $logger->debug(sprintf('%s - Controller action ended', self::FILENAME)); + if (SaferPayConfig::isVersion17()) { $this->setTemplate( SaferPayConfig::SAFERPAY_HOSTED_TEMPLATE_LOCATION . @@ -63,6 +71,7 @@ public function initContent() '_16.tpl' ); } + } public function setMedia() diff --git a/controllers/front/iframe.php b/controllers/front/iframe.php index 262d30a3c..d48b0e87e 100755 --- a/controllers/front/iframe.php +++ b/controllers/front/iframe.php @@ -26,6 +26,7 @@ use Invertus\SaferPay\Controller\Front\CheckoutController; use Invertus\SaferPay\Core\Payment\DTO\CheckoutData; use Invertus\SaferPay\Enum\ControllerName; +use Invertus\SaferPay\Logger\LoggerInterface; if (!defined('_PS_VERSION_')) { exit; @@ -39,6 +40,11 @@ class SaferPayOfficialIFrameModuleFrontController extends AbstractSaferPayContro public function postProcess() { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + + $logger->debug(sprintf('%s - Controller called', self::FILE_NAME)); + $cart = $this->context->cart; $redirectLink = $this->context->link->getPageLink( 'order', @@ -70,8 +76,15 @@ public function postProcess() } $customer = new Customer($cart->id_customer); if (!Validate::isLoadedObject($customer)) { + $logger->error(sprintf('%s - Customer not found', self::FILE_NAME), [ + 'context' => [], + 'exceptions' => [], + ]); + Tools::redirect($redirectLink); } + + $logger->debug(sprintf('%s - Controller action ended', self::FILE_NAME)); } public function initContent() diff --git a/controllers/front/notify.php b/controllers/front/notify.php index 0155c5210..38c7c001e 100755 --- a/controllers/front/notify.php +++ b/controllers/front/notify.php @@ -25,10 +25,12 @@ use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Controller\AbstractSaferPayController; use Invertus\SaferPay\Core\Payment\DTO\CheckoutData; +use Invertus\SaferPay\Logger\LoggerInterface; use Invertus\SaferPay\Processor\CheckoutProcessor; use Invertus\SaferPay\Repository\SaferPayOrderRepository; use Invertus\SaferPay\Service\SaferPayOrderStatusService; use Invertus\SaferPay\Service\TransactionFlow\SaferPayTransactionAssertion; +use Invertus\SaferPay\Utility\ExceptionUtility; if (!defined('_PS_VERSION_')) { exit; @@ -45,11 +47,21 @@ class SaferPayOfficialNotifyModuleFrontController extends AbstractSaferPayContro */ public function postProcess() { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + + $logger->debug(sprintf('%s - Controller called', self::FILE_NAME)); + $cartId = Tools::getValue('cartId'); $secureKey = Tools::getValue('secureKey'); $cart = new Cart($cartId); if (!Validate::isLoadedObject($cart)) { + $logger->error(sprintf('%s - Cart not found', self::FILE_NAME), [ + 'context' => [], + 'exceptions' => [], + ]); + $this->ajaxDie(json_encode([ 'error_type' => 'unknown_error', 'error_text' => $this->module->l('An unknown error error occurred. Please contact support', self::FILENAME), @@ -57,6 +69,13 @@ public function postProcess() } if ($cart->secure_key !== $secureKey) { + $logger->error(sprintf('%s - Insecure cart', self::FILE_NAME), [ + 'context' => [ + 'cart_id' => $cartId, + ], + 'exceptions' => [], + ]); + die($this->module->l('Error. Insecure cart', self::FILENAME)); } @@ -117,6 +136,12 @@ public function postProcess() $orderStatusService = $this->module->getService(SaferPayOrderStatusService::class); $orderStatusService->cancel($order); + $logger->debug(sprintf('%s - Liability shift is false', self::FILE_NAME), [ + 'context' => [ + 'id_order' => $order->id, + ], + ]); + die($this->module->l('Liability shift is false', self::FILENAME)); } @@ -181,23 +206,22 @@ public function postProcess() die('canceled'); } - PrestaShopLogger::addLog( - sprintf( - '%s has caught an error: %s', - __CLASS__, - $e->getMessage() - ), - 1, - null, - null, - null, - true - ); + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + $logger->error(sprintf('%s - AccountToAccount order is declined', self::FILENAME), [ + 'context' => [ + 'orderId' => $orderId, + ], + 'exceptions' => ExceptionUtility::getExceptions($e), + ]); + $this->releaseLock(); die($this->module->l($e->getMessage(), self::FILENAME)); } + $logger->debug(sprintf('%s - Controller action ended', self::FILE_NAME)); + die($this->module->l('Success', self::FILENAME)); } diff --git a/controllers/front/pendingNotify.php b/controllers/front/pendingNotify.php index cf25f56d8..cde3da705 100755 --- a/controllers/front/pendingNotify.php +++ b/controllers/front/pendingNotify.php @@ -24,6 +24,7 @@ use Invertus\SaferPay\Api\Enum\TransactionStatus; use Invertus\SaferPay\Controller\AbstractSaferPayController; use Invertus\SaferPay\DTO\Response\AssertRefund\AssertRefundBody; +use Invertus\SaferPay\Logger\LoggerInterface; use Invertus\SaferPay\Repository\SaferPayOrderRepository; use Invertus\SaferPay\Service\TransactionFlow\SaferPayTransactionRefundAssertion; @@ -42,6 +43,11 @@ class SaferPayOfficialPendingNotifyModuleFrontController extends AbstractSaferPa */ public function postProcess() { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + + $logger->debug(sprintf('%s - Controller called', self::FILE_NAME)); + $cartId = Tools::getValue('cartId'); $secureKey = Tools::getValue('secureKey'); @@ -67,6 +73,8 @@ public function postProcess() } } + $logger->debug(sprintf('%s - Controller action ended', self::FILE_NAME)); + die($this->module->l('Success', self::FILENAME)); } @@ -89,6 +97,14 @@ private function handleCapturedRefund($orderRefundId) /** @var SaferPayOrderRepository $saferPayOrderRepository */ $saferPayOrderRepository = $this->module->getService(SaferPayOrderRepository::class); + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + $logger->debug(sprintf('%s - Capture refund', self::FILE_NAME), [ + 'context' => [ + 'order_refund_id' => $orderRefundId, + ], + ]); + $orderRefund = new SaferPayOrderRefund($orderRefundId); $orderRefund->status = TransactionStatus::CAPTURED; $orderRefund->update(); diff --git a/controllers/front/return.php b/controllers/front/return.php index 48cb8db7f..c454ca3b9 100755 --- a/controllers/front/return.php +++ b/controllers/front/return.php @@ -28,10 +28,12 @@ use Invertus\SaferPay\DTO\Response\Assert\AssertBody; use Invertus\SaferPay\Enum\ControllerName; use Invertus\SaferPay\Exception\Api\SaferPayApiException; +use Invertus\SaferPay\Logger\LoggerInterface; use Invertus\SaferPay\Processor\CheckoutProcessor; use Invertus\SaferPay\Service\SaferPayOrderStatusService; use Invertus\SaferPay\Service\TransactionFlow\SaferPayTransactionAssertion; use Invertus\SaferPay\Service\TransactionFlow\SaferPayTransactionAuthorization; +use Invertus\SaferPay\Utility\ExceptionUtility; if (!defined('_PS_VERSION_')) { exit; @@ -43,6 +45,11 @@ class SaferPayOfficialReturnModuleFrontController extends AbstractSaferPayContro public function postProcess() { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + + $logger->debug(sprintf('%s - Controller called', self::FILE_NAME)); + $cartId = (int) Tools::getValue('cartId'); $order = new Order($this->getOrderId($cartId)); $secureKey = Tools::getValue('secureKey'); @@ -138,15 +145,23 @@ public function postProcess() $orderStatusService->setPending($order); } } catch (SaferPayApiException $e) { - \PrestaShopLogger::addLog($e->getMessage()); + $logger->debug($e->getMessage(), [ + 'context' => [], + 'exceptions' => ExceptionUtility::getExceptions($e), + ]); // we only care if we have a response with pending status, else we skip further actions } + + $logger->debug(sprintf('%s - Controller action ended', self::FILE_NAME)); } /** * @throws PrestaShopException */ public function initContent() { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + $cartId = Tools::getValue('cartId'); $secureKey = Tools::getValue('secureKey'); $isBusinessLicence = (int) Tools::getValue(SaferPayConfig::IS_BUSINESS_LICENCE); @@ -156,6 +171,11 @@ public function initContent() $cart = new Cart($cartId); if (!Validate::isLoadedObject($cart)) { + $logger->error(sprintf('%s - Cart not found', self::FILE_NAME), [ + 'context' => [], + 'exceptions' => [], + ]); + $this->ajaxDie(json_encode([ 'error_type' => 'unknown_error', 'error_text' => $this->module->l('An unknown error error occurred. Please contact support', self::FILENAME), @@ -163,6 +183,12 @@ public function initContent() } if ($cart->secure_key !== $secureKey) { + $logger->error(sprintf('%s - Secure key does not match', self::FILE_NAME), [ + 'context' => [ + 'cartId' => $cartId, + ], + ]); + $this->ajaxDie(json_encode([ 'error_type' => 'unknown_error', 'error_text' => $this->module->l('An unknown error error occurred. Please contact support', self::FILENAME), diff --git a/controllers/front/success.php b/controllers/front/success.php index fc74b2408..80c41c09e 100755 --- a/controllers/front/success.php +++ b/controllers/front/success.php @@ -22,6 +22,7 @@ */ use Invertus\SaferPay\Controller\AbstractSaferPayController; +use Invertus\SaferPay\Logger\LoggerInterface; if (!defined('_PS_VERSION_')) { exit; @@ -33,6 +34,11 @@ class SaferPayOfficialSuccessModuleFrontController extends AbstractSaferPayContr public function postProcess() { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + + $logger->debug(sprintf('%s - Controller called', self::FILE_NAME)); + $cartId = Tools::getValue('cartId'); $moduleId = Tools::getValue('moduleId'); $orderId = Tools::getValue('orderId'); @@ -41,6 +47,12 @@ public function postProcess() $cart = new Cart($cartId); if ($cart->secure_key !== $secureKey) { + $logger->error(sprintf('%s - Secure key does not match', self::FILE_NAME), [ + 'context' => [ + 'cartId' => $cartId, + ] + ]); + $redirectLink = $this->context->link->getPageLink( 'order', true, @@ -53,6 +65,8 @@ public function postProcess() Tools::redirect($redirectLink); } + $logger->debug(sprintf('%s - Controller action ended', self::FILE_NAME)); + Tools::redirect($this->context->link->getPageLink( 'order-confirmation', true, diff --git a/controllers/front/successHosted.php b/controllers/front/successHosted.php index 637947820..fb26d4931 100755 --- a/controllers/front/successHosted.php +++ b/controllers/front/successHosted.php @@ -24,6 +24,8 @@ use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Controller\AbstractSaferPayController; use Invertus\SaferPay\Enum\ControllerName; +use Invertus\SaferPay\Logger\LoggerInterface; +use Invertus\SaferPay\Utility\ExceptionUtility; if (!defined('_PS_VERSION_')) { exit; @@ -46,6 +48,11 @@ public function init() public function postProcess() { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + + $logger->debug(sprintf('%s - Controller called', self::FILE_NAME)); + $cartId = Tools::getValue('cartId'); $orderId = Tools::getValue('orderId'); $secureKey = Tools::getValue('secureKey'); @@ -59,20 +66,17 @@ public function postProcess() } try { + $logger->debug(sprintf('%s - Controller action ended', self::FILE_NAME)); + Tools::redirect($this->getOrderConfirmationLink($cartId, $moduleId, $orderId, $secureKey)); } catch (Exception $e) { - PrestaShopLogger::addLog( - sprintf( - '%s has caught an error: %s', - __CLASS__, - $e->getMessage() - ), - 1, - null, - null, - null, - true - ); + $logger->error($e->getMessage(), [ + 'context' => [ + 'cartId' => $cartId, + 'orderId' => $orderId, + ], + 'exceptions' => ExceptionUtility::getExceptions($e), + ]); Tools::redirect( $this->context->link->getModuleLink( diff --git a/controllers/front/successIFrame.php b/controllers/front/successIFrame.php index b74503630..c783340dc 100755 --- a/controllers/front/successIFrame.php +++ b/controllers/front/successIFrame.php @@ -24,6 +24,8 @@ use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Controller\AbstractSaferPayController; use Invertus\SaferPay\Enum\ControllerName; +use Invertus\SaferPay\Logger\LoggerInterface; +use Invertus\SaferPay\Utility\ExceptionUtility; if (!defined('_PS_VERSION_')) { exit; @@ -46,6 +48,11 @@ public function init() public function postProcess() // todo refactor this by the logic provided { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + + $logger->debug(sprintf('%s - Controller called', self::FILE_NAME)); + $cartId = Tools::getValue('cartId'); $orderId = Tools::getValue('orderId'); $secureKey = Tools::getValue('secureKey'); @@ -60,20 +67,14 @@ public function postProcess() // todo refactor this by the logic provided } try { + $logger->debug(sprintf('%s - Controller action ended', self::FILE_NAME)); + Tools::redirect($this->getOrderConfirmationLink($cartId, $moduleId, $orderId, $secureKey)); } catch (Exception $e) { - PrestaShopLogger::addLog( - sprintf( - '%s has caught an error: %s', - __CLASS__, - $e->getMessage() - ), - 1, - null, - null, - null, - true - ); + $logger->error($e->getMessage(), [ + 'context' => [], + 'exceptions' => ExceptionUtility::getExceptions($e), + ]); Tools::redirect( $this->context->link->getModuleLink( diff --git a/controllers/front/validation.php b/controllers/front/validation.php index de8d1cf2b..1a59393a1 100755 --- a/controllers/front/validation.php +++ b/controllers/front/validation.php @@ -24,6 +24,7 @@ use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Controller\AbstractSaferPayController; use Invertus\SaferPay\Core\Payment\DTO\CheckoutData; +use Invertus\SaferPay\Logger\LoggerInterface; use Invertus\SaferPay\Service\SaferPayExceptionService; use Invertus\SaferPay\Controller\Front\CheckoutController; @@ -43,6 +44,11 @@ class SaferPayOfficialValidationModuleFrontController extends AbstractSaferPayCo */ public function postProcess() { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + + $logger->debug(sprintf('%s - Controller called', self::FILE_NAME)); + $paymentMethod = Tools::getValue('saved_card_method'); $cart = $this->context->cart; $redirectLink = $this->context->link->getPageLink( @@ -90,6 +96,8 @@ public function postProcess() $redirectLink = $checkoutController->execute($checkoutData); + $logger->debug(sprintf('%s - Controller action ended', self::FILE_NAME)); + Tools::redirect($redirectLink); } catch (\Exception $exception) { /** @var SaferPayExceptionService $exceptionService */ diff --git a/saferpayofficial.php b/saferpayofficial.php index 9892ed2c4..32ab76deb 100755 --- a/saferpayofficial.php +++ b/saferpayofficial.php @@ -40,7 +40,7 @@ public function __construct($name = null) { $this->name = 'saferpayofficial'; $this->author = 'Invertus'; - $this->version = '1.2.3'; + $this->version = '1.2.4'; $this->module_key = '3d3506c3e184a1fe63b936b82bda1bdf'; $this->displayName = 'SaferpayOfficial'; $this->description = 'Saferpay Payment module'; diff --git a/src/Adapter/LegacyContext.php b/src/Adapter/LegacyContext.php index 618d21cf7..91434eecb 100755 --- a/src/Adapter/LegacyContext.php +++ b/src/Adapter/LegacyContext.php @@ -38,7 +38,17 @@ public function getContext() public function getShopId() { - return $this->getContext()->shop->id; + return (int) $this->getContext()->shop->id; + } + + public function getLanguageId() + { + return (int) $this->getContext()->language->id; + } + + public function getLanguageIso() + { + return (string) $this->getContext()->language->iso_code ?: 'en'; } public function getCurrencyIsoCode() @@ -78,4 +88,133 @@ public function getDeviceDetect() { return (int) $this->getContext()->getDevice(); } + + public function getAdminLink($controllerName, array $params = []) + { + /* @noinspection PhpMethodParametersCountMismatchInspection - its valid for PS1.7 */ + return (string) Context::getContext()->link->getAdminLink($controllerName, true, [], $params); + } + + public function getLanguageCode() + { + return (string) $this->getContext()->language->language_code ?: 'en-us'; + } + + public function getCurrencyIso() + { + if (!$this->getContext()->currency) { + return ''; + } + + return (string) $this->getContext()->currency->iso_code; + } + + public function getCountryIso() + { + if (!$this->getContext()->country) { + return ''; + } + + return (string) $this->getContext()->country->iso_code; + } + + public function getCurrency() + { + return $this->getContext()->currency; + } + + public function getCustomerId() + { + if (!$this->getContext()->customer) { + return 0; + } + + return (int) $this->getContext()->customer->id; + } + + public function isCustomerLoggedIn() + { + if (!$this->getContext()->customer) { + return false; + } + + return (bool) $this->getContext()->customer->isLogged(); + } + + public function getCustomerEmail() + { + if (!$this->getContext()->customer) { + return ''; + } + + return $this->getContext()->customer->email; + } + + public function getShopDomain() + { + return (string) $this->getContext()->shop->domain; + } + + public function getShopName() + { + return (string) $this->getContext()->shop->name; + } + + public function getController() + { + return $this->getContext()->controller; + } + + /** + * @throws \Throwable + */ + public function setCurrentCart(\Cart $cart) + { + $this->getContext()->cart = $cart; + $this->getContext()->cart->update(); + + $this->getContext()->cookie->__set('id_cart', (int) $cart->id); + $this->getContext()->cookie->write(); + } + + public function setCountry(\Country $country) + { + $this->getContext()->country = $country; + } + + public function setCurrency(\Currency $currency) + { + $this->getContext()->currency = $currency; + } + + public function getBaseLink($shopId = null, $ssl = null) + { + return (string) $this->getContext()->link->getBaseLink($shopId, $ssl); + } + + public function getCartProducts() + { + $cart = $this->getContext()->cart; + + if (!$cart) { + return []; + } + + return $cart->getProducts(); + } + + public function getCart() + { + return isset($this->getContext()->cart) ? $this->getContext()->cart : null; + } + + public function getShopThemeName() + { + return $this->getContext()->shop->theme_name; + } + + public function updateCustomer(\Customer $customer) + { + $this->getContext()->updateCustomer($customer); + } } diff --git a/src/Adapter/Tools.php b/src/Adapter/Tools.php new file mode 100644 index 000000000..0c2911b7e --- /dev/null +++ b/src/Adapter/Tools.php @@ -0,0 +1,171 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Adapter; + +use Context as PrestashopContext; +use Tools as PrestashopTools; + +if (!defined('_PS_VERSION_')) { + exit; +} + +class Tools +{ + public function linkRewrite($str) + { + return PrestashopTools::str2url($str); + } + + public function redirectAdmin($controller) + { + PrestashopTools::redirectAdmin($controller); + } + + public function redirect($url) + { + PrestashopTools::redirect($url); + } + + public function isSubmit($form) + { + return PrestashopTools::isSubmit($form); + } + + public function strtoupper($string) + { + return PrestashopTools::strtoupper($string); + } + + public function strtolower($string) + { + return PrestashopTools::strtolower($string); + } + + public function encrypt($string) + { + return PrestashopTools::encrypt($string); + } + + public function passwdGen($length = 8, $flag = 'ALPHANUMERIC') + { + return PrestashopTools::passwdGen($length, $flag); + } + + public function fileGetContents( + $url, + $useIncludePath = false, + $steamContext = null, + $curlTimeout = 5, + $fallback = false + ) { + return PrestashopTools::file_get_contents($url, $useIncludePath, $steamContext, $curlTimeout, $fallback); + } + + public static function replaceAccentedChars($string) + { + return PrestashopTools::replaceAccentedChars($string); + } + + /** + * @param string $value + * @param string|false $defaultValue + * + * @return mixed Value + */ + public function getValue($value, $defaultValue = false) + { + $toolsValue = PrestashopTools::getValue($value, $defaultValue); + + return is_null($toolsValue) || $toolsValue === '' || $toolsValue === 'null' ? null : $toolsValue; + } + + /** + * @param string $value + * @param string|false $defaultValue + * + * @return bool + */ + public function getValueAsBoolean($value, $defaultValue = false) + { + $result = $this->getValue($value, $defaultValue); + + if (in_array($result, ['false', '0', null, false, 0], true)) { + return false; + } + + return (bool) $result; + } + + /** + * @param string $value + * @param string|false $defaultValue + * + * @return bool + */ + public function getValueAsInteger($value, $defaultValue = false) + { + $result = $this->getValue($value, $defaultValue); + + if (in_array($result, ['false', '0', null, false, 0], true)) { + return 0; + } + + return (int) $result; + } + + public function getAllValues() + { + return PrestashopTools::getAllValues(); + } + + public function getValueAsInt($value, $defaultValue = 0) + { + return (int) PrestashopTools::getValue($value, $defaultValue); + } + + public function getShopDomain() + { + return PrestashopTools::getShopDomain(); + } + + public function displayPrice($price, $currency = null, $no_utf8 = false, PrestashopContext $context = null) + { + return PrestashopTools::displayPrice($price, $currency, $no_utf8, $context); + } + + public function ps_round($value, $precision = 0, $round_mode = null) + { + return PrestashopTools::ps_round($value, $precision, $round_mode); + } + + public function getToken($page = true, PrestashopContext $context = null) + { + return PrestashopTools::getToken($page, $context); + } + + public function convertPriceFull($amount, \Currency $currency_from = null, \Currency $currency_to = null) + { + return PrestashopTools::convertPriceFull($amount, $currency_from, $currency_to); + } +} diff --git a/src/Api/ApiRequest.php b/src/Api/ApiRequest.php index a005d7e91..6844f030b 100755 --- a/src/Api/ApiRequest.php +++ b/src/Api/ApiRequest.php @@ -27,6 +27,8 @@ use Exception; use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Exception\Api\SaferPayApiException; +use Invertus\SaferPay\Logger\LoggerInterface; +use Invertus\SaferPay\Utility\ExceptionUtility; use SaferPayLog; use Unirest\Request; use Unirest\Response; @@ -37,6 +39,15 @@ class ApiRequest { + const FILE_NAME = 'ApiRequest'; + /** @var LoggerInterface */ + private $logger; + + public function __construct(LoggerInterface $logger) + { + $this->logger = $logger; + } + /** * API Request Post Method. * @@ -59,10 +70,11 @@ public function post($url, $params = []) return json_decode($response->raw_body); } catch (Exception $exception) { - $logs = new SaferPayLog(); - $logs->message = $exception->getMessage() ?: "missing response"; - $logs->payload = json_encode($params); - $logs->add(); + $this->logger->error($exception->getMessage(), [ + 'context' => [], + 'exceptions' => ExceptionUtility::getExceptions($exception) + ]); + throw $exception; } } @@ -81,17 +93,22 @@ public function get($url, $params = []) $response = Request::get( $this->getBaseUrl() . $url, $this->getHeaders(), - json_encode($params) + $params ); $this->isValidResponse($response); return json_decode($response->raw_body); } catch (Exception $exception) { - $logs = new SaferPayLog(); - $logs->message = $exception->getMessage() ?: "missing response"; - $logs->payload = json_encode($params); - $logs->add(); + $this->logger->error($exception->getMessage(), [ + 'context' => [ + 'headers' => $this->getHeaders(), + 'request' => $params, + 'response' => json_decode($response->raw_body), + ], + 'exceptions' => ExceptionUtility::getExceptions($exception) + ]); + throw $exception; } } @@ -119,6 +136,11 @@ private function getBaseUrl() private function isValidResponse(Response $response) { if ($response->code >= 300) { + $this->logger->error(sprintf('%s - API thrown code: %d', self::FILE_NAME, $response->code), [ + 'context' => [], + 'response' => $response->body, + ]); + throw new SaferPayApiException(sprintf('Initialize API failed: %s', $response->raw_body), SaferPayApiException::INITIALIZE); } } diff --git a/src/Config/SaferPayConfig.php b/src/Config/SaferPayConfig.php index c2c31af4b..516418019 100755 --- a/src/Config/SaferPayConfig.php +++ b/src/Config/SaferPayConfig.php @@ -264,8 +264,17 @@ class SaferPayConfig const PAYMENT_BEHAVIOR_WITHOUT_3D_AUTHORIZE = 1; const SAFERPAY_CARDFORM_HOLDERNAME_REQUIRENCE = 'MANDATORY'; + const SAFERPAY_DEBUG_MODE = 'SAFERPAY_DEBUG_MODE'; - public static function supportsOrderCapture(string $paymentMethod) + const LOG_SEVERITY_LEVEL_INFORMATIVE = 1; + + const LOG_SEVERITY_LEVEL_WARNING = 2; + + const LOG_SEVERITY_LEVEL_ERROR = 3; + + const LOG_SEVERITY_LEVEL_MAJOR = 4; + + public static function supportsOrderCapture($paymentMethod) { //payments that DOES NOT SUPPORT capture $unsupportedCapturePayments = [ @@ -276,7 +285,7 @@ public static function supportsOrderCapture(string $paymentMethod) return !in_array($paymentMethod, $unsupportedCapturePayments); } - public static function supportsOrderCancel(string $paymentMethod) + public static function supportsOrderCancel($paymentMethod) { //payments that DOES NOT SUPPORT order cancel $unsupportedCancelPayments = [ @@ -416,6 +425,11 @@ public static function isTestMode() return (bool) Configuration::get(self::TEST_MODE); } + public static function isDebugMode() + { + return (bool) Configuration::get(self::SAFERPAY_DEBUG_MODE); + } + public static function isVersion17() { return (bool) version_compare(_PS_VERSION_, '1.7', '>='); diff --git a/src/Context/GlobalShopContext.php b/src/Context/GlobalShopContext.php new file mode 100644 index 000000000..77c453684 --- /dev/null +++ b/src/Context/GlobalShopContext.php @@ -0,0 +1,83 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Context; + +use Invertus\SaferPay\Adapter\LegacyContext; + +if (!defined('_PS_VERSION_')) { + exit; +} +/** + * Gets shop context data + * NOTE: Done without interface because throwing error in the module + */ +class GlobalShopContext implements GlobalShopContextInterface +{ + private $context; + + public function __construct(LegacyContext $context) + { + $this->context = $context; + } + + public function getShopId() + { + return $this->context->getShopId(); + } + + public function getLanguageId() + { + return $this->context->getLanguageId(); + } + + public function getLanguageIso() + { + return $this->context->getLanguageIso(); + } + + public function getCurrencyIso() + { + return $this->context->getCurrencyIso(); + } + + public function getCurrency() + { + return $this->context->getCurrency(); + } + + public function getShopDomain() + { + return $this->context->getShopDomain(); + } + + public function getShopName() + { + return $this->context->getShopName(); + } + + public function isShopSingleShopContext() + { + return \Shop::getContext() === \Shop::CONTEXT_SHOP; + } +} diff --git a/src/Context/GlobalShopContextInterface.php b/src/Context/GlobalShopContextInterface.php new file mode 100644 index 000000000..b8f6e41aa --- /dev/null +++ b/src/Context/GlobalShopContextInterface.php @@ -0,0 +1,50 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Context; + +if (!defined('_PS_VERSION_')) { + exit; +} + +/** + * Gets shop context data + */ +interface GlobalShopContextInterface +{ + public function getShopId(); + + public function getLanguageId(); + + public function getLanguageIso(); + + public function getCurrencyIso(); + + public function getCurrency(); + + public function getShopDomain(); + + public function getShopName(); + + public function isShopSingleShopContext(); +} diff --git a/src/Controller/AbstractAdminSaferPayController.php b/src/Controller/AbstractAdminSaferPayController.php new file mode 100644 index 000000000..9cc6521f8 --- /dev/null +++ b/src/Controller/AbstractAdminSaferPayController.php @@ -0,0 +1,94 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Controller; + +use Invertus\SaferPay\Logger\LoggerInterface; +use Invertus\SaferPay\Response\JsonResponse; +use Invertus\SaferPay\Utility\ExceptionUtility; + +class AbstractAdminSaferPayController extends \ModuleAdminController +{ + const FILE_NAME = 'AbstractAdminSaferPayController'; + + protected function ajaxResponse($value = null, $controller = null, $method = null) + { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + + if ($value instanceof JsonResponse) { + if ($value->getStatusCode() === JsonResponse::HTTP_INTERNAL_SERVER_ERROR) { + $logger->error('Failed to return valid response', [ + 'context' => [ + 'response' => $value->getContent(), + ], + ]); + } + + http_response_code($value->getStatusCode()); + + $value = $value->getContent(); + } + + try { + if (method_exists(\ControllerCore::class, 'ajaxRender')) { + $this->ajaxRender($value, $controller, $method); + + exit; + } + + $this->ajaxDie($value, $controller, $method); + } catch (\Exception $exception) { + $logger->error($exception->getMessage(), [ + 'context' => [], + 'response' => json_encode($value ?: []), + 'exceptions' => ExceptionUtility::getExceptions($exception), + ]); + } + + exit; + } + + public function ensureHasPermissions($permissions, $ajax = false) + { + foreach ($permissions as $permission) { + if (!$this->access($permission)) { + if ($ajax) { + $this->ajaxResponse(json_encode([ + 'error' => true, + 'message' => $this->module->l('Unauthorized.', self::FILE_NAME), + ]), JsonResponse::HTTP_UNAUTHORIZED); + } else { + $this->errors[] = $this->module->l( + 'You do not have permission to view this.', + self::FILE_NAME + ); + } + + return false; + } + } + + return true; + } +} diff --git a/src/Entity/SaferPayLog.php b/src/Entity/SaferPayLog.php index c58429656..7cc44fffb 100755 --- a/src/Entity/SaferPayLog.php +++ b/src/Entity/SaferPayLog.php @@ -27,18 +27,32 @@ class SaferPayLog extends ObjectModel { + public $id_saferpay_log; + + public $id_log; + + public $id_shop; + public $message; - public $date_add; + public $request; - public $payload; + public $response; + + public $context; + + public $date_add; public static $definition = [ 'table' => 'saferpay_log', 'primary' => 'id_saferpay_log', 'fields' => [ + 'id_log' => ['type' => self::TYPE_INT, 'validate' => 'isInt'], + 'id_shop' => ['type' => self::TYPE_INT, 'validate' => 'isInt'], 'message' => ['type' => self::TYPE_STRING, 'validate' => 'isString'], - 'payload' => ['type' => self::TYPE_STRING, 'validate' => 'isString'], + 'request' => ['type' => self::TYPE_STRING, 'validate' => 'isString'], + 'response' => ['type' => self::TYPE_STRING, 'validate' => 'isString'], + 'context' => ['type' => self::TYPE_STRING, 'validate' => 'isString'], 'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'], ], ]; diff --git a/src/EntityManager/EntityManagerInterface.php b/src/EntityManager/EntityManagerInterface.php new file mode 100644 index 000000000..ed7bbd7c6 --- /dev/null +++ b/src/EntityManager/EntityManagerInterface.php @@ -0,0 +1,51 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\EntityManager; + +if (!defined('_PS_VERSION_')) { + exit; +} + +interface EntityManagerInterface +{ + /** + * @param \ObjectModel $model + * @param string $unitOfWorkType - @see ObjectModelUnitOfWork + * @param string|null $specificKey + * + * @return EntityManagerInterface + */ + public function persist( + \ObjectModel $model, + $unitOfWorkType, + $specificKey = null + ); + + /** + * @return array<\ObjectModel> + * + * @throws \PrestaShopException + */ + public function flush(); +} diff --git a/src/EntityManager/ObjectModelEntityManager.php b/src/EntityManager/ObjectModelEntityManager.php new file mode 100644 index 000000000..0ab073abb --- /dev/null +++ b/src/EntityManager/ObjectModelEntityManager.php @@ -0,0 +1,86 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\EntityManager; + +if (!defined('_PS_VERSION_')) { + exit; +} + +class ObjectModelEntityManager implements EntityManagerInterface +{ + private $unitOfWork; + + public function __construct(ObjectModelUnitOfWork $unitOfWork) + { + $this->unitOfWork = $unitOfWork; + } + + /** + * @param \ObjectModel $model + * @param string $unitOfWorkType + * @param string|null $specificKey + * for example external_id key to make it easier to keep + * track of which object model is related to which external_id + */ + public function persist( + \ObjectModel $model, + $unitOfWorkType, + $specificKey = null + ) { + $this->unitOfWork->setWork($model, $unitOfWorkType, $specificKey); + + return $this; + } + + /** + * @return array<\ObjectModel> + * + * @throws \PrestaShopDatabaseException + * @throws \PrestaShopException + */ + public function flush() + { + $persistenceModels = $this->unitOfWork->getWork(); + $persistedModels = []; + + foreach ($persistenceModels as $externalId => $persistenceModel) { + if ($persistenceModel['unit_of_work_type'] === ObjectModelUnitOfWork::UNIT_OF_WORK_SAVE) { + $persistenceModel['object']->save(); + } + + if ($persistenceModel['unit_of_work_type'] === ObjectModelUnitOfWork::UNIT_OF_WORK_DELETE) { + $persistenceModel['object']->delete(); + } + + if (!empty($externalId)) { + $persistedModels[$externalId] = $persistenceModel['object']; + } else { + $persistedModels[] = $persistenceModel['object']; + } + } + $this->unitOfWork->clearWork(); + + return $persistedModels; + } +} diff --git a/src/EntityManager/ObjectModelUnitOfWork.php b/src/EntityManager/ObjectModelUnitOfWork.php new file mode 100644 index 000000000..7a969693b --- /dev/null +++ b/src/EntityManager/ObjectModelUnitOfWork.php @@ -0,0 +1,64 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\EntityManager; + +if (!defined('_PS_VERSION_')) { + exit; +} + +/** In memory entity manager object model unit of work */ +class ObjectModelUnitOfWork +{ + const UNIT_OF_WORK_SAVE = 'UNIT_OF_WORK_SAVE'; + const UNIT_OF_WORK_DELETE = 'UNIT_OF_WORK_DELETE'; + + private $work = []; + + public function setWork(\ObjectModel $objectModel, $unitOfWorkType, $specificKey) + { + $work = [ + 'unit_of_work_type' => $unitOfWorkType, + 'object' => $objectModel, + ]; + + if (!is_null($specificKey)) { + $this->work[$specificKey] = $work; + } else { + $this->work[] = $work; + } + } + + /** + * @return array + */ + public function getWork() + { + return $this->work; + } + + public function clearWork() + { + $this->work = []; + } +} diff --git a/src/Enum/PermissionType.php b/src/Enum/PermissionType.php new file mode 100644 index 000000000..afcf34c36 --- /dev/null +++ b/src/Enum/PermissionType.php @@ -0,0 +1,34 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Enum; + +if (!defined('_PS_VERSION_')) { + exit; +} + +class PermissionType +{ + const VIEW = 'view'; + const EDIT = 'edit'; +} diff --git a/src/Install/Installer.php b/src/Install/Installer.php index d005c53be..e7b3c7278 100755 --- a/src/Install/Installer.php +++ b/src/Install/Installer.php @@ -299,12 +299,18 @@ private function installSaferPayCardAlias() private function installSaferPayLog() { return Db::getInstance()->execute( - 'CREATE TABLE IF NOT EXISTS ' . _DB_PREFIX_ . 'saferpay_log' . '( - `id_saferpay_log` INTEGER(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY, - `message` TEXT NOT NULL, - `payload` TEXT NOT NULL, - `date_add` datetime NOT NULL - ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci' + 'CREATE TABLE IF NOT EXISTS ' . _DB_PREFIX_ . pSQL(\SaferPayLog::$definition['table']) . '( + `id_saferpay_log` INTEGER(10) UNSIGNED AUTO_INCREMENT, + `id_log` INT(10) DEFAULT 0, + `id_shop` INT(10) DEFAULT ' . (int) Configuration::get('PS_SHOP_DEFAULT') . ', + `message` TEXT DEFAULT NULL, + `request` MEDIUMTEXT DEFAULT NULL, + `response` MEDIUMTEXT DEFAULT NULL, + `context` TEXT DEFAULT NULL, + `date_add` datetime NOT NULL, + PRIMARY KEY (`id_saferpay_log`, `id_log`, `id_shop`), + INDEX (`id_log`) + ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci' ); } diff --git a/src/Logger/Formatter/LogFormatter.php b/src/Logger/Formatter/LogFormatter.php new file mode 100644 index 000000000..cfb3a9158 --- /dev/null +++ b/src/Logger/Formatter/LogFormatter.php @@ -0,0 +1,38 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Logger\Formatter; + +if (!defined('_PS_VERSION_')) { + exit; +} + +class LogFormatter implements LogFormatterInterface +{ + const SAFERPAY_LOG_PREFIX = 'SAFERPAY_MODULE_LOG:'; + + public function getMessage($message) + { + return self::SAFERPAY_LOG_PREFIX . ' ' . $message; + } +} diff --git a/src/Logger/Formatter/LogFormatterInterface.php b/src/Logger/Formatter/LogFormatterInterface.php new file mode 100644 index 000000000..f31c872bb --- /dev/null +++ b/src/Logger/Formatter/LogFormatterInterface.php @@ -0,0 +1,38 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Logger\Formatter; + +if (!defined('_PS_VERSION_')) { + exit; +} + +interface LogFormatterInterface +{ + /** + * @param string $message - an actual error message + * + * @return string + */ + public function getMessage($message); +} diff --git a/src/Logger/Logger.php b/src/Logger/Logger.php new file mode 100644 index 000000000..af87ca475 --- /dev/null +++ b/src/Logger/Logger.php @@ -0,0 +1,194 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Logger; + +use Invertus\SaferPay\Adapter\Configuration; +use Invertus\SaferPay\Adapter\LegacyContext; +use Invertus\SaferPay\Config\SaferPayConfig; +use Invertus\SaferPay\Context\GlobalShopContext; +use Invertus\SaferPay\EntityManager\ObjectModelEntityManager; +use Invertus\SaferPay\EntityManager\ObjectModelUnitOfWork; +use Invertus\SaferPay\Logger\Formatter\LogFormatterInterface; +use Invertus\SaferPay\Provider\BasicIdempotencyProvider; +use Invertus\SaferPay\Repository\PrestashopLoggerRepositoryInterface; + +class Logger implements LoggerInterface +{ + const FILE_NAME = 'Logger'; + + const LOG_OBJECT_TYPE = 'saferpayLog'; + + const SEVERITY_INFO = 1; + const SEVERITY_WARNING = 2; + const SEVERITY_ERROR = 3; + + private $logFormatter; + private $globalShopContext; + private $configuration; + private $context; + private $entityManager; + private $idempotencyProvider; + private $prestashopLoggerRepository; + + public function __construct( + LogFormatterInterface $logFormatter, + GlobalShopContext $globalShopContext, + Configuration $configuration, + LegacyContext $context, + ObjectModelEntityManager $entityManager, + BasicIdempotencyProvider $idempotencyProvider, + PrestashopLoggerRepositoryInterface $prestashopLoggerRepository + ) { + $this->logFormatter = $logFormatter; + $this->globalShopContext = $globalShopContext; + $this->configuration = $configuration; + $this->context = $context; + $this->entityManager = $entityManager; + $this->idempotencyProvider = $idempotencyProvider; + $this->prestashopLoggerRepository = $prestashopLoggerRepository; + } + + public function emergency($message, array $context = []) + { + $this->log( + $this->configuration->getAsInteger( + 'PS_LOGS_BY_EMAIL', + $this->globalShopContext->getShopId() + ), + $message, + $context + ); + } + + public function alert($message, array $context = []) + { + $this->log(self::SEVERITY_WARNING, $message, $context); + } + + public function critical($message, array $context = []) + { + $this->log( + $this->configuration->getAsInteger( + 'PS_LOGS_BY_EMAIL', + $this->globalShopContext->getShopId() + ), + $message, + $context + ); + } + + public function error($message, array $context = []) + { + $this->log(self::SEVERITY_ERROR, $message, $context); + } + + public function warning($message, array $context = []) + { + $this->log(self::SEVERITY_WARNING, $message, $context); + } + + public function notice($message, array $context = []) + { + $this->log(self::SEVERITY_INFO, $message, $context); + } + + public function info($message, array $context = []) + { + $this->log(self::SEVERITY_INFO, $message, $context); + } + + public function debug($message, array $context = []) + { + if (!SaferPayConfig::isDebugMode()) { + return; + } + + $this->log(self::SEVERITY_INFO, $message, $context); + } + + public function log($level, $message, array $context = []) + { + $idempotencyKey = $this->idempotencyProvider->getIdempotencyKey(); + + \PrestaShopLogger::addLog( + $this->logFormatter->getMessage($message), + $level, + null, + self::LOG_OBJECT_TYPE, + $idempotencyKey + ); + + $logId = $this->prestashopLoggerRepository->getLogIdByObjectId( + $idempotencyKey, + $this->globalShopContext->getShopId() + ); + + if (!$logId) { + return; + } + + $this->logContext($logId, $context); + } + + private function logContext($logId, array $context) + { + $request = ''; + $response = ''; + + if (isset($context['request'])) { + $request = $context['request']; + unset($context['request']); + } + + if (isset($context['response'])) { + $response = $context['response']; + unset($context['response']); + } + + if (isset($context['correlation-id'])) { + $correlationId = $context['correlation-id']; + unset($context['correlation-id']); + } + + $log = new \SaferPayLog(); + $log->id_log = $logId; + $log->id_shop = $this->globalShopContext->getShopId(); + $log->context = json_encode($this->getFilledContextWithShopData($context)); + $log->request = json_encode($request); + $log->response = json_encode($response); + + $this->entityManager->persist($log, ObjectModelUnitOfWork::UNIT_OF_WORK_SAVE); + $this->entityManager->flush(); + } + + private function getFilledContextWithShopData(array $context = []) + { + $context['context_id_customer'] = $this->context->getCustomerId(); + $context['id_shop'] = $this->globalShopContext->getShopId(); + $context['currency'] = $this->globalShopContext->getCurrencyIso(); + $context['id_language'] = $this->globalShopContext->getLanguageId(); + + return $context; + } +} diff --git a/src/Logger/LoggerInterface.php b/src/Logger/LoggerInterface.php new file mode 100644 index 000000000..9c3073cb0 --- /dev/null +++ b/src/Logger/LoggerInterface.php @@ -0,0 +1,32 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Logger; + +if (!defined('_PS_VERSION_')) { + exit; +} + +interface LoggerInterface extends \Psr\Log\LoggerInterface +{ +} diff --git a/src/Processor/CheckoutProcessor.php b/src/Processor/CheckoutProcessor.php index 62405046c..0d0e7c2b2 100644 --- a/src/Processor/CheckoutProcessor.php +++ b/src/Processor/CheckoutProcessor.php @@ -35,14 +35,18 @@ use Invertus\SaferPay\Exception\Api\SaferPayApiException; use Invertus\SaferPay\Exception\CouldNotProcessCheckout; use Invertus\SaferPay\Factory\ModuleFactory; +use Invertus\SaferPay\Logger\LoggerInterface; use Invertus\SaferPay\Repository\SaferPayOrderRepository; use Invertus\SaferPay\Service\SaferPayInitialize; +use Invertus\SaferPay\Utility\ExceptionUtility; use Order; use PrestaShopException; use SaferPayOrder; class CheckoutProcessor { + const FILE_NAME = 'CheckoutProcessor'; + /** @var \SaferPayOfficial */ private $module; @@ -71,7 +75,16 @@ public function run(CheckoutData $data) { $cart = new Cart($data->getCartId()); + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + if (!$cart) { + $logger->debug(sprintf('%s - Cart not found', self::FILE_NAME), [ + 'context' => [ + 'cartId' => $data->getCartId(), + ], + ]); + throw CouldNotProcessCheckout::failedToFindCart($data->getCartId()); } @@ -109,6 +122,13 @@ public function run(CheckoutData $data) $data->getIsTransaction() ); } catch (\Exception $exception) { + $logger->error($exception->getMessage(), [ + 'context' => [ + 'cartId' => $data->getCartId(), + ], + 'exceptions' => ExceptionUtility::getExceptions($exception) + ]); + throw CouldNotProcessCheckout::failedToCreateSaferPayOrder($data->getCartId()); } @@ -204,6 +224,13 @@ private function processAuthorizedOrder(CheckoutData $data, Cart $cart) $saferPayOrder->id_order = $order->id; $saferPayOrder->update(); } catch (\Exception $exception) { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + $logger->error($exception->getMessage(), [ + 'context' => [], + 'cartId' => $data->getCartId(), + ]); + throw CouldNotProcessCheckout::failedToCreateOrder($data->getCartId()); } } diff --git a/src/Repository/CollectionRepository.php b/src/Repository/CollectionRepository.php new file mode 100644 index 000000000..0f18bad29 --- /dev/null +++ b/src/Repository/CollectionRepository.php @@ -0,0 +1,67 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Repository; + +if (!defined('_PS_VERSION_')) { + exit; +} + +class CollectionRepository implements ReadOnlyCollectionRepositoryInterface +{ + /** + * @var string + */ + private $fullyClassifiedClassName; + + public function __construct($fullyClassifiedClassName) + { + $this->fullyClassifiedClassName = $fullyClassifiedClassName; + } + + public function findAllInCollection($langId = null) + { + return new \PrestaShopCollection($this->fullyClassifiedClassName, $langId); + } + + /** + * @param array $keyValueCriteria + * @param int|null $langId + * + * @return \ObjectModel|null + * + * @throws \PrestaShopException + */ + public function findOneBy(array $keyValueCriteria, $langId = null) + { + $psCollection = new \PrestaShopCollection($this->fullyClassifiedClassName, $langId); + + foreach ($keyValueCriteria as $field => $value) { + $psCollection = $psCollection->where($field, '=', $value); + } + + $first = $psCollection->getFirst(); + + return false === $first ? null : $first; + } +} diff --git a/src/Repository/PrestashopLoggerRepository.php b/src/Repository/PrestashopLoggerRepository.php new file mode 100644 index 000000000..d7190a710 --- /dev/null +++ b/src/Repository/PrestashopLoggerRepository.php @@ -0,0 +1,73 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Repository; + +use Invertus\Knapsack\Collection; +use Invertus\SaferPay\Logger\Logger; +use Invertus\SaferPay\Utility\VersionUtility; + +if (!defined('_PS_VERSION_')) { + exit; +} + +class PrestashopLoggerRepository extends CollectionRepository implements PrestashopLoggerRepositoryInterface +{ + public function __construct() + { + parent::__construct(\PrestaShopLogger::class); + } + + /** {@inheritDoc} */ + public function getLogIdByObjectId($objectId, $shopId) + { + $query = new \DbQuery(); + + $query + ->select('l.id_log') + ->from('log', 'l') + ->where('l.object_id = "' . pSQL($objectId) . '"') + ->orderBy('l.id_log DESC'); + + if (VersionUtility::isPsVersionGreaterOrEqualTo('1.7.8.0')) { + $query->where('l.id_shop = ' . (int) $shopId); + } + + $logId = \Db::getInstance()->getValue($query); + + return (int) $logId ?: null; + } + + public function prune($daysToKeep) + { + Collection::from( + $this->findAllInCollection() + ->sqlWhere('DATEDIFF(NOW(),date_add) >= ' . $daysToKeep) + ->where('object_type', '=', Logger::LOG_OBJECT_TYPE) + ) + ->each(function (\PrestaShopLogger $log) { + $log->delete(); + }) + ->realize(); + } +} diff --git a/src/Repository/PrestashopLoggerRepositoryInterface.php b/src/Repository/PrestashopLoggerRepositoryInterface.php new file mode 100644 index 000000000..9acd2ff76 --- /dev/null +++ b/src/Repository/PrestashopLoggerRepositoryInterface.php @@ -0,0 +1,41 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Repository; + +if (!defined('_PS_VERSION_')) { + exit; +} + +interface PrestashopLoggerRepositoryInterface extends ReadOnlyCollectionRepositoryInterface +{ + /** + * @param string $objectId + * @param int $shopId + * + * @return int|null + */ + public function getLogIdByObjectId($objectId, $shopId); + + public function prune($daysToKeep); +} diff --git a/src/Repository/ReadOnlyCollectionRepositoryInterface.php b/src/Repository/ReadOnlyCollectionRepositoryInterface.php new file mode 100644 index 000000000..ad4c44ea9 --- /dev/null +++ b/src/Repository/ReadOnlyCollectionRepositoryInterface.php @@ -0,0 +1,50 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Repository; + +if (!defined('_PS_VERSION_')) { + exit; +} + +interface ReadOnlyCollectionRepositoryInterface +{ + /** + * @param int|null $langId - objects which ussualy are type of array will become strings. E.g + * $product->name is string instead of multidimensional array where key is id_language. + * Always pass language id + * unless there is a special need not to. Synchronization or smth. + * It saves quite a lot performance wise. + * + * @return \PrestaShopCollection + */ + public function findAllInCollection($langId = null); + + /** + * @param array $keyValueCriteria - e.g [ 'id_cart' => 5 ] + * @param int|null $langId + * + * @return \ObjectModel|null + */ + public function findOneBy(array $keyValueCriteria, $langId = null); +} diff --git a/src/Repository/SaferPayLogRepository.php b/src/Repository/SaferPayLogRepository.php new file mode 100644 index 000000000..af17438e4 --- /dev/null +++ b/src/Repository/SaferPayLogRepository.php @@ -0,0 +1,50 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Repository; + +use Invertus\Knapsack\Collection; + +if (!defined('_PS_VERSION_')) { + exit; +} + +class SaferPayLogRepository extends CollectionRepository implements SaferPayLogRepositoryInterface +{ + public function __construct() + { + parent::__construct(\SaferPayLog::class); + } + + public function prune($daysToKeep) + { + Collection::from( + $this->findAllInCollection() + ->sqlWhere('DATEDIFF(NOW(),date_add) >= ' . $daysToKeep) + ) + ->each(function (\KlarnaPaymentLog $log) { + $log->delete(); + }) + ->realize(); + } +} diff --git a/src/Repository/SaferPayLogRepositoryInterface.php b/src/Repository/SaferPayLogRepositoryInterface.php new file mode 100644 index 000000000..240907e3b --- /dev/null +++ b/src/Repository/SaferPayLogRepositoryInterface.php @@ -0,0 +1,33 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Repository; + +if (!defined('_PS_VERSION_')) { + exit; +} + +interface SaferPayLogRepositoryInterface extends ReadOnlyCollectionRepositoryInterface +{ + public function prune($daysToKeep); +} diff --git a/src/Response/JsonResponse.php b/src/Response/JsonResponse.php new file mode 100644 index 000000000..28936f9f8 --- /dev/null +++ b/src/Response/JsonResponse.php @@ -0,0 +1,76 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Response; + +use Symfony\Component\HttpFoundation\JsonResponse as BaseJsonResponse; + +if (!defined('_PS_VERSION_')) { + exit; +} + +class JsonResponse extends BaseJsonResponse +{ + /** + * @param mixed $data + */ + public function __construct($data = null, $status = 200, array $headers = []) + { + parent::__construct($data, $status, $headers); + } + + public static function success($data, $status = 200) + { + return new self([ + 'success' => true, + 'errors' => [], + 'data' => $data, + ], $status); + } + + /** + * @param string|array $error + * @param int $status + * + * @return static + */ + public static function error($error, $status = 400) + { + if ($status === JsonResponse::HTTP_UNPROCESSABLE_ENTITY) { + // NOTE: removing rule name. ['required' => 'message'] becomes [0 => 'message'] + foreach ($error as $key => $messages) { + $error[$key] = array_values($messages); + } + } + + if (!is_array($error)) { + $error = [$error]; + } + + return new self([ + 'success' => false, + 'errors' => $error, + 'data' => [], + ], $status); + } +} diff --git a/src/Service/SaferPayInitialize.php b/src/Service/SaferPayInitialize.php index e4822f7e0..d44e8225e 100755 --- a/src/Service/SaferPayInitialize.php +++ b/src/Service/SaferPayInitialize.php @@ -31,9 +31,11 @@ use Invertus\SaferPay\DTO\Request\Initialize\InitializeRequest; use Invertus\SaferPay\Enum\ControllerName; use Invertus\SaferPay\Exception\Api\SaferPayApiException; +use Invertus\SaferPay\Logger\LoggerInterface; use Invertus\SaferPay\Repository\SaferPayCardAliasRepository; use Invertus\SaferPay\Factory\ModuleFactory; use Invertus\SaferPay\Service\Request\InitializeRequestObjectCreator; +use Invertus\SaferPay\Utility\ExceptionUtility; use SaferPayOfficial; if (!defined('_PS_VERSION_')) { @@ -42,6 +44,7 @@ class SaferPayInitialize { + const FILE_NAME = 'SaferPayInitialize'; /** * @var SaferPayOfficial */ @@ -89,6 +92,13 @@ public function initialize(InitializeRequest $initializeRequest, $isBusinessLice try { $initialize = $this->initializeService->initialize($initializeRequest, $isBusinessLicence); } catch (Exception $e) { + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + $logger->error($e->getMessage(), [ + 'context' => [], + 'exceptions' => ExceptionUtility::getExceptions($e), + ]); + throw new SaferPayApiException('Initialize API failed', SaferPayApiException::INITIALIZE); } diff --git a/src/Service/SaferPayObtainPaymentMethods.php b/src/Service/SaferPayObtainPaymentMethods.php index c0635d25e..27a00dbe0 100755 --- a/src/Service/SaferPayObtainPaymentMethods.php +++ b/src/Service/SaferPayObtainPaymentMethods.php @@ -26,7 +26,9 @@ use Exception; use Invertus\SaferPay\Api\Request\ObtainPaymentMethodsService; use Invertus\SaferPay\Exception\Api\SaferPayApiException; +use Invertus\SaferPay\Logger\LoggerInterface; use Invertus\SaferPay\Service\Request\ObtainPaymentMethodsObjectCreator; +use function Invertus\Knapsack\toArray; if (!defined('_PS_VERSION_')) { exit; @@ -34,18 +36,22 @@ class SaferPayObtainPaymentMethods { + const FILE_NAME = 'SaferPayObtainPaymentMethods'; private $obtainPaymentMethodsService; private $obtainPaymentMethodsObjectCreator; private $saferPayPaymentNotation; + private $logger; public function __construct( ObtainPaymentMethodsService $obtainPaymentMethodsService, ObtainPaymentMethodsObjectCreator $obtainPaymentMethodsObjectCreator, - SaferPayPaymentNotation $saferPayPaymentNotation + SaferPayPaymentNotation $saferPayPaymentNotation, + LoggerInterface $logger ) { $this->obtainPaymentMethodsService = $obtainPaymentMethodsService; $this->obtainPaymentMethodsObjectCreator = $obtainPaymentMethodsObjectCreator; $this->saferPayPaymentNotation = $saferPayPaymentNotation; + $this->logger = $logger; } public function obtainPaymentMethods() @@ -57,6 +63,11 @@ public function obtainPaymentMethods() $this->obtainPaymentMethodsObjectCreator->create() ); } catch (Exception $e) { + $this->logger->debug(sprintf('%s - failed to get payment methods list', self::FILE_NAME), [ + 'context' => [], + 'exception' => $e + ]); + throw new SaferPayApiException('Initialize API failed', SaferPayApiException::INITIALIZE); } diff --git a/src/Service/SaferPayOrderStatusService.php b/src/Service/SaferPayOrderStatusService.php index d3c32483e..c608e5dc6 100755 --- a/src/Service/SaferPayOrderStatusService.php +++ b/src/Service/SaferPayOrderStatusService.php @@ -36,10 +36,12 @@ use Invertus\SaferPay\Enum\ControllerName; use Invertus\SaferPay\Exception\Api\SaferPayApiException; use Invertus\SaferPay\Factory\ModuleFactory; +use Invertus\SaferPay\Logger\LoggerInterface; use Invertus\SaferPay\Repository\SaferPayOrderRepository; use Invertus\SaferPay\Service\Request\CancelRequestObjectCreator; use Invertus\SaferPay\Service\Request\CaptureRequestObjectCreator; use Invertus\SaferPay\Service\Request\RefundRequestObjectCreator; +use Invertus\SaferPay\Utility\ExceptionUtility; use Order; use SaferPayAssert; use SaferPayOfficial; @@ -51,6 +53,7 @@ class SaferPayOrderStatusService { + const FILE_NAME = 'SaferPayOrderStatusService'; /** * @var CaptureService */ @@ -89,6 +92,10 @@ class SaferPayOrderStatusService * @var SaferPayOfficial */ private $module; + /** + * @var LoggerInterface + */ + private $logger; public function __construct( CaptureService $captureService, @@ -99,7 +106,8 @@ public function __construct( RefundService $refundService, RefundRequestObjectCreator $refundRequestObjectCreator, LegacyContext $context, - ModuleFactory $module + ModuleFactory $module, + LoggerInterface $logger ) { $this->captureService = $captureService; $this->captureRequestObjectCreator = $captureRequestObjectCreator; @@ -110,6 +118,7 @@ public function __construct( $this->refundRequestObjectCreator = $refundRequestObjectCreator; $this->context = $context; $this->module = $module->getModule(); + $this->logger = $logger; } public function setPending(Order $order) @@ -155,6 +164,11 @@ public function capture(Order $order, $refundedAmount = 0, $isRefund = false) try { $captureResponse = $this->captureService->capture($captureRequest); } catch (Exception $e) { + $this->logger->error($e->getMessage(), [ + 'context' => [], + 'exceptions' => ExceptionUtility::getExceptions($e), + ]); + throw new SaferPayApiException('Capture API failed', SaferPayApiException::CAPTURE); } @@ -191,6 +205,13 @@ public function cancel(Order $order) try { $this->cancelService->cancel($cancelRequest); } catch (Exception $e) { + $this->logger->error($e->getMessage(), [ + 'context' => [ + 'orderId' => $order->id, + ], + 'exceptions' => ExceptionUtility::getExceptions($e), + ]); + throw new SaferPayApiException('Cancel API failed', SaferPayApiException::CANCEL); } $order->setCurrentState(_SAFERPAY_PAYMENT_CANCELED_); @@ -248,6 +269,10 @@ public function refund(Order $order, $refundedAmount) try { $refundResponse = $this->refundService->refund($refundRequest); } catch (Exception $e) { + $this->logger->error($e->getMessage(), [ + 'exceptions' => ExceptionUtility::getExceptions($e), + ]); + throw new SaferPayApiException('Refund API failed', SaferPayApiException::REFUND); } $saferPayOrder->refund_id = $refundResponse->Transaction->Id; diff --git a/src/Service/TransactionFlow/SaferPayTransactionAssertion.php b/src/Service/TransactionFlow/SaferPayTransactionAssertion.php index 5fcc35496..bbe2cfe70 100755 --- a/src/Service/TransactionFlow/SaferPayTransactionAssertion.php +++ b/src/Service/TransactionFlow/SaferPayTransactionAssertion.php @@ -25,6 +25,7 @@ use Invertus\SaferPay\Api\Request\AssertService; use Invertus\SaferPay\DTO\Response\Assert\AssertBody; +use Invertus\SaferPay\Logger\LoggerInterface; use Invertus\SaferPay\Repository\SaferPayOrderRepository; use Invertus\SaferPay\Service\Request\AssertRequestObjectCreator; use SaferPayOrder; @@ -35,6 +36,7 @@ class SaferPayTransactionAssertion { + const FILE_NAME = 'SaferPayTransactionAssertion'; /** * @var AssertRequestObjectCreator */ @@ -49,15 +51,21 @@ class SaferPayTransactionAssertion * @var AssertService */ private $assertionService; + /** + * @var LoggerInterface + */ + private $logger; public function __construct( AssertRequestObjectCreator $assertRequestCreator, SaferPayOrderRepository $orderRepository, - AssertService $assertionService + AssertService $assertionService, + LoggerInterface $logger ) { $this->assertRequestCreator = $assertRequestCreator; $this->orderRepository = $orderRepository; $this->assertionService = $assertionService; + $this->logger = $logger; } /** @@ -69,7 +77,13 @@ public function __construct( public function assert($cartId, $update = true) { $saferPayOrder = new SaferPayOrder($this->orderRepository->getIdByCartId($cartId)); - \PrestaShopLogger::addLog('saferpayOrderId:' . $saferPayOrder->id); + + $this->logger->debug(sprintf('%s - assert service called',self::FILE_NAME), [ + 'context' => [ + 'cart_id' => $cartId, + 'saferpay_order_id' => $saferPayOrder->id, + ], + ]); $assertRequest = $this->assertRequestCreator->create($saferPayOrder->token); $assertResponse = $this->assertionService->assert($assertRequest, $saferPayOrder->id); @@ -90,6 +104,13 @@ public function assert($cartId, $update = true) $saferPayOrder->update(); } + $this->logger->debug(sprintf('%s - assert service ended',self::FILE_NAME), [ + 'context' => [ + 'cart_id' => $cartId, + 'saferpay_order_id' => $saferPayOrder->id, + ], + ]); + return $assertBody; } } diff --git a/src/ServiceProvider/BaseServiceProvider.php b/src/ServiceProvider/BaseServiceProvider.php index fb547e645..789a7f320 100755 --- a/src/ServiceProvider/BaseServiceProvider.php +++ b/src/ServiceProvider/BaseServiceProvider.php @@ -23,10 +23,22 @@ namespace Invertus\SaferPay\ServiceProvider; +use Invertus\SaferPay\Context\GlobalShopContext; +use Invertus\SaferPay\EntityManager\EntityManagerInterface; +use Invertus\SaferPay\EntityManager\ObjectModelEntityManager; +use Invertus\SaferPay\Logger\Formatter\LogFormatter; +use Invertus\SaferPay\Logger\Formatter\LogFormatterInterface; +use Invertus\SaferPay\Logger\Logger; +use Invertus\SaferPay\Logger\LoggerInterface; use Invertus\SaferPay\Provider\BasicIdempotencyProvider; use Invertus\SaferPay\Provider\IdempotencyProviderInterface; use Invertus\SaferPay\Repository\OrderRepository; use Invertus\SaferPay\Repository\OrderRepositoryInterface; +use Invertus\SaferPay\Repository\PrestashopLoggerRepository; +use Invertus\SaferPay\Repository\PrestashopLoggerRepositoryInterface; +use Invertus\SaferPay\Repository\SaferPayLogRepository; +use Invertus\SaferPay\Repository\SaferPayLogRepositoryInterface; +use Invertus\SaferPay\Context\GlobalShopContextInterface; use League\Container\Container; if (!defined('_PS_VERSION_')) { @@ -48,7 +60,13 @@ public function __construct($extendedServices) public function register(Container $container) { $this->addService($container, IdempotencyProviderInterface::class, $container->get(BasicIdempotencyProvider::class)); + $this->addService($container, LogFormatterInterface::class, $container->get(LogFormatter::class)); + $this->addService($container, GlobalShopContextInterface::class, $container->get(GlobalShopContext::class)); $this->addService($container, OrderRepositoryInterface::class, $container->get(OrderRepository::class)); + $this->addService($container, SaferPayLogRepositoryInterface::class, $container->get(SaferPayLogRepository::class)); + $this->addService($container, PrestashopLoggerRepositoryInterface::class, $container->get(PrestashopLoggerRepository::class)); + $this->addService($container, LoggerInterface::class, $container->get(Logger::class)); + $this->addService($container, EntityManagerInterface::class, $container->get(ObjectModelEntityManager::class)); } private function addService(Container $container, $className, $service) diff --git a/src/Utility/ExceptionUtility.php b/src/Utility/ExceptionUtility.php new file mode 100644 index 000000000..2ee3495cc --- /dev/null +++ b/src/Utility/ExceptionUtility.php @@ -0,0 +1,57 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Utility; + +if (!defined('_PS_VERSION_')) { + exit; +} + +class ExceptionUtility +{ + public static function getExceptions($exception) + { + if (method_exists($exception, 'getExceptions')) { + return $exception->getExceptions(); + } + + return [self::toArray($exception)]; + } + + public static function toArray($exception) + { + if (method_exists($exception, 'getContext')) { + $context = $exception->getContext(); + } else { + $context = []; + } + + return [ + 'message' => (string) $exception->getMessage(), + 'code' => (int) $exception->getCode(), + 'file' => (string) $exception->getFile(), + 'line' => (int) $exception->getLine(), + 'context' => $context, + ]; + } +} diff --git a/src/Utility/VersionUtility.php b/src/Utility/VersionUtility.php new file mode 100644 index 000000000..d19b7ac7d --- /dev/null +++ b/src/Utility/VersionUtility.php @@ -0,0 +1,61 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Utility; + +if (!defined('_PS_VERSION_')) { + exit; +} + +class VersionUtility +{ + public static function isPsVersionLessThan($version) + { + return version_compare(_PS_VERSION_, $version, '<'); + } + + public static function isPsVersionGreaterThan($version) + { + return version_compare(_PS_VERSION_, $version, '>'); + } + + public static function isPsVersionGreaterOrEqualTo($version) + { + return version_compare(_PS_VERSION_, $version, '>='); + } + + public static function isPsVersionLessThanOrEqualTo($version) + { + return version_compare(_PS_VERSION_, $version, '<='); + } + + public static function isPsVersionEqualTo($version) + { + return version_compare(_PS_VERSION_, $version, '='); + } + + public static function current() + { + return _PS_VERSION_; + } +} diff --git a/upgrade/install-1.2.4.php b/upgrade/install-1.2.4.php new file mode 100644 index 000000000..e3ced5e0d --- /dev/null +++ b/upgrade/install-1.2.4.php @@ -0,0 +1,41 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +if (!defined('_PS_VERSION_')) { + exit; +} + +function upgrade_module_1_2_4(SaferPayOfficial $module) +{ + return Db::getInstance()->execute( + 'ALTER TABLE ' . _DB_PREFIX_ . pSQL(SaferPayLog::$definition['table']) . ' + ADD COLUMN `id_log` INT(10) DEFAULT 0, + ADD COLUMN `id_shop` INT(10) DEFAULT ' . (int) Configuration::get('PS_SHOP_DEFAULT') . ', + CHANGE `payload` `request` TEXT, + ADD COLUMN `response` MEDIUMTEXT DEFAULT NULL, + ADD COLUMN `context` MEDIUMTEXT DEFAULT NULL, + DROP PRIMARY KEY, + PRIMARY KEY (`id_saferpay_log`, `id_log`, `id_shop`), + ADD INDEX (`id_log`),' + ); +} diff --git a/var/cache/index.php b/var/cache/index.php old mode 100755 new mode 100644 index ee6227264..9d92aad2a --- a/var/cache/index.php +++ b/var/cache/index.php @@ -28,4 +28,4 @@ header('Pragma: no-cache'); header('Location: ../'); -exit; +exit; \ No newline at end of file diff --git a/views/css/admin/logs_tab.css b/views/css/admin/logs_tab.css index f679c02ce..5bb36a92f 100755 --- a/views/css/admin/logs_tab.css +++ b/views/css/admin/logs_tab.css @@ -22,4 +22,92 @@ .saferpay-text-break { word-break: break-all; width: 700px; -} \ No newline at end of file +} + +.button { + cursor: pointer; +} + +.log-modal-overlay { + transition: opacity 0.2s ease-out; + pointer-events: none; + background: rgba(15, 23, 42, 0.8); + position: fixed; + opacity: 0; + bottom: 0; + right: 0; + left: 0; + top: 0; +} + +.modal.open .log-modal-overlay { + pointer-events: all; + opacity: 0.5; +} + +.log-modal-window { + position: relative; + width: 50%; + margin: 10% auto; + + background: #ffffff; + border-radius: 0.5em; + box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); + pointer-events: all; + text-align: left; + max-height: 100vh; + min-height: 60vh; + display: flex; + flex-direction: column; + + overflow: auto; +} + +.open { + display: block; +} + +.log-modal-title { + color: #111827; + padding: 3px; + border-bottom: solid 1px grey; + pointer-events: all; + display: flex; + justify-content: center; + max-height: 10vh; +} + +.log-modal-content { + padding: 15px; + height: 50vh; +} + +.log-modal-content-spinner { + min-height: 50vh; +} + +.log-modal-content-spinner:not(.hidden) { + display: flex; + justify-content: center; + align-items: center; +} + +.log-modal-content-spinner::after { + content: ""; + width: 40px; + height: 40px; + border: 2px solid #f3f3f3; + border-top: 3px solid #f25a41; + border-radius: 100%; + will-change: transform; + animation: spin 1s infinite linear +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/views/js/admin/log.js b/views/js/admin/log.js new file mode 100644 index 000000000..4a8eb769a --- /dev/null +++ b/views/js/admin/log.js @@ -0,0 +1,65 @@ +/** + *NOTICE OF LICENSE + * + *This source file is subject to the Open Software License (OSL 3.0) + *that is bundled with this package in the file LICENSE.txt. + *It is also available through the world-wide-web at this URL: + *http://opensource.org/licenses/osl-3.0.php + *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. + * + *DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade PrestaShop to newer + *versions in the future. If you wish to customize PrestaShop for your + *needs please refer to http://www.prestashop.com for more information. + * + *@author INVERTUS UAB www.invertus.eu + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +$(document).ready(function () { + $('.log-modal-overlay').on('click', function (event) { + $('.modal.open').removeClass('open'); + event.preventDefault(); + }); + + $('.js-log-button').on('click', function (event) { + var logId = $(this).data('log-id'); + var informationType = $(this).data('information-type'); + + // NOTE: opening modal + $('#' + $(this).data('target')).addClass('open'); + + // NOTE: if information has been set already we don't need to call ajax again. + if (!$('#log-modal-' + logId + '-' + informationType + ' .log-modal-content-data').hasClass('hidden')) { + return; + } + + $('.log-modal-content-spinner').removeClass('hidden'); + + $.ajax({ + type: 'POST', + url: saferpayofficial.logsUrl, + data: { + ajax: true, + action: 'getLog', + log_id: logId + } + }) + .then(response => jQuery.parseJSON(response)) + .then(data => { + $('.log-modal-content-spinner').addClass('hidden') + + $('#log-modal-' + logId + '-request .log-modal-content-data').removeClass('hidden').html(prettyJson(data.log.request)); + $('#log-modal-' + logId + '-response .log-modal-content-data').removeClass('hidden').html(prettyJson(data.log.response)); + $('#log-modal-' + logId + '-context .log-modal-content-data').removeClass('hidden').html(prettyJson(data.log.context)); + }) + }); +}); + +function prettyJson(json) { + return JSON.stringify(JSON.parse(json), null, 2) +} diff --git a/views/templates/admin/logs/log_modal.tpl b/views/templates/admin/logs/log_modal.tpl new file mode 100644 index 000000000..62cb43dd4 --- /dev/null +++ b/views/templates/admin/logs/log_modal.tpl @@ -0,0 +1,53 @@ +{** + *NOTICE OF LICENSE + * + *This source file is subject to the Open Software License (OSL 3.0) + *that is bundled with this package in the file LICENSE.txt. + *It is also available through the world-wide-web at this URL: + *http://opensource.org/licenses/osl-3.0.php + *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. + * + *DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade PrestaShop to newer + *versions in the future. If you wish to customize PrestaShop for your + *needs please refer to http://www.prestashop.com for more information. + * + *@author INVERTUS UAB www.invertus.eu + *@copyright SIX Payment Services + *@license SIX Payment Services + *} +
+ {l s='View' mod='saferpayofficial'} +
+ + \ No newline at end of file diff --git a/views/templates/admin/logs/severity_level_column.tpl b/views/templates/admin/logs/severity_level_column.tpl new file mode 100644 index 000000000..1629dc078 --- /dev/null +++ b/views/templates/admin/logs/severity_level_column.tpl @@ -0,0 +1,32 @@ +{** + *NOTICE OF LICENSE + * + *This source file is subject to the Open Software License (OSL 3.0) + *that is bundled with this package in the file LICENSE.txt. + *It is also available through the world-wide-web at this URL: + *http://opensource.org/licenses/osl-3.0.php + *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. + * + *DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade PrestaShop to newer + *versions in the future. If you wish to customize PrestaShop for your + *needs please refer to http://www.prestashop.com for more information. + * + *@author INVERTUS UAB www.invertus.eu + *@copyright SIX Payment Services + *@license SIX Payment Services + *} +{if $log_severity_level == $log_severity_level_informative} + {l s='Informative only' mod='saferpayofficial'} ({$log_severity_level|intval}) +{elseif $log_severity_level == $log_severity_level_warning} + {l s='Warning' mod='saferpayofficial'} ({$log_severity_level|intval}) +{elseif $log_severity_level == $log_severity_level_error} + {l s='Error' mod='saferpayofficial'} ({$log_severity_level|intval}) +{elseif $log_severity_level == $log_severity_level_major} + {l s='Major issue (crash)!' mod='saferpayofficial'} ({$log_severity_level|intval}) +{else} + {$log_severity_level|escape:'htmlall':'UTF-8'} +{/if} \ No newline at end of file diff --git a/views/templates/admin/logs/severity_levels.tpl b/views/templates/admin/logs/severity_levels.tpl new file mode 100644 index 000000000..c6ab90fa6 --- /dev/null +++ b/views/templates/admin/logs/severity_levels.tpl @@ -0,0 +1,34 @@ +{** + *NOTICE OF LICENSE + * + *This source file is subject to the Open Software License (OSL 3.0) + *that is bundled with this package in the file LICENSE.txt. + *It is also available through the world-wide-web at this URL: + *http://opensource.org/licenses/osl-3.0.php + *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. + * + *DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade PrestaShop to newer + *versions in the future. If you wish to customize PrestaShop for your + *needs please refer to http://www.prestashop.com for more information. + * + *@author INVERTUS UAB www.invertus.eu + *@copyright SIX Payment Services + *@license SIX Payment Services + *} +
+

+ + {l s='Severity levels:' mod='saferpayofficial'} +

+

{l s='Meaning of severity levels:' mod='saferpayofficial'}

+
    +
  1. {l s='Info' mod='saferpayofficial'}
  2. +
  3. {l s='Warning' mod='saferpayofficial'}
  4. +
  5. {l s='Error' mod='saferpayofficial'}
  6. +
  7. {l s='Fatal' mod='saferpayofficial'}
  8. +
+
\ No newline at end of file