Files

386 lines
12 KiB
PHP
Raw Permalink Normal View History

<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
declare(strict_types=1);
if (!defined('_PS_VERSION_') || version_compare(_PS_VERSION_, '8.0.2', '<')) {
return;
}
$autoloadPath = __DIR__ . '/vendor/autoload.php';
if (file_exists($autoloadPath)) {
require_once $autoloadPath;
}
use PrestaShop\Module\Mbo\Accounts\Provider\AccountsDataProvider;
use PrestaShop\Module\Mbo\Addons\Subscriber\ModuleManagementEventSubscriber;
use PrestaShop\Module\Mbo\Helpers\Config;
use PrestaShop\Module\Mbo\Helpers\EnvHelper;
use PrestaShop\Module\Mbo\Helpers\ErrorHelper;
use PrestaShop\PrestaShop\Core\Module\ModuleRepository;
use PrestaShopBundle\Event\ModuleManagementEvent;
class ps_mbo extends Module
{
use PrestaShop\Module\Mbo\Traits\HaveTabs;
use PrestaShop\Module\Mbo\Traits\UseHooks;
public const VERSION = '5.2.2';
public array $configurationList = [
'PS_MBO_SHOP_ADMIN_UUID' => '', // 'ADMIN' because there will be only one for all shops in a multishop context
'PS_MBO_LAST_PS_VERSION_API_CONFIG' => '',
];
/**
* @var PrestaShop\Module\Mbo\DependencyInjection\ServiceContainer
*/
private $serviceContainer;
/**
* @var string
*/
public $imgPath;
/**
* @var string
*/
public $moduleCacheDir;
/**
* Constructor.
*/
public function __construct()
{
$this->name = 'ps_mbo';
// This value must be hard-coded to respect Addons rules, so we must make sure that the const value is always synced with this one
$this->version = '5.2.2';
$this->author = 'PrestaShop';
$this->tab = 'administration';
$this->module_key = '6cad5414354fbef755c7df4ef1ab74eb';
$this->need_instance = 0;
$this->ps_versions_compliancy = [
'min' => '9.0.0',
'max' => '9.99.99',
];
parent::__construct();
$this->imgPath = $this->_path . 'views/img/';
$this->moduleCacheDir = sprintf('%s/var/modules/%s/', rtrim(_PS_ROOT_DIR_, '/'), $this->name);
$this->displayName = $this->trans('PrestaShop Marketplace in your Back Office', [], 'Modules.Mbo.Global');
$this->description = $this
->trans('Browse the Addons marketplace directly from your back office to better meet your needs.',
[],
'Modules.Mbo.Global'
);
if (self::checkModuleStatus()) {
$this->bootHooks();
}
$this->loadEnv();
}
/**
* Install Module.
*
* @return bool
*/
public function install(): bool
{
try {
/** @var PrestaShop\PsAccountsInstaller\Installer\Installer|null $installer */
$installer = $this->get(PrestaShop\PsAccountsInstaller\Installer\Installer::class);
if ($installer) {
$installer->install();
}
} catch (Exception $e) {
ErrorHelper::reportError($e);
}
$this->installTables();
if (parent::install() && $this->registerHook($this->getHooksNames())) {
// Do come extra operations on modules' registration like modifying orders
$this->installHooks();
$this->postponeTabsTranslations();
return true;
}
// If installation fails, we remove the tables previously created
$this->uninstallTables();
return false;
}
/**
* @inerhitDoc
*/
public function uninstall()
{
if (!parent::uninstall()) {
return false;
}
foreach (array_keys($this->configurationList) as $name) {
Configuration::deleteByName($name);
}
// This will reset cached configuration values (uuid, mail, ...) to avoid reusing them
Config::resetConfigValues();
$this->uninstallTables();
/** @var Symfony\Component\EventDispatcher\EventDispatcher $eventDispatcher */
$eventDispatcher = $this->get('event_dispatcher');
if (!$eventDispatcher->hasListeners(ModuleManagementEvent::UNINSTALL)) {
return true;
}
// Execute them first
foreach ($eventDispatcher->getListeners(ModuleManagementEvent::UNINSTALL) as $listener) {
if ($listener[0] instanceof ModuleManagementEventSubscriber) {
/** @var ModuleRepository $moduleRepository */
$moduleRepository = $this->get(ModuleRepository::class);
$legacyModule = $moduleRepository->getModule('ps_mbo');
$listener[0]->{(string) $listener[1]}(new ModuleManagementEvent($legacyModule));
}
}
// And then remove them
foreach ($eventDispatcher->getListeners(ModuleManagementEvent::UNINSTALL) as $listener) {
if ($listener[0] instanceof ModuleManagementEventSubscriber) {
$eventDispatcher->removeSubscriber($listener[0]);
break;
}
}
return true;
}
/**
* Enable Module.
*
* @param bool $force_all
*
* @return bool
*/
public function enable($force_all = false): bool
{
if (self::checkModuleStatus()) {
return true;
}
// Store previous context
$previousContextType = Shop::getContext();
$previousContextShopId = Shop::getContextShopID();
$allShops = Shop::getShops(true, null, true);
foreach ($allShops as $shop) {
if (!$this->enableByShop($shop)) {
return false;
}
}
// Restore previous context
Shop::setContext($previousContextType, $previousContextShopId);
// Install tab before registering shop, we need the tab to be active to create the good token
$this->updateTabs();
$this->postponeTabsTranslations();
return true;
}
/**
* Disable Module.
*
* @param bool $force_all
*
* @return bool
*/
public function disable($force_all = false): bool
{
// Store previous context
$previousContextType = Shop::getContext();
$previousContextShopId = Shop::getContextShopID();
$allShops = Shop::getShops(true, null, true);
foreach ($allShops as $shop) {
if (!$this->disableByShop($shop)) {
return false;
}
}
// Restore previous context
Shop::setContext($previousContextType, $previousContextShopId);
return $this->handleTabAction('uninstall');
}
/**
* @param string $serviceName
*
* @return object|null
*/
public function getService($serviceName)
{
if ($this->serviceContainer === null) {
$this->serviceContainer = new PrestaShop\Module\Mbo\DependencyInjection\ServiceContainer(
$this->name . str_replace('.', '', $this->version),
$this->getLocalPath()
);
}
return $this->serviceContainer->getService($serviceName);
}
/**
* @inerhitDoc
*/
public function isUsingNewTranslationSystem(): bool
{
return true;
}
/**
* Used to correctly check if the module is enabled or not whe registering services
*
* @return bool
*/
public static function checkModuleStatus(): bool
{
// First if the module have active=0 in the DB, the module is inactive
$result = Db::getInstance()->getRow('SELECT `active`
FROM `' . _DB_PREFIX_ . 'module`
WHERE `name` = "ps_mbo"');
if ($result && false === (bool) $result['active']) {
return false;
}
// If active = 1
// in the module table, the module must be associated to at least one shop to be considered as active
$result = Db::getInstance()->getRow('SELECT m.`id_module` as `active`, ms.`id_module` as `shop_active`
FROM `' . _DB_PREFIX_ . 'module` m
LEFT JOIN `' . _DB_PREFIX_ . 'module_shop` ms ON m.`id_module` = ms.`id_module`
WHERE `name` = "ps_mbo"');
if ($result) {
return $result['active'] && $result['shop_active'];
} else {
return false;
}
}
public function installTables(string $table = null): bool
{
$sqlQueries = [];
if (null === $table || 'mbo_api_config' === $table) {
$sqlQueries[] = ' CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'mbo_api_config` (
`id_mbo_api_config` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`config_key` varchar(255) NULL,
`config_value` varchar(255) NULL,
`ps_version` varchar(255) NULL,
`mbo_version` varchar(255) NULL,
`applied` TINYINT(1) NOT NULL DEFAULT \'0\',
`date_add` datetime NOT NULL,
PRIMARY KEY (`id_mbo_api_config`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8;';
}
foreach ($sqlQueries as $query) {
if (!Db::getInstance()->execute($query)) {
return false;
}
}
return true;
}
public function getAccountsDataProvider(): ?AccountsDataProvider
{
try {
return $this->get(AccountsDataProvider::class);
} catch (Exception $e) {
ErrorHelper::reportError($e);
return null;
}
}
public function postponeTabsTranslations(): void
{
/**it'
* There is an issue for translating tabs during installation :
* Active modules translations files are loaded during the kernel boot.
* So the installing module translations are not known
* So, we postpone the tabs translations for the first time the module's code is executed.
*/
$lockFile = $this->moduleCacheDir . 'translate_tabs.lock';
if (!file_exists($lockFile)) {
if (!is_dir($this->moduleCacheDir)) {
mkdir($this->moduleCacheDir, 0777, true);
}
$f = fopen($lockFile, 'w+');
fclose($f);
}
}
private function enableByShop(int $shopId)
{
// Force context to all shops
Shop::setContext(Shop::CONTEXT_SHOP, $shopId);
return parent::enable(true);
}
private function disableByShop(int $shopId)
{
// Force context to all shops
Shop::setContext(Shop::CONTEXT_SHOP, $shopId);
return parent::disable(true);
}
private function uninstallTables(): bool
{
$sqlQueries[] = 'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'mbo_api_config`';
foreach ($sqlQueries as $query) {
if (!Db::getInstance()->execute($query)) {
return false;
}
}
return true;
}
/**
* @return void
*/
private function loadEnv(): void
{
EnvHelper::loadEnv(__DIR__ . '/.env');
}
}