Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PIPRES-342: Cloudsync connect #831

Merged
merged 6 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"webmozart/assert": "^1.11",
"symfony/http-client": "^4.4",
"http-interop/http-factory-guzzle": "^1.1",
"php-http/message-factory": "^1.1"
"php-http/message-factory": "^1.1",
"prestashop/prestashop-accounts-installer": "^1.0.4",
"prestashop/module-lib-mbo-installer": "^2.0"
},
"require-dev": {
"roave/security-advisories": "dev-latest",
Expand All @@ -41,11 +43,11 @@
},
"config": {
"platform": {
"php": "7.2"
"php": "7.2.5"
},
"prepend-autoloader": false,
"allow-plugins": {
"php-http/discovery": true
"php-http/discovery": false
}
},
"type": "prestashop-module",
Expand Down
232 changes: 204 additions & 28 deletions controllers/admin/AdminMollieSettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,25 @@
exit;
}

use Mollie\Adapter\ConfigurationAdapter;
use Mollie\Adapter\ToolsAdapter;
use Mollie\Builder\Content\BaseInfoBlock;
use Mollie\Builder\Content\UpdateMessageInfoBlock;
use Mollie\Config\Config;
use Mollie\Install\PrestaShopDependenciesInstall;
use Mollie\Logger\PrestaLoggerInterface;
use Mollie\Repository\ModuleRepository;
use Mollie\Service\Content\TemplateParserInterface;
use Mollie\Service\SettingsSaveService;
use PrestaShop\Module\PsEventbus\Service\PresenterService;
use PrestaShop\PrestaShop\Core\Addon\Module\ModuleManagerBuilder;
use PrestaShop\PsAccountsInstaller\Installer\Exception\ModuleNotInstalledException;
use PrestaShop\PsAccountsInstaller\Installer\Facade\PsAccounts;

class AdminMollieSettingsController extends ModuleAdminController
{
private const FILE_NAME = 'AdminMollieSettingsController';

/** @var Mollie */
public $module;

Expand All @@ -27,48 +44,77 @@ public function __construct()
$this->bootstrap = true;
}

public function postProcess()
public function initContent(): void
{
/** @var \Mollie\Repository\ModuleRepository $moduleRepository */
$moduleRepository = $this->module->getService(\Mollie\Repository\ModuleRepository::class);
$moduleDatabaseVersion = $moduleRepository->getModuleDatabaseVersion($this->module->name);
$needsUpgrade = Tools::version_compare($this->module->version, $moduleDatabaseVersion, '>');
if ($needsUpgrade) {
$this->context->controller->errors[] = $this->module->l('Please upgrade Mollie module');
$this->checkPrestaShopDependenciesHealth();
$this->setEnvironmentForAccounts();
$this->setEnvironmentForCloudSync();

return;
}
$this->content .= $this->context->smarty->fetch($this->module->getLocalPath() . '/views/templates/admin/_configure/configuration.tpl');

$isShopContext = Shop::getContext() === Shop::CONTEXT_SHOP;
$this->content .= $this->displayModuleSettings();

if (!$isShopContext) {
$this->context->controller->errors[] = $this->module->l('Select the shop that you want to configure');
$this->addJs($this->module->getPathUri() . '/views/js/admin/_configure/configuration.js');

return;
}
parent::initContent();
}

public function postProcess()
{
/** @var ConfigurationAdapter $configuration */
$configuration = $this->module->getService(ConfigurationAdapter::class);

/** @var \Mollie\Service\Content\TemplateParserInterface $templateParser */
$templateParser = $this->module->getService(\Mollie\Service\Content\TemplateParserInterface::class);
/** @var ToolsAdapter $tools */
$tools = $this->module->getService(ToolsAdapter::class);

$isSubmitted = (bool) Tools::isSubmit("submit{$this->module->name}");
$isSubmitted = $tools->isSubmit("submit{$this->module->name}");

/* @phpstan-ignore-next-line */
if (false === Configuration::get(Mollie\Config\Config::MOLLIE_STATUS_AWAITING) && !$isSubmitted) {
if (!$isSubmitted && !$configuration->get(Config::MOLLIE_STATUS_AWAITING)) {
$this->context->controller->errors[] = $this->module->l('Select an order status for \"Status for Awaiting payments\" in the \"Advanced settings\" tab');
}

$errors = [];

if (Tools::isSubmit("submit{$this->module->name}")) {
/** @var \Mollie\Service\SettingsSaveService $saveSettingsService */
$saveSettingsService = $this->module->getService(\Mollie\Service\SettingsSaveService::class);
if ($tools->isSubmit("submit{$this->module->name}")) {
/** @var SettingsSaveService $saveSettingsService */
$saveSettingsService = $this->module->getService(SettingsSaveService::class);

$resultMessages = $saveSettingsService->saveSettings($errors);

if (!empty($errors)) {
$this->context->controller->errors = $resultMessages;
$this->context->controller->errors = array_merge(
$this->context->controller->errors,
$resultMessages
);
} else {
$this->context->controller->confirmations = $resultMessages;
$this->context->controller->confirmations = array_merge(
$this->context->controller->confirmations,
$resultMessages
);
}
}
}

private function displayModuleSettings(): string
{
/** @var ModuleRepository $moduleRepository */
$moduleRepository = $this->module->getService(ModuleRepository::class);

$moduleDatabaseVersion = $moduleRepository->getModuleDatabaseVersion($this->module->name);
$needsUpgrade = Tools::version_compare($this->module->version, $moduleDatabaseVersion, '>');

if ($needsUpgrade) {
$this->context->controller->errors[] = $this->module->l('Please upgrade Mollie module');

return '';
}

if (\Shop::getContext() !== \Shop::CONTEXT_SHOP) {
$this->context->controller->errors[] = $this->module->l('Select the shop that you want to configure');

return '';
}

Media::addJsDef([
'description_message' => addslashes($this->module->l('Enter a description')),
Expand All @@ -85,6 +131,9 @@ public function postProcess()
'not_valid_file_message' => addslashes($this->module->l('Invalid file: %s%')),
]);

/** @var TemplateParserInterface $templateParser */
$templateParser = $this->module->getService(TemplateParserInterface::class);

$this->context->controller->addJS($this->module->getPathUri() . 'views/js/method_countries.js');
$this->context->controller->addJS($this->module->getPathUri() . 'views/js/validation.js');
$this->context->controller->addJS($this->module->getPathUri() . 'views/js/admin/settings.js');
Expand All @@ -101,8 +150,9 @@ public function postProcess()
$this->module->getLocalPath() . 'views/templates/admin/logo.tpl'
);

/** @var \Mollie\Builder\Content\UpdateMessageInfoBlock $updateMessageInfoBlock */
$updateMessageInfoBlock = $this->module->getService(\Mollie\Builder\Content\UpdateMessageInfoBlock::class);
/** @var UpdateMessageInfoBlock $updateMessageInfoBlock */
$updateMessageInfoBlock = $this->module->getService(UpdateMessageInfoBlock::class);

$updateMessageInfoBlockData = $updateMessageInfoBlock->setAddons(false);

$html .= $templateParser->parseTemplate(
Expand All @@ -111,8 +161,9 @@ public function postProcess()
$this->module->getLocalPath() . 'views/templates/admin/updateMessage.tpl'
);

/** @var \Mollie\Builder\Content\BaseInfoBlock $baseInfoBlock */
$baseInfoBlock = $this->module->getService(\Mollie\Builder\Content\BaseInfoBlock::class);
/** @var BaseInfoBlock $baseInfoBlock */
$baseInfoBlock = $this->module->getService(BaseInfoBlock::class);

$this->context->smarty->assign($baseInfoBlock->buildParams());

/** @var \Mollie\Builder\FormBuilder $settingsFormBuilder */
Expand All @@ -126,6 +177,131 @@ public function postProcess()
$this->context->controller->errors[] = $this->module->l('The database tables are missing. Reset the module.');
}

$this->content .= $html;
return $html;
}

private function setEnvironmentForAccounts(): void
{
/** @var PrestaLoggerInterface $logger */
$logger = $this->module->getService(PrestaLoggerInterface::class);

try {
/** @var PsAccounts $accountsFacade */
$accountsFacade = $this->module->getService(PsAccounts::class);

$psAccountsPresenter = $accountsFacade->getPsAccountsPresenter();
$psAccountsService = $accountsFacade->getPsAccountsService();
} catch (ModuleNotInstalledException $exception) {
$logger->error('PrestaShop Accounts is not installed', [
'Exception message' => $exception->getMessage(),
'Exception code' => $exception->getCode(),
]);

$this->context->controller->errors[] =
$this->module->l('PrestaShop Accounts is not installed. Please contact support.', self::FILE_NAME);

return;
} catch (\Throwable $exception) {
$logger->error('PrestaShop Accounts unknown error.', [
'Exception message' => $exception->getMessage(),
'Exception code' => $exception->getCode(),
]);

$this->context->controller->errors[] =
$this->module->l('PrestaShop Accounts initialization failed. Please contact support.', self::FILE_NAME);

return;
}

try {
Media::addJsDef([
'contextPsAccounts' => $psAccountsPresenter->present(),
]);
} catch (\Throwable $exception) {
$logger->error('PrestaShop Accounts presenter unknown error.', [
'Exception message' => $exception->getMessage(),
'Exception code' => $exception->getCode(),
]);

$this->context->controller->errors[] =
$this->module->l('PrestaShop Accounts presenter error. Please contact support.', self::FILE_NAME);

return;
}

$this->context->smarty->assign([
'urlAccountsCdn' => $psAccountsService->getAccountsCdn(),
]);
}

private function setEnvironmentForCloudSync(): void
{
/** @var PrestaLoggerInterface $logger */
$logger = $this->module->getService(PrestaLoggerInterface::class);

$moduleManager = ModuleManagerBuilder::getInstance();

if (!$moduleManager) {
$this->context->controller->errors[] =
$this->module->l('Failed to get module manager builder instance.', self::FILE_NAME);
}

$moduleManager = $moduleManager->build();

/** @var \Ps_eventbus $eventbusModule */
$eventbusModule = \Module::getInstanceByName('ps_eventbus');

if (!version_compare($eventbusModule->version, '1.9.0', '>=')) {
try {
$moduleManager->install('ps_eventbus');
} catch (\Throwable $exception) {
$logger->error('Failed to upgrade PrestaShop Event Bus.', [
'Exception message' => $exception->getMessage(),
'Exception code' => $exception->getCode(),
]);

$this->context->controller->errors[] =
$this->module->l('Failed to upgrade PrestaShop Event Bus. Please contact support.', self::FILE_NAME);

return;
}
}

/** @var PresenterService $eventbusPresenterService */
$eventbusPresenterService = $eventbusModule->getService(PresenterService::class);

Media::addJsDef([
'contextPsEventbus' => $eventbusPresenterService->expose($this->module, ['orders']),
]);

$this->context->smarty->assign([
'cloudSyncPathCDC' => Config::PRESTASHOP_CLOUDSYNC_CDN,
]);
}

private function checkPrestaShopDependenciesHealth(): void
{
/** @var PrestaShopDependenciesInstall $prestaShopDependenciesInstaller */
$prestaShopDependenciesInstaller = $this->module->getService(PrestaShopDependenciesInstall::class);

/** @var PrestaLoggerInterface $logger */
$logger = $this->module->getService(PrestaLoggerInterface::class);

try {
/*
* TODO if eventbus is installed in current page load context, error still will be thrown "install eventbus".
* After refresh everything is working, but it could be annoying to some merchants.
* Not critical error, but improvement would be nice.
*/
$prestaShopDependenciesInstaller->install();
} catch (\Throwable $exception) {
$logger->error('Failed to install PrestaShop dependencies', [
'Exception message' => $exception->getMessage(),
'Exception code' => $exception->getCode(),
]);

$this->context->controller->errors[] =
$this->module->l('Failed to install PrestaShop dependencies. Please contact support.', self::FILE_NAME);
}
}
}
20 changes: 20 additions & 0 deletions mollie.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Mollie\Exception\ShipmentCannotBeSentException;
use Mollie\Handler\ErrorHandler\ErrorHandler;
use Mollie\Handler\Shipment\ShipmentSenderHandlerInterface;
use Mollie\Install\PrestaShopDependenciesInstall;
use Mollie\Logger\PrestaLoggerInterface;
use Mollie\Provider\ProfileIdProviderInterface;
use Mollie\Repository\MolOrderPaymentFeeRepositoryInterface;
Expand Down Expand Up @@ -168,6 +169,25 @@ public function install()
return false;
}

/** @var PrestaShopDependenciesInstall $prestaShopDependenciesInstaller */
$prestaShopDependenciesInstaller = $this->getService(PrestaShopDependenciesInstall::class);

/** @var PrestaLoggerInterface $logger */
$logger = $this->getService(PrestaLoggerInterface::class);

try {
$prestaShopDependenciesInstaller->install();
} catch (\Throwable $exception) {
$logger->error('Failed to install PrestaShop dependencies', [
'Exception message' => $exception->getMessage(),
'Exception code' => $exception->getCode(),
]);

$this->_errors[] = $this->l('Failed to install PrestaShop dependencies. Please contact support.');

return false;
}

// TODO inject base install and subscription services
$coreInstaller = $this->getService(Mollie\Install\Installer::class);

Expand Down
13 changes: 13 additions & 0 deletions src/Config/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Mollie\Api\Types\PaymentStatus;
use Mollie\Api\Types\RefundStatus;
use Mollie\Utility\EnvironmentUtility;
use Mollie\Utility\PsVersionUtility;

if (!defined('_PS_VERSION_')) {
exit;
Expand Down Expand Up @@ -318,6 +319,18 @@ class Config

const MOLLIE_BUTTON_ORDER_TOTAL_REFRESH = 'MOLLIE_BUTTON_ORDER_TOTAL_REFRESH';

public const PRESTASHOP_ACCOUNTS_INSTALLER_VERSION = '5.0.0';
public const PRESTASHOP_CLOUDSYNC_CDN = 'https://assets.prestashop3.com/ext/cloudsync-merchant-sync-consent/latest/cloudsync-cdc.js';

public static function getPsAccountsVersion(): string
{
if (PsVersionUtility::isPsVersionGreaterOrEqualTo(_PS_VERSION_, '8.0.0')) {
return '6.0.0';
}

return '5.0.0';
}

// TODO migrate functions below to separate service
public static function getStatuses()
{
Expand Down
5 changes: 5 additions & 0 deletions src/Exception/Code/ExceptionCode.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ class ExceptionCode
public const INFRASTRUCTURE_LOCK_EXISTS = 1003;
public const INFRASTRUCTURE_LOCK_ON_ACQUIRE_IS_MISSING = 1004;
public const INFRASTRUCTURE_LOCK_ON_RELEASE_IS_MISSING = 1005;
public const INFRASTRUCTURE_FAILED_TO_INSTALL_MBO_INSTALLER = 1006;
public const INFRASTRUCTURE_FAILED_TO_INSTALL_DEPENDENCIES = 1007;
public const INFRASTRUCTURE_FAILED_TO_RETRIEVE_MODULE_MANAGER_BUILDER = 1008;
public const INFRASTRUCTURE_FAILED_TO_INSTALL_PRESTASHOP_ACCOUNTS = 1009;
public const INFRASTRUCTURE_FAILED_TO_INSTALL_PRESTASHOP_EVENT_BUS = 1010;

public const FAILED_TO_FIND_CUSTOMER_ADDRESS = 2001;

Expand Down
Loading
Loading