Skip to content

Commit

Permalink
✨ Handle the MBO module installation.
Browse files Browse the repository at this point in the history
Set up new context variable to interact with the CDC.
Install or enable the MBO module if needed.
  • Loading branch information
intraordinaire committed Mar 9, 2023
1 parent 120891d commit 8985ca3
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 6 deletions.
110 changes: 104 additions & 6 deletions src/DependencyBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,18 @@

namespace Prestashop\ModuleLibMboInstaller;

use Prestashop\ModuleLibGuzzleAdapter\Interfaces\ClientExceptionInterface;
use Symfony\Component\Routing\Router;

class DependencyBuilder
{
const DEPENDENCY_FILENAME = 'ps_dependencies.json';
const GET_PARAMETER = 'mbo_action_needed';
const INSTALL_ACTION = 'install';
const ENABLE_ACTION = 'enable';
const APP_STATE_LAUNCHABLE = 'launchable';
const APP_STATE_MBO_IN_PROGRESS = 'mbo_in_progress';
const APP_STATE_AUTOSTART = 'autostart';

/**
* @var \ModuleCore
Expand All @@ -29,18 +36,78 @@ public function __construct($module)
$this->buildRouter();
}

/**
* Handle dependencies behavior and return dependencies data array to be given to the CDC
*
* @return array{
* "module_display_name": string,
* "module_name": string,
* "module_version": string,
* "ps_version": string,
* "php_version": string,
* "locale": string,
* "dependencies": array<array{
* "current_version"?: string,
* "installed"?: bool,
* "enabled"?: bool
* }>
* }
*
* @throws \Exception|ClientExceptionInterface
*/
public function handleDependencies()
{
$appState = $this->handleMboInstallation();

return $this->buildDependenciesContext($appState);
}

/**
* Install or enable the MBO depending on the action requested
*
* @return string
*
* @throws \Exception|ClientExceptionInterface
*/
protected function handleMboInstallation()
{
if (!isset($_GET[self::GET_PARAMETER])) {
return self::APP_STATE_LAUNCHABLE;
}

$mboStatus = (new Presenter())->present();
$installer = new Installer(_PS_VERSION_);

if ($mboStatus['isInstalled'] && $mboStatus['isEnabled']) {
return self::APP_STATE_AUTOSTART;
}

if (!$mboStatus['isInstalled']) {
$installer->installModule();
} elseif (!$mboStatus['isEnabled']) {
$installer->enableModule();
}

// Force another refresh of the page to correctly clear the cache and load MBO configurations
header('Refresh:0');
// To avoid wasting time rerendering the entire page, die immediately
return self::APP_STATE_MBO_IN_PROGRESS;
}

/**
* Build the dependencies data array to be given to the CDC
*
* @param string $appState
*
* @return array{
* "module_display_name": string,
* "module_name": string,
* "module_version": string,
* "ps_version": string,
* "php_version": string,
* "locale": string,
* "app_state": string,
* "dependencies": array<array{
* "min_version"?: string,
* "current_version"?: string,
* "installed"?: bool,
* "enabled"?: bool
Expand All @@ -49,14 +116,15 @@ public function __construct($module)
*
* @throws \Exception
*/
public function buildDependencies()
protected function buildDependenciesContext($appState = self::APP_STATE_LAUNCHABLE)
{
$data = [
'module_display_name' => (string) $this->module->displayName,
'module_name' => (string) $this->module->name,
'module_version' => (string) $this->module->version,
'ps_version' => (string) _PS_VERSION_,
'php_version' => (string) PHP_VERSION,
'app_state' => $appState,
'dependencies' => [],
];

Expand Down Expand Up @@ -84,13 +152,23 @@ public function buildDependencies()
}

if (!is_array($dependenciesContent) || empty($dependenciesContent['dependencies']) || !is_array($dependenciesContent['dependencies'])) {
$mboDependencyData = $this->addMboInDependencies();

if ($mboDependencyData) {
$data['dependencies'][Installer::MODULE_NAME] = $mboDependencyData;
}

return $data;
}

foreach ($dependenciesContent['dependencies'] as $dependencyName => $dependencyMinVersion) {
if (!isset($dependenciesContent['dependencies'][Installer::MODULE_NAME])) {
$dependenciesContent['dependencies'][] = Installer::MODULE_NAME;
}

foreach ($dependenciesContent['dependencies'] as $dependencyName) {
$dependencyData = \DbCore::getInstance()->getRow('SELECT `id_module`, `active`, `version` FROM `' . _DB_PREFIX_ . 'module` WHERE `name` = "' . pSQL((string) $dependencyName) . '"');

$data['dependencies'][$dependencyName] = array_merge(['min_version' => (string) $dependencyMinVersion], $this->buildRoutesForModule($dependencyName));
$data['dependencies'][$dependencyName] = $this->buildRoutesForModule($dependencyName);
if (!$dependencyData) {
$data['dependencies'][$dependencyName]['installed'] = false;
continue;
Expand Down Expand Up @@ -137,13 +215,33 @@ protected function buildRouter()

$container = $kernel->getContainer();
if (!$container instanceof \Symfony\Component\DependencyInjection\ContainerInterface) {
throw new \Exception('Unable to retrieve Symfony ContainerInterface.');
throw new \Exception('Unable to retrieve Symfony container.');
}

$router = $container->get('router');
if (!$router instanceof Router) {
throw new \Exception('Unable to retrieve Symfony Router.');
throw new \Exception('Unable to retrieve Symfony router.');
}
$this->router = $router;
}

/**
* @return array<string,bool|string>|null
*/
protected function addMboInDependencies()
{
$mboStatus = (new Presenter())->present();

if ((bool) $mboStatus['isEnabled']) {
return null;
}

$mboRoutes = $this->buildRoutesForModule(Installer::MODULE_NAME);

return array_merge([
'current_version' => (string) $mboStatus['version'],
'installed' => (bool) $mboStatus['isInstalled'],
'enabled' => false,
], $mboRoutes);
}
}
19 changes: 19 additions & 0 deletions src/Installer.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use GuzzleHttp\Psr7\Request;
use Prestashop\ModuleLibGuzzleAdapter\ClientFactory;
use Prestashop\ModuleLibGuzzleAdapter\Interfaces\ClientExceptionInterface;
use Prestashop\ModuleLibGuzzleAdapter\Interfaces\HttpClientInterface;
use PrestaShop\PrestaShop\Core\Addon\Module\ModuleManagerBuilder;

Expand All @@ -30,6 +31,8 @@ class Installer

/**
* @param string $prestashopVersion
*
* @throws \Exception
*/
public function __construct($prestashopVersion)
{
Expand All @@ -47,6 +50,8 @@ public function __construct($prestashopVersion)
* Installs ps_mbo module
*
* @return bool
*
* @throws ClientExceptionInterface
*/
public function installModule()
{
Expand All @@ -59,10 +64,24 @@ public function installModule()
return $this->moduleManagerBuilder->build()->install(self::MODULE_NAME);
}

/**
* Enable ps_mbo module
*
* @return bool
*
* @throws \Exception
*/
public function enableModule()
{
return $this->moduleManagerBuilder->build()->enable(self::MODULE_NAME);
}

/**
* Downloads ps_mbo module source from addons, store it and returns the file name
*
* @return string
*
* @throws \Exception|ClientExceptionInterface
*/
private function downloadModule()
{
Expand Down

0 comments on commit 8985ca3

Please sign in to comment.