From 3460059b0f96167b3c69a0e45fb3c619b8e9eb93 Mon Sep 17 00:00:00 2001 From: Robin Wieschendorf Date: Mon, 25 Dec 2023 09:16:52 +0100 Subject: [PATCH 01/10] wip: some new button tests --- src/Templates/ModuleInfo.tmpl.php | 56 +---------- src/Templates/ModuleInfoButtons.tmpl.php | 116 +++++++++++++++++++++++ src/Templates/Styles/button.css | 6 +- 3 files changed, 122 insertions(+), 56 deletions(-) create mode 100644 src/Templates/ModuleInfoButtons.tmpl.php diff --git a/src/Templates/ModuleInfo.tmpl.php b/src/Templates/ModuleInfo.tmpl.php index 2eea5f9c..1ea60390 100644 --- a/src/Templates/ModuleInfo.tmpl.php +++ b/src/Templates/ModuleInfo.tmpl.php @@ -91,61 +91,7 @@
-
- isUpdatable() && !$moduleView->isRepairable()) { ?> - Update installieren - - - isRepairable()) { ?> - - - - Änderungen verwerfen - - - Änderungen übernehmen (Link-Mode) - - - - - - - - Änderungen verwerfen inkl. Templates - - - Änderungen übernehmen inkl. Templates (Link-Mode) - - - - - isCompatibleLoadableAndInstallable()) { ?> - Download & Install - - isIncompatibleLoadebale()) { ?> - Download (inkompatible Version) - - isUninstallable() && !$moduleView->isRepairable()) { ?> - Deinstallieren - - isCompatibleInstallable()) { ?> - Installieren - - isIncompatibleInstallable()) { ?> - Installieren (inkompatible Version) - - hasInstalledVersion()) { ?> - Zur installierten Version - - - isRemote() && $moduleView->isLoaded() && !$moduleView->isInstalled()) { ?> - Modul löschen - -
+
diff --git a/src/Templates/ModuleInfoButtons.tmpl.php b/src/Templates/ModuleInfoButtons.tmpl.php new file mode 100644 index 00000000..eb630313 --- /dev/null +++ b/src/Templates/ModuleInfoButtons.tmpl.php @@ -0,0 +1,116 @@ + + + +
+ +
+ + + +
+ + + +
+ + + +
+ +
+ + + +
+ + + + isUpdatable() && !$moduleView->isRepairable()) { ?> + Update installieren + + + isRepairable()) { ?> + + + + + Änderungen verwerfen + + + Änderungen übernehmen (Link-Mode) + + + + + + + + Änderungen verwerfen inkl. Templates + + + Änderungen übernehmen inkl. Templates (Link-Mode) + + + + + isCompatibleLoadableAndInstallable()) { ?> + Download & Install + + isIncompatibleLoadebale()) { ?> + Download (inkompatible Version) + + isUninstallable() && !$moduleView->isRepairable()) { ?> + Deinstallieren + + isCompatibleInstallable()) { ?> + Installieren + + isIncompatibleInstallable()) { ?> + Installieren (inkompatible Version) + + hasInstalledVersion()) { ?> + Zur installierten Version + + + isRemote() && $moduleView->isLoaded() && !$moduleView->isInstalled()) { ?> + Modul löschen + +
\ No newline at end of file diff --git a/src/Templates/Styles/button.css b/src/Templates/Styles/button.css index 1291c49b..355d1c25 100644 --- a/src/Templates/Styles/button.css +++ b/src/Templates/Styles/button.css @@ -1,6 +1,10 @@ +.btn { + padding: 10px; +} + .button { display: inline-block; - margin: 0px 10px 0px 10px; + margin: 0px 0px 0px 10px; padding: 10px; text-align: center; text-decoration: none; From c5190b24bc3b3d107b0f802d6bfe8524dd3660d1 Mon Sep 17 00:00:00 2001 From: Robin Wieschendorf Date: Mon, 25 Dec 2023 22:08:37 +0100 Subject: [PATCH 02/10] docs: improve docblock infos --- src/Classes/ModuleManager/ModuleInstaller.php | 10 ---------- src/Classes/ModuleManager/ModuleManager.php | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/Classes/ModuleManager/ModuleInstaller.php b/src/Classes/ModuleManager/ModuleInstaller.php index 62973313..84dc83b8 100644 --- a/src/Classes/ModuleManager/ModuleInstaller.php +++ b/src/Classes/ModuleManager/ModuleInstaller.php @@ -195,11 +195,6 @@ public function install(Module $module, bool $force = false): void * Set to true to skip the dependency check (default is false). * @param bool $force * Set to true to force the installation even if the module is already installed (default is false). - * - * @throws RuntimeException - * If the module is already installed (and 'force' is false) or if no valid combination of versions for the - * module's dependencies can be found (and 'skipDependencyCheck' is false), a RuntimeException is thrown with - * detailed error messages. Any other errors during the installation process are also reported via exceptions. */ public function installWithoutDependencies( Module $module, @@ -235,11 +230,6 @@ public function installWithoutDependencies( * * @param Module $module The module to be updated. * @param bool $force Set to true to force the update even if the module is not installed (default is false). - * - * @throws RuntimeException - * If the module is not installed (and 'force' is false) or if no valid combination of versions for the - * module's dependencies can be found, a RuntimeException is thrown with detailed error messages. Any other - * errors during the update process are also reported via exceptions. */ public function update(Module $installedModule, Module $newModule, bool $force = false): void { diff --git a/src/Classes/ModuleManager/ModuleManager.php b/src/Classes/ModuleManager/ModuleManager.php index f6557ced..6b9f6a9d 100644 --- a/src/Classes/ModuleManager/ModuleManager.php +++ b/src/Classes/ModuleManager/ModuleManager.php @@ -322,7 +322,7 @@ public function installWithoutDependencies( } /** - * Aktuallisiert das Modul auf die neuste Version. Dabei werden keine Abhänggigkeiten + * Aktuallisiert das Modul auf die neuste mögliche Version. Dabei werden keine Abhänggigkeiten * aktualisiert. Kommen durch das Update jedoch neue Abhängigkeiten hinzu, werden diese installt. Können nicht alle * Abhängigkeiten erfüllt werten, wird nicht aktualisiert und eine Exception geworfen. */ From ff68f6613b05e1626de2fcc074fd82e4c45af46e Mon Sep 17 00:00:00 2001 From: Robin Wieschendorf Date: Mon, 25 Dec 2023 22:10:28 +0100 Subject: [PATCH 03/10] feat: add method updateWithoutDependencies to ModuleManager --- src/Classes/ModuleManager/ModuleInstaller.php | 4 +- src/Classes/ModuleManager/ModuleManager.php | 103 +++++++++++++++--- 2 files changed, 90 insertions(+), 17 deletions(-) diff --git a/src/Classes/ModuleManager/ModuleInstaller.php b/src/Classes/ModuleManager/ModuleInstaller.php index 84dc83b8..51635291 100644 --- a/src/Classes/ModuleManager/ModuleInstaller.php +++ b/src/Classes/ModuleManager/ModuleInstaller.php @@ -270,9 +270,9 @@ public function update(Module $installedModule, Module $newModule, bool $force = } /** - * //TODO: Nicht zur Neusten sondern zu höchst möglichsten Version aktualisieren. + * */ - public function updateWithoutMissingDependencies( + public function updateWithoutDependencies( Module $instaledModule, Module $newModule, bool $skipDependencyCheck = false, diff --git a/src/Classes/ModuleManager/ModuleManager.php b/src/Classes/ModuleManager/ModuleManager.php index 6b9f6a9d..6e083401 100644 --- a/src/Classes/ModuleManager/ModuleManager.php +++ b/src/Classes/ModuleManager/ModuleManager.php @@ -409,23 +409,96 @@ public function update(string $archiveName): ModuleManagerResult } /** - * Aktualiseirt NUR das Modul auf die neuste Version. Es werden keine fehlenden Abhänggigkeiten + * Aktualiseirt NUR das Modul auf die neuste möglche Version. Es werden keine fehlenden Abhänggigkeiten * installiert. Es werden keine Abhänggigkeiten aktualisiert. Können nicht alle Abhängigkeiten erfüllt werten, - * wird nicht aktualisiert und eine Exception geworfen. + * wird nicht aktualisiert, es sei denn, der Abhängigkeits-Check wird mit $skipDependencyCheck deaktiviert. */ - // public function updateWithoutMissingDependencies(string $archvieName, bool $skipDependencyCheck = false): Module - // { - // $loadedNewModul = $this->moduleInstaller->updateWithoutMissingDependencies( - // $module, - // $skipDependencyCheck, - // false - // ); - - // $autoloadFileCreator = new AutoloadFileCreator(); - // $autoloadFileCreator->createAutoloadFile(); - - // return $loadedNewModul; - // } + public function updateWithoutDependencies( + string $archiveName, + bool $skipDependencyCheck = false + ): ModuleManagerResult { + $moduleLoader = LocalModuleLoader::createFromConfig(); + $module = $moduleLoader->loadInstalledVersionByArchiveName($archiveName); + + if (!$module) { + return $this->error( + ModuleManagerMessage::create(ModuleManagerMessage::UPDATE_ERROR_MODULE_NOT_FOUND) + ->setArchiveName($archiveName) + ); + } + + if (!$module->isInstalled()) { + return $this->error( + ModuleManagerMessage::create(ModuleManagerMessage::UPDATE_ERROR_MODULE_NOT_INSTALLED) + ->setModule($module) + ); + } + + if ($module->isChanged()) { + return $this->error( + ModuleManagerMessage::create(ModuleManagerMessage::UPDATE_ERROR_MODULE_IS_CHANGED) + ->setModule($module) + ); + } + + if ($skipDependencyCheck === false) { + $systemSet = $this->systemSetFactory->getSystemSet(); + $versionConstraint = '>' . $module->getVersion(); + $combinationSatisfyerResult = $this->dependencyBuilder->satisfies($archiveName, $versionConstraint, $systemSet); + if ( + $combinationSatisfyerResult->result === CombinationSatisfyerResult::RESULT_COMBINATION_NOT_FOUND + || !$combinationSatisfyerResult->foundCombination + ) { + return $this->error( + ModuleManagerMessage::create(ModuleManagerMessage::UPDATE_ERROR_MODULE_MISSING_REQUIREMENTS) + ->setArchiveName($archiveName) + ->setVersionConstraint($versionConstraint) + ->setCombinationSatisfyerResult($combinationSatisfyerResult) + ); + } + $version = $combinationSatisfyerResult->foundCombination->getVersion($archiveName); + $newModule = $this->moduleLoader->loadByArchiveNameAndVersion($archiveName, $version); + } else { + $newModule = $this->moduleLoader->loadLatestVersionByArchiveName($archiveName); + } + + if (!$newModule) { + return $this->error( + ModuleManagerMessage::create(ModuleManagerMessage::UPDATE_ERROR_MODULE_NOT_FOUND) + ->setArchiveName($archiveName) + ->setVersion($version) + ); + } + + if (!$newModule->isLoaded()) { + $this->info( + ModuleManagerMessage::create(ModuleManagerMessage::UDPATE_INFO_PULL_MODULE_START) + ->setModule($newModule) + ); + $newModule = $this->moduleInstaller->pull($newModule); + } + + $this->info( + ModuleManagerMessage::create(ModuleManagerMessage::UPDATE_INFO_START) + ->setModule($module) + ); + $this->moduleInstaller->updateWithoutDependencies($module, $newModule, true, true); + + $this->info( + ModuleManagerMessage::create(ModuleManagerMessage::UPDATE_INFO_TO) + ->setModule($newModule) + ); + + $this->info( + ModuleManagerMessage::create(ModuleManagerMessage::UPDATE_INFO_UPDATE_AUTOLOAD_START) + ); + + $autoloadFileCreator = new AutoloadFileCreator(); + $autoloadFileCreator->createAutoloadFile(); + + return ModuleManagerResult::success() + ->setModule($newModule); + } /** * Entfernt alle Änderungen die an den Modul-Dateien im Shop gemacht wurden. Änderungen an Template Dateien werden From d27839450710508a8e1f85f475aa7d1f71eb040b Mon Sep 17 00:00:00 2001 From: Robin Wieschendorf Date: Mon, 25 Dec 2023 22:11:27 +0100 Subject: [PATCH 04/10] feat: add and use force option for update and uninstall in IndexController --- src/Classes/Controllers/IndexController.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Classes/Controllers/IndexController.php b/src/Classes/Controllers/IndexController.php index 04093371..29164009 100644 --- a/src/Classes/Controllers/IndexController.php +++ b/src/Classes/Controllers/IndexController.php @@ -451,8 +451,14 @@ public function invokeUpdate() $queryParams = $this->serverRequest->getQueryParams(); $archiveName = $queryParams['archiveName'] ?? ''; $version = $queryParams['version'] ?? ''; + $force = $queryParams['force'] ?? ''; + $force = $force === 'true' ? true : false; - $moduleManagerResult = $this->moduleManager->update($archiveName); + if ($force === false) { + $moduleManagerResult = $this->moduleManager->update($archiveName, $version); + } else { + $moduleManagerResult = $this->moduleManager->updateWithoutDependencies($archiveName, true); + } if ($moduleManagerResult->getType() === ModuleManagerResult::TYPE_ERROR) { Notification::pushFlashMessage([ @@ -517,8 +523,10 @@ public function invokeUninstall() $queryParams = $this->serverRequest->getQueryParams(); $archiveName = $queryParams['archiveName'] ?? ''; $version = $queryParams['version'] ?? ''; + $force = $queryParams['force'] ?? ''; + $force = $force === 'true' ? true : false; - $moduleManagerResult = $this->moduleManager->uninstall($archiveName); + $moduleManagerResult = $this->moduleManager->uninstall($archiveName, $force); if ($moduleManagerResult->getType() === ModuleManagerResult::TYPE_ERROR) { Notification::pushFlashMessage([ From ae144032c451db0e98d13fe917429d2d64130265 Mon Sep 17 00:00:00 2001 From: Robin Wieschendorf Date: Mon, 25 Dec 2023 22:12:11 +0100 Subject: [PATCH 05/10] feat: add getForceUpdateUrl() and getForceUninstallUrl() in ModuleViewModel --- src/Classes/ViewModels/ModuleViewModel.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Classes/ViewModels/ModuleViewModel.php b/src/Classes/ViewModels/ModuleViewModel.php index 6762e508..90ea2f43 100644 --- a/src/Classes/ViewModels/ModuleViewModel.php +++ b/src/Classes/ViewModels/ModuleViewModel.php @@ -33,6 +33,11 @@ public function getUpdateUrl(string $ref = ''): string return $this->getUrl('update', $ref); } + public function getForceUpdateUrl(string $ref = ''): string + { + return $this->getUrl('update', $ref, null, ['force' => 'true']); + } + public function getInstallUrl(string $ref = ''): string { return $this->getUrl('install', $ref); @@ -63,6 +68,11 @@ public function getUninstallUrl(string $ref = ''): string return $this->getUrl('uninstall', $ref); } + public function getForceUninstallUrl(string $ref = ''): string + { + return $this->getUrl('uninstall', $ref, null, ['force' => 'true']); + } + public function getModuleInfoUrl(string $ref = ''): string { return $this->getUrl('moduleInfo', $ref); From 5c07743cf6bb27781a22155ce85cc895987c8412 Mon Sep 17 00:00:00 2001 From: Robin Wieschendorf Date: Mon, 25 Dec 2023 22:12:56 +0100 Subject: [PATCH 06/10] fix: can not update loaded modules --- src/Classes/ModuleStatus.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Classes/ModuleStatus.php b/src/Classes/ModuleStatus.php index 02ac83c3..7fb8b23c 100644 --- a/src/Classes/ModuleStatus.php +++ b/src/Classes/ModuleStatus.php @@ -128,11 +128,15 @@ public static function isUpdatable(Module $module): bool $installedVersion = $module->getInstalledVersion(); $newestVersion = $module->getNewestVersion(); + if ($installedVersion->getVersion() === 'auto') { + return false; + } + if (!$installedVersion) { return false; } - if (!$newestVersion->isLoadable()) { + if (!$newestVersion->isLoadable() && !$newestVersion->isLoaded()) { return false; } From 1d141c56fc1c6555779a3dc8ae9b66697a303ec5 Mon Sep 17 00:00:00 2001 From: Robin Wieschendorf Date: Mon, 25 Dec 2023 22:13:33 +0100 Subject: [PATCH 07/10] feat: add new class ButtonViewModel --- src/Classes/ViewModels/ButtonViewModel.php | 172 +++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 src/Classes/ViewModels/ButtonViewModel.php diff --git a/src/Classes/ViewModels/ButtonViewModel.php b/src/Classes/ViewModels/ButtonViewModel.php new file mode 100644 index 00000000..28919f09 --- /dev/null +++ b/src/Classes/ViewModels/ButtonViewModel.php @@ -0,0 +1,172 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace RobinTheHood\ModifiedModuleLoaderClient\ViewModels; + +class ButtonViewModel +{ + public const DEFAULT = 'default'; + public const PRIMARY = 'primary'; + public const SUCCESS = 'success'; + public const WARNING = 'warning'; + public const DANGER = 'danger'; + + /** + * @var array $actions + */ + private $actions = []; + + /** @var string */ + private $class = self::DEFAULT; + + public function __construct(string $class) + { + $this->class = $class; + } + + public static function create(string $class): ButtonViewModel + { + $button = new ButtonViewModel($class); + return $button; + } + + public function addAction(string $title, string $url): ButtonViewModel + { + $this->actions[] = [ + 'title' => $title, + 'url' => $url, + 'message' => '' + ]; + return $this; + } + + public function addConfirmAction(string $title, string $url, string $message): ButtonViewModel + { + $this->actions[] = [ + 'title' => $title, + 'url' => $url, + 'message' => $message + ]; + return $this; + } + + public function render(): string + { + if (empty($this->actions)) { + return ''; + } + + $class = $this->mapClassToCss($this->class); + + $title = $this->actions[0]['title'] ?? ''; + $url = $this->actions[0]['url'] ?? ''; + $message = $this->actions[0]['message'] ?? ''; + + $js = $message ? $this->renderConfirmJs($message) : ''; + + if (count($this->actions) > 1) { + $htmlActions = $this->renderActions($this->actions); + + $html = sprintf( + '
+ + + +
', + htmlspecialchars($class), + htmlspecialchars($url), + $js, + htmlspecialchars($title), + htmlspecialchars($class), + $htmlActions + ); + } else { + $html = sprintf( + '%s', + htmlspecialchars($class), + htmlspecialchars($url), + $js, + htmlspecialchars($title) + ); + } + + return $html; + } + + + public function __toString() + { + return $this->render(); + } + + private function mapClassToCss(string $class): string + { + $classMapping = [ + self::DEFAULT => 'btn-outline-default', + self::PRIMARY => 'btn-outline-primary', + self::SUCCESS => 'btn-outline-success', + self::WARNING => 'btn-outline-warning', + self::DANGER => 'btn-outline-danger', + ]; + + return $classMapping[$class] ?? 'btn-outline-default'; + } + + private function renderActions(): string + { + $html = ''; + foreach ($this->actions as $action) { + if ($action['message']) { + $html .= $this->renderAConfirmTag( + $action['title'], + $action['url'], + $action['message'], + 'dropdown-item' + ); + } else { + $html .= $this->renderATag($action['title'], $action['url'], 'dropdown-item'); + } + } + return $html; + } + + private function renderATag(string $title, string $url, string $class = ''): string + { + return sprintf( + '%s', + htmlspecialchars($class), + htmlspecialchars($url), + htmlspecialchars($title) + ); + } + + private function renderAConfirmTag(string $title, string $url, string $message, string $class = ''): string + { + $js = $this->renderConfirmJs($message); + return sprintf( + '%s', + htmlspecialchars($class), + htmlspecialchars($url), + $js, + htmlspecialchars($title, ENT_QUOTES, 'UTF-8') + ); + } + + private function renderConfirmJs(string $message): string + { + return sprintf('onclick="return confirm(\'%s\');"', htmlspecialchars($message, ENT_QUOTES, 'UTF-8')); + } +} From 22369368f83cad0d8b601115de168ca4421cc280 Mon Sep 17 00:00:00 2001 From: Robin Wieschendorf Date: Mon, 25 Dec 2023 22:14:06 +0100 Subject: [PATCH 08/10] feat: use new class ButtonViewModel --- src/Templates/ModuleInfoButtons.tmpl.php | 195 +++++++++++------------ src/Templates/Styles/button.css | 4 + 2 files changed, 96 insertions(+), 103 deletions(-) diff --git a/src/Templates/ModuleInfoButtons.tmpl.php b/src/Templates/ModuleInfoButtons.tmpl.php index eb630313..9a5895b5 100644 --- a/src/Templates/ModuleInfoButtons.tmpl.php +++ b/src/Templates/ModuleInfoButtons.tmpl.php @@ -7,110 +7,99 @@ defined('LOADED_FROM_INDEX') && LOADED_FROM_INDEX ?? die('Access denied.'); use RobinTheHood\ModifiedModuleLoaderClient\Config; +use RobinTheHood\ModifiedModuleLoaderClient\ViewModels\ModuleViewModel; +use RobinTheHood\ModifiedModuleLoaderClient\ViewModels\ButtonViewModel as Button; + +/** @var ModuleViewModel $moduleView */ + +$buttonInfo = Button::create(Button::PRIMARY) + ->addAction('Zur installierten Version', $moduleView->getInstalledUrl('moduleInfo')); + +$buttonPullAndInstall = Button::create(Button::PRIMARY) + ->addAction('Download & Installieren', $moduleView->getLoadAndInstallUrl('moduleInfo')) + ->addAction('Download', $moduleView->getLoadModuleUrl('moduleInfo')); + +$buttonPull = Button::create(Button::PRIMARY) + ->addAction('Download', $moduleView->getLoadModuleUrl('moduleInfo')); + +$buttonInstall = Button::create(Button::SUCCESS) + ->addAction('Installieren', $moduleView->getInstallUrl('moduleInfo')) + //->addAction('Installieren ohne Abhängigkeiten', '#') + ->addAction('Installieren ohne Abhängigkeiten erzwingen', $moduleView->getForceInstallUrl('moduleInfo')); + +$buttonUpdate = Button::create(Button::SUCCESS) + ->addAction('Update installieren', $moduleView->getUpdateUrl('moduleInfo')) + ->addAction('Update installieren ohne Abhängigkeiten erzwingen', $moduleView->getForceUpdateUrl('moduleInfo')); + +$buttonDiscard = Button::create(Button::DANGER) + ->addConfirmAction( + 'Änderungen verwerfen', + $moduleView->getRevertChangesUrl('moduleInfo'), + 'Möchtest du deine Änderungen wirklich rückgängig machen?' + ) + ->addConfirmAction( + 'Änderungen inkl. Templates verwerfen', + $moduleView->getRevertChangesWithTemplateUrl('moduleInfo'), + 'Möchtest du deine Änderungen wirklich rückgängig machen?' + ); + +$buttonDiscardLink = Button::create(Button::WARNING) + ->addAction( + 'Änderungen übernehmen', + $moduleView->getRevertChangesUrl('moduleInfo') + ) + ->addAction( + 'Änderungen inkl. Templates übernehmen', + $moduleView->getRevertChangesWithTemplateUrl('moduleInfo') + ); + +$buttonUninstall = Button::create(Button::DANGER) + ->addAction('Deinstallieren', $moduleView->getUninstallUrl('moduleInfo')) + ->addAction('Deinstallieren erzwingen', $moduleView->getForceUninstallUrl('moduleInfo')); + +$buttonDelete = Button::create(Button::DANGER) + ->addConfirmAction('Löschen', $moduleView->getUnloadModuleUrl('moduleInfo'), 'Möchtest du das Modul wirklich löschen?'); + +$jsGoToFilesTab = " + +"; ?> -
- -
- - - -
- - - -
- - - -
- -
- - - -
- - - - isUpdatable() && !$moduleView->isRepairable()) { ?> - Update installieren - - - isRepairable()) { ?> - - - - - Änderungen verwerfen - - - Änderungen übernehmen (Link-Mode) - - - - - - - - Änderungen verwerfen inkl. Templates - - - Änderungen übernehmen inkl. Templates (Link-Mode) - - - - - isCompatibleLoadableAndInstallable()) { ?> - Download & Install - - isIncompatibleLoadebale()) { ?> - Download (inkompatible Version) - - isUninstallable() && !$moduleView->isRepairable()) { ?> - Deinstallieren - - isCompatibleInstallable()) { ?> - Installieren - - isIncompatibleInstallable()) { ?> - Installieren (inkompatible Version) - - hasInstalledVersion()) { ?> - Zur installierten Version - - - isRemote() && $moduleView->isLoaded() && !$moduleView->isInstalled()) { ?> - Modul löschen - + isUpdatable() && !$moduleView->isRepairable()) { + echo $buttonUpdate; + } elseif ($moduleView->hasInstalledVersion()) { + echo $buttonInfo; + } + + if ($moduleView->isRepairable()) { + if (Config::getInstallMode() != 'link') { + echo $buttonDiscard; + } else { + echo $buttonDiscardLink; + echo $jsGoToFilesTab; + } + } + + if ($moduleView->isCompatibleLoadableAndInstallable()) { + echo $buttonPullAndInstall; + } elseif ($moduleView->isIncompatibleLoadebale()) { + echo $buttonPull; + } elseif ($moduleView->isUninstallable() && !$moduleView->isRepairable()) { + echo $buttonUninstall; + } elseif ($moduleView->isCompatibleInstallable()) { + echo $buttonInstall; + } elseif ($moduleView->isIncompatibleInstallable()) { + echo $buttonInstall; + } + + if (!$moduleView->isRemote() && $moduleView->isLoaded() && !$moduleView->isInstalled()) { + echo $buttonDelete; + } + ?>
\ No newline at end of file diff --git a/src/Templates/Styles/button.css b/src/Templates/Styles/button.css index 355d1c25..79e82908 100644 --- a/src/Templates/Styles/button.css +++ b/src/Templates/Styles/button.css @@ -2,6 +2,10 @@ padding: 10px; } +.moduleinfo-buttons > .btn, .moduleinfo-buttons > .btn-group { + margin-right: 10px; +} + .button { display: inline-block; margin: 0px 0px 0px 10px; From 63f7f6faaab55ef0220b61e63424249f138e4c6f Mon Sep 17 00:00:00 2001 From: Robin Wieschendorf Date: Mon, 25 Dec 2023 22:44:04 +0100 Subject: [PATCH 09/10] fix: possible errors that psalm spotted --- src/Classes/Controllers/IndexController.php | 2 +- src/Classes/ModuleManager/ModuleManager.php | 1 + src/Classes/ModuleStatus.php | 4 ++-- src/Classes/ViewModels/ButtonViewModel.php | 15 +++++++++------ 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/Classes/Controllers/IndexController.php b/src/Classes/Controllers/IndexController.php index 29164009..01fff0af 100644 --- a/src/Classes/Controllers/IndexController.php +++ b/src/Classes/Controllers/IndexController.php @@ -455,7 +455,7 @@ public function invokeUpdate() $force = $force === 'true' ? true : false; if ($force === false) { - $moduleManagerResult = $this->moduleManager->update($archiveName, $version); + $moduleManagerResult = $this->moduleManager->update($archiveName); } else { $moduleManagerResult = $this->moduleManager->updateWithoutDependencies($archiveName, true); } diff --git a/src/Classes/ModuleManager/ModuleManager.php b/src/Classes/ModuleManager/ModuleManager.php index 6e083401..44a24f0b 100644 --- a/src/Classes/ModuleManager/ModuleManager.php +++ b/src/Classes/ModuleManager/ModuleManager.php @@ -460,6 +460,7 @@ public function updateWithoutDependencies( $newModule = $this->moduleLoader->loadByArchiveNameAndVersion($archiveName, $version); } else { $newModule = $this->moduleLoader->loadLatestVersionByArchiveName($archiveName); + $version = ''; } if (!$newModule) { diff --git a/src/Classes/ModuleStatus.php b/src/Classes/ModuleStatus.php index 7fb8b23c..f421514c 100644 --- a/src/Classes/ModuleStatus.php +++ b/src/Classes/ModuleStatus.php @@ -128,11 +128,11 @@ public static function isUpdatable(Module $module): bool $installedVersion = $module->getInstalledVersion(); $newestVersion = $module->getNewestVersion(); - if ($installedVersion->getVersion() === 'auto') { + if (!$installedVersion) { return false; } - if (!$installedVersion) { + if ($installedVersion->getVersion() === 'auto') { return false; } diff --git a/src/Classes/ViewModels/ButtonViewModel.php b/src/Classes/ViewModels/ButtonViewModel.php index 28919f09..065b462f 100644 --- a/src/Classes/ViewModels/ButtonViewModel.php +++ b/src/Classes/ViewModels/ButtonViewModel.php @@ -125,15 +125,18 @@ private function mapClassToCss(string $class): string return $classMapping[$class] ?? 'btn-outline-default'; } - private function renderActions(): string + /** + * @param array $actions + */ + private function renderActions(array $actions): string { $html = ''; - foreach ($this->actions as $action) { - if ($action['message']) { + foreach ($actions as $action) { + if ($action['message'] ?? '') { $html .= $this->renderAConfirmTag( - $action['title'], - $action['url'], - $action['message'], + $action['title'] ?? '', + $action['url'] ?? '', + $action['message'] ?? '', 'dropdown-item' ); } else { From 95b3ebf4c929b50649117e0f10d40394ba2e3d1d Mon Sep 17 00:00:00 2001 From: Robin Wieschendorf Date: Tue, 26 Dec 2023 00:46:40 +0100 Subject: [PATCH 10/10] chore: arrange the dropdown on the left below the button. --- src/Classes/ViewModels/ButtonViewModel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Classes/ViewModels/ButtonViewModel.php b/src/Classes/ViewModels/ButtonViewModel.php index 065b462f..cd44e3b4 100644 --- a/src/Classes/ViewModels/ButtonViewModel.php +++ b/src/Classes/ViewModels/ButtonViewModel.php @@ -81,7 +81,7 @@ public function render(): string '