Skip to content
12 changes: 10 additions & 2 deletions src/Classes/Controllers/IndexController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
} else {
$moduleManagerResult = $this->moduleManager->updateWithoutDependencies($archiveName, true);
}

if ($moduleManagerResult->getType() === ModuleManagerResult::TYPE_ERROR) {
Notification::pushFlashMessage([
Expand Down Expand Up @@ -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([
Expand Down
14 changes: 2 additions & 12 deletions src/Classes/ModuleManager/ModuleInstaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -280,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,
Expand Down
106 changes: 90 additions & 16 deletions src/Classes/ModuleManager/ModuleManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -409,23 +409,97 @@ 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);
$version = '';
}

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
Expand Down
6 changes: 5 additions & 1 deletion src/Classes/ModuleStatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,11 @@ public static function isUpdatable(Module $module): bool
return false;
}

if (!$newestVersion->isLoadable()) {
if ($installedVersion->getVersion() === 'auto') {
return false;
}

if (!$newestVersion->isLoadable() && !$newestVersion->isLoaded()) {
return false;
}

Expand Down
175 changes: 175 additions & 0 deletions src/Classes/ViewModels/ButtonViewModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<?php

declare(strict_types=1);

/*
* This file is part of MMLC - ModifiedModuleLoaderClient.
*
* (c) Robin Wieschendorf <mail@robinwieschendorf.de>
*
* 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<int, array{title: string, url: string, message?: string}> $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(
'<div class="btn-group">
<a class="btn %s" href="%s" %s role="button" aria-expanded="false">%s</a>
<button type="button" class="btn %s dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"
aria-expanded="false" data-reference="parent">
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu">%s</div>
</div>',
htmlspecialchars($class),
htmlspecialchars($url),
$js,
htmlspecialchars($title),
htmlspecialchars($class),
$htmlActions
);
} else {
$html = sprintf(
'<a class="btn %s" href="%s" %s role="button">%s</a>',
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';
}

/**
* @param array<int, array{title: string, url: string, message?: string}> $actions
*/
private function renderActions(array $actions): string
{
$html = '';
foreach ($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(
'<a class="%s" href="%s">%s</a>',
htmlspecialchars($class),
htmlspecialchars($url),
htmlspecialchars($title)
);
}

private function renderAConfirmTag(string $title, string $url, string $message, string $class = ''): string
{
$js = $this->renderConfirmJs($message);
return sprintf(
'<a class="%s" href="%s" %s>%s</a>',
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'));
}
}
10 changes: 10 additions & 0 deletions src/Classes/ViewModels/ModuleViewModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
Loading