mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-02-06 04:28:41 +00:00
finalize app installation draft
This commit is contained in:
parent
ca537eda92
commit
e8cae23ca9
|
|
@ -31,6 +31,14 @@ use phpOMS\System\File\PathException;
|
||||||
*/
|
*/
|
||||||
final class ApplicationManager
|
final class ApplicationManager
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Application instance.
|
||||||
|
*
|
||||||
|
* @var ApplicationAbstract
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
private ApplicationAbstract $app;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applications
|
* Applications
|
||||||
*
|
*
|
||||||
|
|
@ -42,10 +50,13 @@ final class ApplicationManager
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @since. 1.0.0
|
* @param ApplicationAbstract $app Application
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct(ApplicationAbstract $app)
|
||||||
{
|
{
|
||||||
|
$this->app = $app;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -85,31 +96,30 @@ final class ApplicationManager
|
||||||
public function install(string $source, string $destination, string $theme = 'Default') : bool
|
public function install(string $source, string $destination, string $theme = 'Default') : bool
|
||||||
{
|
{
|
||||||
$destination = \rtrim($destination, '\\/');
|
$destination = \rtrim($destination, '\\/');
|
||||||
|
$source = \rtrim($source, '/\\');
|
||||||
|
|
||||||
if (!\is_dir($source) || \is_dir($destination)) {
|
if (!\is_dir($source) || \is_dir($destination)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$app = $this->loadInfo(\rtrim($source, '/\\') . '/info.json');
|
if (!\is_file($source . '/Admin/Installer.php')) {
|
||||||
$this->applications[$app->getInternalName()] = $app;
|
return false;
|
||||||
|
|
||||||
$this->installFiles($source, $destination);
|
|
||||||
$this->installTheme($destination, $theme);
|
|
||||||
|
|
||||||
$files = Directory::list($destination, '*', true);
|
|
||||||
foreach ($files as $file) {
|
|
||||||
if (!\is_file($destination . '/' . $file)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$content = \file_get_contents($destination . '/' . $file);
|
|
||||||
if ($content === false) {
|
|
||||||
continue; // @codeCoverageIgnore
|
|
||||||
}
|
|
||||||
|
|
||||||
\file_put_contents($destination . '/' . $file, \str_replace('{APPNAME}', \basename($destination), $content));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
try {
|
||||||
|
$info = $this->loadInfo($source . '/info.json');
|
||||||
|
$this->applications[$info->getInternalName()] = $info;
|
||||||
|
|
||||||
|
$this->installFiles($source, $destination);
|
||||||
|
$this->replacePlaceholder($destination);
|
||||||
|
|
||||||
|
$class = '\\Web\\' . $info->getInternalName() . '\\Admin\\Installer';
|
||||||
|
$class::install($this->app->dbPool, $info, $this->app->appSettings);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (\Throwable $t) {
|
||||||
|
return false; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -128,36 +138,28 @@ final class ApplicationManager
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Install the theme
|
* Replace placeholder string (application placeholder name)
|
||||||
*
|
*
|
||||||
* @param string $destination Destination of the application
|
* @param string $destination Destination of the application
|
||||||
* @param string $theme Theme name
|
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
private function installTheme(string $destination, string $theme) : void
|
private function replacePlaceholder(string $destination) : void
|
||||||
{
|
{
|
||||||
if (!\is_dir($path = $destination . '/Themes/' . $theme)) {
|
$files = Directory::list($destination, '*', true);
|
||||||
return;
|
foreach ($files as $file) {
|
||||||
}
|
if (!\is_file($destination . '/' . $file)) {
|
||||||
|
|
||||||
$dirs = \scandir($path);
|
|
||||||
foreach ($dirs as $dir) {
|
|
||||||
if (!\is_dir($path. '/' . $dir) || $dir === '.' || $dir === '..') {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (\is_dir($destination . '/' . $dir)) {
|
$content = \file_get_contents($destination . '/' . $file);
|
||||||
Directory::delete($destination . '/' . $dir);
|
if ($content === false) {
|
||||||
|
continue; // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
Directory::copy(
|
\file_put_contents($destination . '/' . $file, \str_replace('{APPNAME}', \basename($destination), $content));
|
||||||
$destination . '/Themes/' . $theme . '/' . $dir,
|
|
||||||
$destination . '/' . $dir,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
34
Application/ApplicationStatus.php
Normal file
34
Application/ApplicationStatus.php
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Orange Management
|
||||||
|
*
|
||||||
|
* PHP Version 8.0
|
||||||
|
*
|
||||||
|
* @package phpOMS\Application
|
||||||
|
* @copyright Dennis Eichhorn
|
||||||
|
* @license OMS License 1.0
|
||||||
|
* @version 1.0.0
|
||||||
|
* @link https://orange-management.org
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace phpOMS\Application;
|
||||||
|
|
||||||
|
use phpOMS\Stdlib\Base\Enum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App status enum.
|
||||||
|
*
|
||||||
|
* @package phpOMS\Application
|
||||||
|
* @license OMS License 1.0
|
||||||
|
* @link https://orange-management.org
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
abstract class ApplicationStatus extends Enum
|
||||||
|
{
|
||||||
|
public const NORMAL = 1;
|
||||||
|
|
||||||
|
public const READ_ONLY = 2;
|
||||||
|
|
||||||
|
public const DISABLED = 3;
|
||||||
|
}
|
||||||
190
Application/InstallerAbstract.php
Normal file
190
Application/InstallerAbstract.php
Normal file
|
|
@ -0,0 +1,190 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Orange Management
|
||||||
|
*
|
||||||
|
* PHP Version 8.0
|
||||||
|
*
|
||||||
|
* @package phpOMS\Application
|
||||||
|
* @copyright Dennis Eichhorn
|
||||||
|
* @license OMS License 1.0
|
||||||
|
* @version 1.0.0
|
||||||
|
* @link https://orange-management.org
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace phpOMS\Application;
|
||||||
|
|
||||||
|
use phpOMS\Application\ApplicationInfo;
|
||||||
|
use phpOMS\Config\SettingsInterface;
|
||||||
|
use phpOMS\DataStorage\Database\DatabasePool;
|
||||||
|
use phpOMS\DataStorage\Database\Query\Builder;
|
||||||
|
use phpOMS\DataStorage\Database\Schema\Builder as SchemaBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Installer abstract class.
|
||||||
|
*
|
||||||
|
* @package phpOMS\Application
|
||||||
|
* @license OMS License 1.0
|
||||||
|
* @link https://orange-management.org
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
abstract class InstallerAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Install app.
|
||||||
|
*
|
||||||
|
* @param DatabasePool $dbPool Database instance
|
||||||
|
* @param ApplicationInfo $info App info
|
||||||
|
* @param SettingsInterface $cfgHandler Settings/Configuration handler
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function install(DatabasePool $dbPool, ApplicationInfo $info, SettingsInterface $cfgHandler) : void
|
||||||
|
{
|
||||||
|
self::createTables($dbPool, $info);
|
||||||
|
self::registerInDatabase($dbPool, $info);
|
||||||
|
self::installSettings($dbPool, $info, $cfgHandler);
|
||||||
|
self::activate($dbPool, $info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register app in database.
|
||||||
|
*
|
||||||
|
* @param DatabasePool $dbPool Database instance
|
||||||
|
* @param ApplicationInfo $info App info
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function registerInDatabase(DatabasePool $dbPool, ApplicationInfo $info) : void
|
||||||
|
{
|
||||||
|
$queryApp = new Builder($dbPool->get('insert'));
|
||||||
|
$queryApp->insert('app_name', 'app_theme', 'app_status')
|
||||||
|
->into('app')
|
||||||
|
->values($info->getInternalName(), 'Default', ApplicationStatus::NORMAL)
|
||||||
|
->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install the theme
|
||||||
|
*
|
||||||
|
* @param string $destination Destination of the application
|
||||||
|
* @param string $theme Theme name
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function installTheme(string $destination, string $theme) : void
|
||||||
|
{
|
||||||
|
if (!\is_dir($path = $destination . '/Themes/' . $theme)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dirs = \scandir($path);
|
||||||
|
foreach ($dirs as $dir) {
|
||||||
|
if (!\is_dir($path. '/' . $dir) || $dir === '.' || $dir === '..') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\is_dir($destination . '/' . $dir)) {
|
||||||
|
Directory::delete($destination . '/' . $dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
Directory::copy(
|
||||||
|
$destination . '/Themes/' . $theme . '/' . $dir,
|
||||||
|
$destination . '/' . $dir,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install app settings.
|
||||||
|
*
|
||||||
|
* @param DatabasePool $dbPool Database instance
|
||||||
|
* @param ApplicationInfo $info App info
|
||||||
|
* @param SettingsInterface $cfgHandler Settings/Configuration handler
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function installSettings(DatabasePool $dbPool, ApplicationInfo $info, SettingsInterface $cfgHandler) : void
|
||||||
|
{
|
||||||
|
$path = __DIR__ . '/../../Web/' . $info->getInternalName() . '/Admin/Install/Settings.install.php';
|
||||||
|
if (!\is_file($path)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$settings = include $path;
|
||||||
|
|
||||||
|
foreach ($settings as $setting) {
|
||||||
|
$cfgHandler->create($setting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create tables for app.
|
||||||
|
*
|
||||||
|
* @param DatabasePool $dbPool Database instance
|
||||||
|
* @param ApplicationInfo $info App info
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
protected static function createTables(DatabasePool $dbPool, ApplicationInfo $info) : void
|
||||||
|
{
|
||||||
|
$path = __DIR__ . '/../../Web/' . $info->getInternalName() . '/Admin/Install/db.json';
|
||||||
|
if (!\is_file($path)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = \file_get_contents($path);
|
||||||
|
if ($content === false) {
|
||||||
|
return; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
$definitions = \json_decode($content, true);
|
||||||
|
foreach ($definitions as $definition) {
|
||||||
|
SchemaBuilder::createFromSchema($definition, $dbPool->get('schema'))->execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activate after install.
|
||||||
|
*
|
||||||
|
* @param DatabasePool $dbPool Database instance
|
||||||
|
* @param ApplicationInfo $info App info
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
protected static function activate(DatabasePool $dbPool, ApplicationInfo $info) : void
|
||||||
|
{
|
||||||
|
/** @var StatusAbstract $class */
|
||||||
|
$class = '\\Web\\' . $info->getInternalName() . '\\Admin\\Status';
|
||||||
|
$class::activate($dbPool, $info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-init app.
|
||||||
|
*
|
||||||
|
* @param ApplicationInfo $info App info
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function reInit(ApplicationInfo $info) : void
|
||||||
|
{
|
||||||
|
$class = '\\Web\\' . $info->getInternalName() . '\\Admin\\Status';
|
||||||
|
$class::activateRoutes($appInfo);
|
||||||
|
$class::activateHooks($appInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -30,21 +30,295 @@ use phpOMS\DataStorage\Database\Query\Builder;
|
||||||
abstract class StatusAbstract
|
abstract class StatusAbstract
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Deactivate module in database.
|
* Deactivate app.
|
||||||
*
|
*
|
||||||
* @param DatabasePool $dbPool Database instance
|
* @param DatabasePool $dbPool Database instance
|
||||||
* @param ModuleInfo $info Module info
|
* @param ApplicationInfo $info Module info
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public static function deactivateInDatabase(DatabasePool $dbPool, ModuleInfo $info) : void
|
public static function activate(DatabasePool $dbPool, ApplicationInfo $info) : void
|
||||||
|
{
|
||||||
|
self::activateRoutes($info);
|
||||||
|
self::activateHooks($info);
|
||||||
|
self::activateInDatabase($dbPool, $info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init routes.
|
||||||
|
*
|
||||||
|
* @param ApplicationInfo $appInfo Application info
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @throws PermissionException
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function activateRoutes(ApplicationInfo $appInfo = null) : void
|
||||||
|
{
|
||||||
|
self::installRoutes(__DIR__ . '/../../Web/' . $appInfo->getInternalName() . '/Routes.php', __DIR__ . '/../../Web/' . $appInfo->getInternalName() . '/Admin/Install/Application/Routes.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init hooks.
|
||||||
|
*
|
||||||
|
* @param ApplicationInfo $appInfo Application info
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @throws PermissionException
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function activateHooks(ApplicationInfo $appInfo = null) : void
|
||||||
|
{
|
||||||
|
self::installRoutes(__DIR__ . '/../../Web/' . $appInfo->getInternalName() . '/Hooks.php', __DIR__ . '/../../Web/' . $appInfo->getInternalName() . '/Admin/Install/Application/Hooks.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install routes.
|
||||||
|
*
|
||||||
|
* @param string $destRoutePath Destination route path
|
||||||
|
* @param string $srcRoutePath Source route path
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @throws PermissionException
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
protected static function installRoutes(string $destRoutePath, string $srcRoutePath) : void
|
||||||
|
{
|
||||||
|
if (!\is_file($destRoutePath)) {
|
||||||
|
\file_put_contents($destRoutePath, '<?php return [];');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!\is_file($srcRoutePath)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!\is_file($destRoutePath)) {
|
||||||
|
throw new PathException($destRoutePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!\is_writable($destRoutePath)) {
|
||||||
|
throw new PermissionException($destRoutePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @noinspection PhpIncludeInspection */
|
||||||
|
$appRoutes = include $destRoutePath;
|
||||||
|
/** @noinspection PhpIncludeInspection */
|
||||||
|
$moduleRoutes = include $srcRoutePath;
|
||||||
|
|
||||||
|
$appRoutes = \array_merge_recursive($appRoutes, $moduleRoutes);
|
||||||
|
|
||||||
|
\file_put_contents($destRoutePath, '<?php return ' . ArrayParser::serializeArray($appRoutes) . ';', \LOCK_EX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install hooks.
|
||||||
|
*
|
||||||
|
* @param string $destHookPath Destination hook path
|
||||||
|
* @param string $srcHookPath Source hook path
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @throws PathException This exception is thrown if the hook file doesn't exist
|
||||||
|
* @throws PermissionException This exception is thrown if the hook file couldn't be updated (no write permission)
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
protected static function installHooks(string $destHookPath, string $srcHookPath) : void
|
||||||
|
{
|
||||||
|
if (!\is_file($destHookPath)) {
|
||||||
|
\file_put_contents($destHookPath, '<?php return [];');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!\is_file($srcHookPath)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!\is_file($destHookPath)) {
|
||||||
|
throw new PathException($destHookPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!\is_writable($destHookPath)) {
|
||||||
|
throw new PermissionException($destHookPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @noinspection PhpIncludeInspection */
|
||||||
|
$appHooks = include $destHookPath;
|
||||||
|
/** @noinspection PhpIncludeInspection */
|
||||||
|
$moduleHooks = include $srcHookPath;
|
||||||
|
|
||||||
|
$appHooks = \array_merge_recursive($appHooks, $moduleHooks);
|
||||||
|
|
||||||
|
\file_put_contents($destHookPath, '<?php return ' . ArrayParser::serializeArray($appHooks) . ';', \LOCK_EX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deactivate routes.
|
||||||
|
*
|
||||||
|
* @param ApplicationInfo $appInfo Application info
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @throws PermissionException
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function deactivateRoutes(ApplicationInfo $appInfo) : void
|
||||||
|
{
|
||||||
|
self::installRoutes(__DIR__ . '/../../Web/' . $appInfo->getInternalName() . '/Routes.php', __DIR__ . '/../../Web/' . $appInfo->getInternalName() . '/Admin/Install/Application/Routes.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deactivate hooks.
|
||||||
|
*
|
||||||
|
* @param ApplicationInfo $appInfo Application info
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @throws PermissionException
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function deactivateHooks(ApplicationInfo $appInfo) : void
|
||||||
|
{
|
||||||
|
self::installRoutes(__DIR__ . '/../../Web/' . $appInfo->getInternalName() . '/Hooks.php', __DIR__ . '/../../Web/' . $appInfo->getInternalName() . '/Admin/Install/Application/Hooks.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uninstall routes.
|
||||||
|
*
|
||||||
|
* @param string $destRoutePath Destination route path
|
||||||
|
* @param string $srcRoutePath Source route path
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @throws PermissionException
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function uninstallRoutes(string $destRoutePath, string $srcRoutePath) : void
|
||||||
|
{
|
||||||
|
if (!\is_file($destRoutePath)
|
||||||
|
|| !\is_file($srcRoutePath)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!\is_file($destRoutePath)) {
|
||||||
|
throw new PathException($destRoutePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!\is_writable($destRoutePath)) {
|
||||||
|
throw new PermissionException($destRoutePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @noinspection PhpIncludeInspection */
|
||||||
|
$appRoutes = include $destRoutePath;
|
||||||
|
/** @noinspection PhpIncludeInspection */
|
||||||
|
$moduleRoutes = include $srcRoutePath;
|
||||||
|
|
||||||
|
$appRoutes = ArrayUtils::array_diff_assoc_recursive($appRoutes, $moduleRoutes);
|
||||||
|
|
||||||
|
\file_put_contents($destRoutePath, '<?php return ' . ArrayParser::serializeArray($appRoutes) . ';', \LOCK_EX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uninstall hooks.
|
||||||
|
*
|
||||||
|
* @param string $destHookPath Destination hook path
|
||||||
|
* @param string $srcHookPath Source hook path
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @throws PermissionException
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
protected static function uninstallHooks(string $destHookPath, string $srcHookPath) : void
|
||||||
|
{
|
||||||
|
if (!\is_file($destHookPath)
|
||||||
|
|| !\is_file($srcHookPath)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!\is_file($destHookPath)) {
|
||||||
|
throw new PathException($destHookPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!\is_writable($destHookPath)) {
|
||||||
|
throw new PermissionException($destHookPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @noinspection PhpIncludeInspection */
|
||||||
|
$appHooks = include $destHookPath;
|
||||||
|
/** @noinspection PhpIncludeInspection */
|
||||||
|
$moduleHooks = include $srcHookPath;
|
||||||
|
|
||||||
|
$appHooks = ArrayUtils::array_diff_assoc_recursive($appHooks, $moduleHooks);
|
||||||
|
|
||||||
|
\file_put_contents($destHookPath, '<?php return ' . ArrayParser::serializeArray($appHooks) . ';', \LOCK_EX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deactivate app in database.
|
||||||
|
*
|
||||||
|
* @param DatabasePool $dbPool Database instance
|
||||||
|
* @param ApplicationInfo $info Module info
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function activateInDatabase(DatabasePool $dbPool, ApplicationInfo $info) : void
|
||||||
{
|
{
|
||||||
$query = new Builder($dbPool->get('update'));
|
$query = new Builder($dbPool->get('update'));
|
||||||
$query->update('app')
|
$query->update('app')
|
||||||
->sets('app.app_active', ModuleStatus::INACTIVE)
|
->sets('app.app_status', ApplicationStatus::NORMAL)
|
||||||
->where('app.app_id', '=', $info->getInternalName())
|
->where('app.app_name', '=', $info->getInternalName())
|
||||||
|
->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deactivate app.
|
||||||
|
*
|
||||||
|
* @param DatabasePool $dbPool Database instance
|
||||||
|
* @param ApplicationInfo $info Module info
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function deactivate(DatabasePool $dbPool, ApplicationInfo $info) : void
|
||||||
|
{
|
||||||
|
self::deactivateRoutes($info);
|
||||||
|
self::deactivateHooks($info);
|
||||||
|
self::deactivateInDatabase($dbPool, $info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deactivate app in database.
|
||||||
|
*
|
||||||
|
* @param DatabasePool $dbPool Database instance
|
||||||
|
* @param ApplicationInfo $info Module info
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function deactivateInDatabase(DatabasePool $dbPool, ApplicationInfo $info) : void
|
||||||
|
{
|
||||||
|
$query = new Builder($dbPool->get('update'));
|
||||||
|
$query->update('app')
|
||||||
|
->sets('app.app_status', ApplicationStatus::DISABLED)
|
||||||
|
->where('app.app_name', '=', $info->getInternalName())
|
||||||
->execute();
|
->execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
116
Application/UninstallerAbstract.php
Normal file
116
Application/UninstallerAbstract.php
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Orange Management
|
||||||
|
*
|
||||||
|
* PHP Version 8.0
|
||||||
|
*
|
||||||
|
* @package phpOMS\Application
|
||||||
|
* @copyright Dennis Eichhorn
|
||||||
|
* @license OMS License 1.0
|
||||||
|
* @version 1.0.0
|
||||||
|
* @link https://orange-management.org
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace phpOMS\Application;
|
||||||
|
|
||||||
|
use phpOMS\DataStorage\Database\DatabasePool;
|
||||||
|
use phpOMS\DataStorage\Database\Query\Builder;
|
||||||
|
use phpOMS\DataStorage\Database\Schema\Builder as SchemaBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uninstaller abstract class.
|
||||||
|
*
|
||||||
|
* @package phpOMS\Application
|
||||||
|
* @license OMS License 1.0
|
||||||
|
* @link https://orange-management.org
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
abstract class UninstallerAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Install module.
|
||||||
|
*
|
||||||
|
* @param DatabasePool $dbPool Database instance
|
||||||
|
* @param ApplicationInfo $info App info
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function uninstall(DatabasePool $dbPool, ApplicationInfo $info) : void
|
||||||
|
{
|
||||||
|
self::deactivate($dbPool, $info);
|
||||||
|
self::dropTables($dbPool, $info);
|
||||||
|
self::unregisterFromDatabase($dbPool, $info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activate after install.
|
||||||
|
*
|
||||||
|
* @param DatabasePool $dbPool Database instance
|
||||||
|
* @param ApplicationInfo $info App info
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
protected static function deactivate(DatabasePool $dbPool, ApplicationInfo $info) : void
|
||||||
|
{
|
||||||
|
/** @var StatusAbstract $class */
|
||||||
|
$class = '\Web\\' . $info->getInternalName() . '\Admin\Status';
|
||||||
|
$class::deactivate($dbPool, $info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop tables of app.
|
||||||
|
*
|
||||||
|
* @param DatabasePool $dbPool Database instance
|
||||||
|
* @param ApplicationInfo $info App info
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function dropTables(DatabasePool $dbPool, ApplicationInfo $info) : void
|
||||||
|
{
|
||||||
|
$path = __DIR__ . '/../../Web/' . $info->getInternalName() . '/Admin/Install/db.json';
|
||||||
|
|
||||||
|
if (!\is_file($path)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = \file_get_contents($path);
|
||||||
|
if ($content === false) {
|
||||||
|
return; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
$definitions = \json_decode($content, true);
|
||||||
|
$builder = new SchemaBuilder($dbPool->get('schema'));
|
||||||
|
|
||||||
|
foreach ($definitions as $definition) {
|
||||||
|
$builder->dropTable($definition['table'] ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
|
$builder->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregister app from database.
|
||||||
|
*
|
||||||
|
* @param DatabasePool $dbPool Database instance
|
||||||
|
* @param ApplicationInfo $info App info
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function unregisterFromDatabase(DatabasePool $dbPool, ApplicationInfo $info) : void
|
||||||
|
{
|
||||||
|
$queryApp = new Builder($dbPool->get('delete'));
|
||||||
|
$queryApp->delete()
|
||||||
|
->from('app')
|
||||||
|
->where('app_name', '=', $info->getInternalName())
|
||||||
|
->execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user