diff --git a/Module/InstallerAbstract.php b/Module/InstallerAbstract.php index e3bca4e88..be2adb756 100644 --- a/Module/InstallerAbstract.php +++ b/Module/InstallerAbstract.php @@ -19,11 +19,6 @@ use phpOMS\Config\SettingsInterface; use phpOMS\DataStorage\Database\DatabasePool; use phpOMS\DataStorage\Database\Query\Builder; use phpOMS\DataStorage\Database\Schema\Builder as SchemaBuilder; -use phpOMS\System\File\Local\Directory; -use phpOMS\System\File\Local\File; -use phpOMS\System\File\PathException; -use phpOMS\System\File\PermissionException; -use phpOMS\Utils\Parser\Php\ArrayParser; /** * Installer abstract class. @@ -91,8 +86,6 @@ abstract class InstallerAbstract self::createTables($dbPool, $info); self::registerInDatabase($dbPool, $info); self::installSettings($dbPool, $info, $cfgHandler); - self::initRoutes($info); - self::initHooks($info); self::activate($dbPool, $info); } @@ -178,168 +171,8 @@ abstract class InstallerAbstract */ public static function reInit(ModuleInfo $info, ApplicationInfo $appInfo = null) : void { - self::initRoutes($info, $appInfo); - self::initHooks($info, $appInfo); - } - - /** - * Init routes. - * - * @param ModuleInfo $info Module info - * @param null|ApplicationInfo $appInfo Application info - * - * @return void - * - * @throws PermissionException - * - * @since 1.0.0 - */ - protected static function initRoutes(ModuleInfo $info, ApplicationInfo $appInfo = null) : void - { - $directories = new Directory(\dirname($info->getPath()) . '/Admin/Routes'); - - /** @var Directory|File $child */ - foreach ($directories as $child) { - if ($child instanceof Directory) { - foreach ($child as $file) { - if (!\is_dir(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php')) - || ($appInfo !== null && \basename($file->getName(), '.php') !== $appInfo->getInternalName()) - ) { - continue; - } - - self::installRoutes(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/Routes.php', $file->getPath()); - } - } elseif ($child instanceof File) { - if (!\is_dir(__DIR__ . '/../../' . $child->getName()) - || ($appInfo !== null && \basename($child->getName(), '.php') !== $appInfo->getInternalName()) - ) { - continue; - } - - self::installRoutes(__DIR__ . '/../../' . $child->getName() . '/Routes.php', $child->getPath()); - } - } - } - - /** - * 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, 'getPath()) . '/Admin/Hooks'); - - /** @var Directory|File $child */ - foreach ($directories as $child) { - if ($child instanceof Directory) { - foreach ($child as $file) { - if (!\is_dir(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php')) - || ($appInfo !== null && \basename($file->getName(), '.php') !== $appInfo->getInternalName()) - ) { - continue; - } - - self::installHooks(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/Hooks.php', $file->getPath()); - } - } elseif ($child instanceof File) { - if (!\is_dir(__DIR__ . '/../../' . $child->getName()) - || ($appInfo !== null && \basename($child->getName(), '.php') !== $appInfo->getInternalName()) - ) { - continue; - } - - self::installHooks(__DIR__ . '/../../' . $child->getName() . '/Hooks.php', $child->getPath()); - } - } - } - - /** - * 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, 'getDirectory() . '\Admin\Status'; + $class::activateRoutes($info, $appInfo); + $class::activateHooks($info, $appInfo); } } diff --git a/Module/ModuleManager.php b/Module/ModuleManager.php index fdaebee35..163bb4b72 100644 --- a/Module/ModuleManager.php +++ b/Module/ModuleManager.php @@ -333,7 +333,6 @@ final class ModuleManager private function loadInfo(string $module) : ?ModuleInfo { $path = \realpath($oldPath = $this->modulePath . $module . '/info.json'); - if ($path === false) { return null; } @@ -356,14 +355,12 @@ final class ModuleManager public function deactivate(string $module) : bool { $installed = $this->getInstalledModules(false); - if (!isset($installed[$module])) { return false; } try { $info = $this->loadInfo($module); - if ($info === null) { return false; } @@ -390,7 +387,6 @@ final class ModuleManager private function deactivateModule(ModuleInfo $info) : void { $class = '\\Modules\\' . $info->getDirectory() . '\\Admin\\Status'; - if (!Autoloader::exists($class)) { throw new InvalidModuleException($info->getDirectory()); } @@ -411,14 +407,12 @@ final class ModuleManager public function activate(string $module) : bool { $installed = $this->getInstalledModules(false); - if (!isset($installed[$module])) { return false; } try { $info = $this->loadInfo($module); - if ($info === null) { return false; } @@ -445,7 +439,6 @@ final class ModuleManager private function activateModule(ModuleInfo $info) : void { $class = '\\Modules\\' . $info->getDirectory() . '\\Admin\\Status'; - if (!Autoloader::exists($class)) { throw new InvalidModuleException($info->getDirectory()); } @@ -495,7 +488,6 @@ final class ModuleManager public function install(string $module) : bool { $installed = $this->getInstalledModules(false); - if (isset($installed[$module])) { return false; } @@ -548,7 +540,6 @@ final class ModuleManager public function uninstall(string $module) : bool { $installed = $this->getInstalledModules(false); - if (!isset($installed[$module])) { return false; } @@ -570,7 +561,6 @@ final class ModuleManager // uninstall module $class = '\\Modules\\' . $info->getDirectory() . '\\Admin\\Uninstaller'; - if (!Autoloader::exists($class)) { throw new InvalidModuleException($info->getDirectory()); } @@ -626,7 +616,6 @@ final class ModuleManager private function installModule(ModuleInfo $info) : void { $class = '\\Modules\\' . $info->getDirectory() . '\\Admin\\Installer'; - if (!Autoloader::exists($class)) { throw new InvalidModuleException($info->getDirectory()); } @@ -649,10 +638,12 @@ final class ModuleManager */ public function installProviding(string $from, string $for) : void { - if (\is_file($this->modulePath . $from . '/Admin/Install/' . $for . '.php')) { - $class = '\\Modules\\' . $from . '\\Admin\\Install\\' . $for; - $class::install($this->modulePath, $this->app->dbPool); + if (!\is_file($this->modulePath . $from . '/Admin/Install/' . $for . '.php')) { + return; } + + $class = '\\Modules\\' . $from . '\\Admin\\Install\\' . $for; + $class::install($this->modulePath, $this->app->dbPool); } /** @@ -673,7 +664,6 @@ final class ModuleManager } $dirs = \scandir($this->modulePath . $from . '/Application'); - if ($dirs === false) { return; } diff --git a/Module/StatusAbstract.php b/Module/StatusAbstract.php index 7a9142ebc..e2ee42315 100644 --- a/Module/StatusAbstract.php +++ b/Module/StatusAbstract.php @@ -16,6 +16,13 @@ namespace phpOMS\Module; use phpOMS\DataStorage\Database\DatabasePool; use phpOMS\DataStorage\Database\Query\Builder; +use phpOMS\System\File\Local\Directory; +use phpOMS\System\File\Local\File; +use phpOMS\System\File\PathException; +use phpOMS\System\File\PermissionException; +use phpOMS\Utils\Parser\Php\ArrayParser; +use phpOMS\Application\ApplicationInfo; +use phpOMS\Utils\ArrayUtils; /** * Status abstract class. @@ -41,10 +48,51 @@ abstract class StatusAbstract */ public static function activate(DatabasePool $dbPool, ModuleInfo $info) : void { - self::activateRoutes(__DIR__ . '/../../Web/Routes.php', __DIR__ . '/../../Modules/' . $info->getDirectory() . '/Admin/Routes/'); + self::activateRoutes($info); + self::activateHooks($info); self::activateInDatabase($dbPool, $info); } + /** + * Init routes. + * + * @param ModuleInfo $info Module info + * @param null|ApplicationInfo $appInfo Application info + * + * @return void + * + * @throws PermissionException + * + * @since 1.0.0 + */ + public static function activateRoutes(ModuleInfo $info, ApplicationInfo $appInfo = null) : void + { + $directories = new Directory(\dirname($info->getPath()) . '/Admin/Routes'); + + /** @var Directory|File $child */ + foreach ($directories as $child) { + if ($child instanceof Directory) { + foreach ($child as $file) { + if (!\is_dir(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php')) + || ($appInfo !== null && \basename($file->getName(), '.php') !== $appInfo->getInternalName()) + ) { + continue; + } + + self::installRoutes(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/Routes.php', $file->getPath()); + } + } elseif ($child instanceof File) { + if (!\is_dir(__DIR__ . '/../../' . $child->getName()) + || ($appInfo !== null && \basename($child->getName(), '.php') !== $appInfo->getInternalName()) + ) { + continue; + } + + self::installRoutes(__DIR__ . '/../../' . $child->getName() . '/Routes.php', $child->getPath()); + } + } + } + /** * Install routes. * @@ -53,10 +101,117 @@ abstract class StatusAbstract * * @return void * + * @throws PermissionException + * * @since 1.0.0 */ - private static function activateRoutes(string $destRoutePath, string $srcRoutePath) : void + protected static function installRoutes(string $destRoutePath, string $srcRoutePath) : void { + if (!\is_file($destRoutePath)) { + \file_put_contents($destRoutePath, 'getPath()) . '/Admin/Hooks'); + + /** @var Directory|File $child */ + foreach ($directories as $child) { + if ($child instanceof Directory) { + foreach ($child as $file) { + if (!\is_dir(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php')) + || ($appInfo !== null && \basename($file->getName(), '.php') !== $appInfo->getInternalName()) + ) { + continue; + } + + self::installHooks(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/Hooks.php', $file->getPath()); + } + } elseif ($child instanceof File) { + if (!\is_dir(__DIR__ . '/../../' . $child->getName()) + || ($appInfo !== null && \basename($child->getName(), '.php') !== $appInfo->getInternalName()) + ) { + continue; + } + + self::installHooks(__DIR__ . '/../../' . $child->getName() . '/Hooks.php', $child->getPath()); + } + } + } + + /** + * 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, 'getDirectory() . '/Admin/Routes/'); + self::deactivateRoutes($info); + self::deactivateHooks($info); self::deactivateInDatabase($dbPool, $info); } /** - * Install routes. + * Deactivate routes. + * + * @param ModuleInfo $info Module info + * @param null|ApplicationInfo $appInfo Application info + * + * @return void + * + * @since 1.0.0 + */ + public static function deactivateRoutes(ModuleInfo $info, ApplicationInfo $appInfo = null) : void + { + $directories = new Directory(\dirname($info->getPath()) . '/Admin/Routes'); + + /** @var Directory|File $child */ + foreach ($directories as $child) { + if ($child instanceof Directory) { + foreach ($child as $file) { + if (!\is_dir(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php')) + || ($appInfo !== null && \basename($file->getName(), '.php') !== $appInfo->getInternalName()) + ) { + continue; + } + + self::uninstallRoutes(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/Routes.php', $file->getPath()); + } + } elseif ($child instanceof File) { + if (!\is_dir(__DIR__ . '/../../' . $child->getName()) + || ($appInfo !== null && \basename($child->getName(), '.php') !== $appInfo->getInternalName()) + ) { + continue; + } + + self::uninstallRoutes(__DIR__ . '/../../' . $child->getName() . '/Routes.php', $child->getPath()); + } + } + } + + /** + * Uninstall routes. * * @param string $destRoutePath Destination route path * @param string $srcRoutePath Source route path * * @return void * + * @throws PermissionException + * * @since 1.0.0 */ - private static function deactivateRoutes(string $destRoutePath, string $srcRoutePath) : void + 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, 'getPath()) . '/Admin/Hooks'); + + /** @var Directory|File $child */ + foreach ($directories as $child) { + if ($child instanceof Directory) { + foreach ($child as $file) { + if (!\is_dir(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php')) + || ($appInfo !== null && \basename($file->getName(), '.php') !== $appInfo->getInternalName()) + ) { + continue; + } + + self::uninstallHooks(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/Hooks.php', $file->getPath()); + } + } elseif ($child instanceof File) { + if (!\is_dir(__DIR__ . '/../../' . $child->getName()) + || ($appInfo !== null && \basename($child->getName(), '.php') !== $appInfo->getInternalName()) + ) { + continue; + } + + self::uninstallHooks(__DIR__ . '/../../' . $child->getName() . '/Hooks.php', $child->getPath()); + } + } + } + + /** + * 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, 'getPath()) . '/Admin/Routes'); + + /** @var Directory|File $child */ + foreach ($directories as $child) { + if ($child instanceof Directory) { + foreach ($child as $file) { + if (!\is_dir(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php')) + || ($appInfo !== null && \basename($file->getName(), '.php') !== $appInfo->getInternalName()) + ) { + continue; + } + + self::uninstallRoutes(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/Routes.php', $file->getPath()); + } + } elseif ($child instanceof File) { + if (!\is_dir(__DIR__ . '/../../' . $child->getName()) + || ($appInfo !== null && \basename($child->getName(), '.php') !== $appInfo->getInternalName()) + ) { + continue; + } + + self::uninstallRoutes(__DIR__ . '/../../' . $child->getName() . '/Routes.php', $child->getPath()); + } + } + } + + /** + * Uninstall routes. + * + * @param string $destRoutePath Destination route path + * @param string $srcRoutePath Source route path + * + * @return void + * + * @throws PermissionException + * + * @since 1.0.0 + */ + protected 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, 'getPath()) . '/Admin/Hooks'); + + /** @var Directory|File $child */ + foreach ($directories as $child) { + if ($child instanceof Directory) { + foreach ($child as $file) { + if (!\is_dir(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php')) + || ($appInfo !== null && \basename($file->getName(), '.php') !== $appInfo->getInternalName()) + ) { + continue; + } + + self::uninstallHooks(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/Hooks.php', $file->getPath()); + } + } elseif ($child instanceof File) { + if (!\is_dir(__DIR__ . '/../../' . $child->getName()) + || ($appInfo !== null && \basename($child->getName(), '.php') !== $appInfo->getInternalName()) + ) { + continue; + } + + self::uninstallHooks(__DIR__ . '/../../' . $child->getName() . '/Hooks.php', $child->getPath()); + } + } + } + + /** + * 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, ' $value) { + if (!\is_array($value)) { + if (!array_key_exists($key, $value2) || !\is_array($values2[$key])) { + $diff[$key] = $value; + } else { + $subDiff = self::array_diff_assoc_recursive($value, $values2[$key]); + if (!empty($subDiff)) { + $diff[$key] = $subDiff; + } + } + } elseif ($values[$key] !== $value || !\array_key_exists($key, $values2)) { + $diff[$key] == $value; + } + } + + return $diff; + } }