diff --git a/src/Classes/Controllers/IndexController.php b/src/Classes/Controllers/IndexController.php
index 15b8f284..04093371 100644
--- a/src/Classes/Controllers/IndexController.php
+++ b/src/Classes/Controllers/IndexController.php
@@ -18,27 +18,25 @@
use RobinTheHood\ModifiedModuleLoaderClient\App;
use RobinTheHood\ModifiedModuleLoaderClient\Loader\ModuleLoader;
use RobinTheHood\ModifiedModuleLoaderClient\Loader\LocalModuleLoader;
-use RobinTheHood\ModifiedModuleLoaderClient\Loader\RemoteModuleLoader;
use RobinTheHood\ModifiedModuleLoaderClient\ModuleFilter;
use RobinTheHood\ModifiedModuleLoaderClient\ModuleSorter;
use RobinTheHood\ModifiedModuleLoaderClient\Category;
use RobinTheHood\ModifiedModuleLoaderClient\SendMail;
use RobinTheHood\ModifiedModuleLoaderClient\Config;
-use RobinTheHood\ModifiedModuleLoaderClient\DependencyManager\DependencyException;
use RobinTheHood\ModifiedModuleLoaderClient\DependencyManager\DependencyManager;
use RobinTheHood\ModifiedModuleLoaderClient\MmlcVersionInfoLoader;
-use RobinTheHood\ModifiedModuleLoaderClient\ModuleInstaller;
+use RobinTheHood\ModifiedModuleLoaderClient\ModuleManager\ModuleManager;
+use RobinTheHood\ModifiedModuleLoaderClient\ModuleManager\ModuleManagerResult;
use RobinTheHood\ModifiedModuleLoaderClient\ModuleStatus;
use RobinTheHood\ModifiedModuleLoaderClient\Notification;
use RobinTheHood\ModifiedModuleLoaderClient\SelfUpdater;
-use RuntimeException;
class IndexController extends Controller
{
private const REQUIRED_PHP_VERSION = '7.4.0';
- /** @var ModuleInstaller */
- private $moduleInstaller;
+ /** @var ModuleManager */
+ private $moduleManager;
/** @var ModuleFilter */
private $moduleFilter;
@@ -47,7 +45,7 @@ public function __construct(ServerRequestInterface $serverRequest, array $sessio
{
parent::__construct($serverRequest, $session);
- $this->moduleInstaller = ModuleInstaller::createFromConfig();
+ $this->moduleManager = ModuleManager::createFromConfig();
$this->moduleFilter = ModuleFilter::createFromConfig();
}
@@ -66,20 +64,20 @@ public function invoke()
return $this->invokeLazyModuleChangeCount();
case 'lazySystemUpdateCount':
return $this->invokeLazySystemUpdateCount();
+ case 'loadRemoteModule':
+ return $this->invokePull();
case 'install':
return $this->invokeInstall();
+ case 'loadAndInstall':
+ return $this->invokeInstall();
case 'update':
return $this->invokeUpdate();
+ case 'revertChanges':
+ return $this->invokeDiscard();
case 'uninstall':
return $this->invokeUninstall();
- case 'loadRemoteModule':
- return $this->invokeLoadRemoteModule();
- case 'loadAndInstall':
- return $this->invokeLoadAndInstall();
case 'unloadLocalModule':
- return $this->invokeUnloadLocalModule();
- case 'revertChanges':
- return $this->invokeRevertChanges();
+ return $this->invokeDelete();
case 'signIn':
return $this->invokeSignIn();
case 'signOut':
@@ -294,7 +292,7 @@ public function invokeModuleInfo()
'type' => 'warning',
'text' =>
'Einige Abhängigkeiten sind nicht installiert. Das Fehlen von Abhängigkeiten kann zu Fehlern
- bei der Ausführung des Moduls führen. Installiere die folgenden fehlenden Abhänigkeiten:
'
+ bei der Ausführung des Moduls führen. Installiere die folgenden fehlenden Abhängigkeiten:
'
. nl2br($string)
]);
}
@@ -374,7 +372,7 @@ public function invokeLazySystemUpdateCount()
}
}
- public function invokeInstall()
+ public function invokePull()
{
if ($accessRedirect = $this->checkAccessRight()) {
return $accessRedirect;
@@ -384,49 +382,29 @@ public function invokeInstall()
$archiveName = $queryParams['archiveName'] ?? '';
$version = $queryParams['version'] ?? '';
- $moduleLoader = LocalModuleLoader::createFromConfig();
- $module = $moduleLoader->loadByArchiveNameAndVersion($archiveName, $version);
-
- if (!$module) {
- $this->addModuleNotFoundNotification($archiveName, $version);
- return $this->redirect('/');
- }
-
- $force = $queryParams['force'] ?? '';
- $force = $force === 'true' ? true : false;
-
-
- try {
- if ($force) {
- $this->moduleInstaller->install($module, true);
- } else {
- $this->moduleInstaller->installWithDependencies($module);
- }
- } catch (DependencyException $e) {
- $foreInstallUrl = "?action=install"
- . "&archiveName={$module->getArchiveName()}"
- . "&version={$module->getVersion()}"
- . "&ref=moduleInfo"
- . "&force=true";
+ $moduleManagerResult = $this->moduleManager->pull($archiveName, $version);
+ if ($moduleManagerResult->getType() === ModuleManagerResult::TYPE_ERROR) {
Notification::pushFlashMessage([
- 'text' => $e->getMessage()
- . '
Click here to '
- . 'force install ' . $module->getArchiveName() . ':' . $module->getVersion()
- . ' without dependencies.',
+ 'text' => (string) $moduleManagerResult->getMessage(),
'type' => 'error'
]);
- } catch (RuntimeException $e) {
+ } else {
Notification::pushFlashMessage([
- 'text' => $e->getMessage(),
- 'type' => 'error'
+ 'text' => 'Module pulled successfully',
+ 'type' => 'success'
]);
}
- return $this->redirectRef($archiveName, $module->getVersion());
+ $module = $moduleManagerResult->getModule();
+ if ($module) {
+ return $this->redirectRef($module->getArchiveName(), $module->getVersion());
+ }
+
+ return $this->redirectRef($archiveName, $version);
}
- private function invokeRevertChanges()
+ public function invokeInstall()
{
if ($accessRedirect = $this->checkAccessRight()) {
return $accessRedirect;
@@ -435,33 +413,36 @@ private function invokeRevertChanges()
$queryParams = $this->serverRequest->getQueryParams();
$archiveName = $queryParams['archiveName'] ?? '';
$version = $queryParams['version'] ?? '';
+ $force = $queryParams['force'] ?? '';
+ $force = $force === 'true' ? true : false;
- $moduleLoader = LocalModuleLoader::createFromConfig();
- $module = $moduleLoader->loadByArchiveNameAndVersion($archiveName, $version);
-
- if (!$module) {
- $this->addModuleNotFoundNotification($archiveName, $version);
- return $this->redirect('/');
+ if ($force === false) {
+ $moduleManagerResult = $this->moduleManager->install($archiveName, $version);
+ } else {
+ $moduleManagerResult = $this->moduleManager->installWithoutDependencies($archiveName, $version, true);
}
- try {
- $this->moduleInstaller->revertChanges($module);
- } catch (DependencyException $e) {
+ if ($moduleManagerResult->getType() === ModuleManagerResult::TYPE_ERROR) {
Notification::pushFlashMessage([
- 'text' => $e->getMessage(),
+ 'text' => (string) $moduleManagerResult->getMessage(),
'type' => 'error'
]);
- } catch (RuntimeException $e) {
+ } else {
Notification::pushFlashMessage([
- 'text' => $e->getMessage(),
- 'type' => 'error'
+ 'text' => 'Module installed successfully',
+ 'type' => 'success'
]);
}
- return $this->redirectRef($archiveName, $module->getVersion());
+ $module = $moduleManagerResult->getModule();
+ if ($module) {
+ return $this->redirectRef($module->getArchiveName(), $module->getVersion());
+ }
+
+ return $this->redirectRef($archiveName, $version);
}
- public function invokeUninstall()
+ public function invokeUpdate()
{
if ($accessRedirect = $this->checkAccessRight()) {
return $accessRedirect;
@@ -471,32 +452,29 @@ public function invokeUninstall()
$archiveName = $queryParams['archiveName'] ?? '';
$version = $queryParams['version'] ?? '';
- $moduleLoader = LocalModuleLoader::createFromConfig();
- $module = $moduleLoader->loadByArchiveNameAndVersion($archiveName, $version);
+ $moduleManagerResult = $this->moduleManager->update($archiveName);
- if (!$module) {
- $this->addModuleNotFoundNotification($archiveName, $version);
- return $this->redirect('/');
- }
-
- try {
- $this->moduleInstaller->uninstall($module);
- } catch (DependencyException $e) {
+ if ($moduleManagerResult->getType() === ModuleManagerResult::TYPE_ERROR) {
Notification::pushFlashMessage([
- 'text' => $e->getMessage(),
+ 'text' => (string) $moduleManagerResult->getMessage(),
'type' => 'error'
]);
- } catch (RuntimeException $e) {
+ } else {
Notification::pushFlashMessage([
- 'text' => $e->getMessage(),
- 'type' => 'error'
+ 'text' => 'Module updated successfully',
+ 'type' => 'success'
]);
}
- return $this->redirectRef($archiveName, $module->getVersion());
+ $module = $moduleManagerResult->getModule();
+ if ($module) {
+ return $this->redirectRef($module->getArchiveName(), $module->getVersion());
+ }
+
+ return $this->redirectRef($archiveName, $version);
}
- public function invokeUpdate()
+ public function invokeDiscard()
{
if ($accessRedirect = $this->checkAccessRight()) {
return $accessRedirect;
@@ -505,41 +483,32 @@ public function invokeUpdate()
$queryParams = $this->serverRequest->getQueryParams();
$archiveName = $queryParams['archiveName'] ?? '';
$version = $queryParams['version'] ?? '';
+ $withTemplate = $queryParams['withTemplate'] ?? '';
+ $withTemplate = $withTemplate === 'true' ? true : false;
- $moduleLoader = LocalModuleLoader::createFromConfig();
- $module = $moduleLoader->loadByArchiveNameAndVersion($archiveName, $version);
-
- if (!$module) {
- $this->addModuleNotFoundNotification($archiveName, $version);
- return $this->redirect('/');
- }
-
- $newModule = $module;
+ $moduleManagerResult = $this->moduleManager->discard($archiveName, $withTemplate);
- try {
- $newModule = $this->moduleInstaller->updateWithDependencies($module);
- } catch (DependencyException $e) {
+ if ($moduleManagerResult->getType() === ModuleManagerResult::TYPE_ERROR) {
Notification::pushFlashMessage([
- 'text' => $e->getMessage(),
+ 'text' => (string) $moduleManagerResult->getMessage(),
'type' => 'error'
]);
- } catch (RuntimeException $e) {
+ } else {
Notification::pushFlashMessage([
- 'text' => $e->getMessage(),
- 'type' => 'error'
+ 'text' => 'Module discard successfully',
+ 'type' => 'success'
]);
}
- if (!$newModule) {
- $newestModule = $module->getNewestVersion();
- $this->addModuleNotFoundNotification($archiveName, $newestModule->getVersion());
- return $this->redirect('/');
+ $module = $moduleManagerResult->getModule();
+ if ($module) {
+ return $this->redirectRef($module->getArchiveName(), $module->getVersion());
}
- return $this->redirectRef($archiveName, $newModule->getVersion());
+ return $this->redirectRef($archiveName, $version);
}
- public function invokeLoadRemoteModule()
+ public function invokeUninstall()
{
if ($accessRedirect = $this->checkAccessRight()) {
return $accessRedirect;
@@ -549,76 +518,29 @@ public function invokeLoadRemoteModule()
$archiveName = $queryParams['archiveName'] ?? '';
$version = $queryParams['version'] ?? '';
- $moduleLoader = RemoteModuleLoader::create();
- $module = $moduleLoader->loadByArchiveNameAndVersion($archiveName, $version);
-
- if (!$module) {
- $this->addModuleNotFoundNotification($archiveName, $version);
- return $this->redirect('/');
- }
+ $moduleManagerResult = $this->moduleManager->uninstall($archiveName);
- if (!$this->moduleInstaller->pull($module)) {
+ if ($moduleManagerResult->getType() === ModuleManagerResult::TYPE_ERROR) {
Notification::pushFlashMessage([
- 'text' => "Fehler: Das Module $archiveName - $version konnte nicht geladen werden.",
+ 'text' => (string) $moduleManagerResult->getMessage(),
'type' => 'error'
]);
- }
-
- return $this->redirectRef($archiveName, $module->getVersion());
- }
-
- public function invokeLoadAndInstall()
- {
- if ($accessRedirect = $this->checkAccessRight()) {
- return $accessRedirect;
- }
-
- $queryParams = $this->serverRequest->getQueryParams();
- $archiveName = $queryParams['archiveName'] ?? '';
- $version = $queryParams['version'] ?? '';
-
- $moduleLoader = RemoteModuleLoader::create();
- $module = $moduleLoader->loadByArchiveNameAndVersion($archiveName, $version);
-
- if (!$module) {
- $this->addModuleNotFoundNotification($archiveName, $version);
- return $this->redirect('/');
- }
-
- if (!$this->moduleInstaller->pull($module)) {
+ } else {
Notification::pushFlashMessage([
- 'text' => "Fehler: Das Module $archiveName - $version konnte nicht geladen werden.",
- 'type' => 'error'
+ 'text' => 'Module uninstalled successfully',
+ 'type' => 'success'
]);
- return $this->redirect('/');
}
- $moduleLoader = LocalModuleLoader::createFromConfig();
- $module = $moduleLoader->loadByArchiveNameAndVersion($archiveName, $version);
-
- if (!$module) {
- $this->addModuleNotFoundNotification($archiveName, $version);
- return $this->redirect('/');
+ $module = $moduleManagerResult->getModule();
+ if ($module) {
+ return $this->redirectRef($module->getArchiveName(), $module->getVersion());
}
- try {
- $this->moduleInstaller->installWithDependencies($module);
- } catch (DependencyException $e) {
- Notification::pushFlashMessage([
- 'text' => $e->getMessage(),
- 'type' => 'error'
- ]);
- } catch (RuntimeException $e) {
- Notification::pushFlashMessage([
- 'text' => $e->getMessage(),
- 'type' => 'error'
- ]);
- }
-
- return $this->redirectRef($archiveName, $module->getVersion());
+ return $this->redirectRef($archiveName, $version);
}
- public function invokeUnloadLocalModule()
+ public function invokeDelete()
{
if ($accessRedirect = $this->checkAccessRight()) {
return $accessRedirect;
@@ -628,29 +550,26 @@ public function invokeUnloadLocalModule()
$archiveName = $queryParams['archiveName'] ?? '';
$version = $queryParams['version'] ?? '';
- $moduleLoader = LocalModuleLoader::createFromConfig();
- $module = $moduleLoader->loadByArchiveNameAndVersion($archiveName, $version);
+ $moduleManagerResult = $this->moduleManager->delete($archiveName, $version);
- if (!$module) {
- $this->addModuleNotFoundNotification($archiveName, $version);
- return $this->redirect('/');
- }
-
- try {
- $this->moduleInstaller->delete($module);
- } catch (DependencyException $e) {
+ if ($moduleManagerResult->getType() === ModuleManagerResult::TYPE_ERROR) {
Notification::pushFlashMessage([
- 'text' => $e->getMessage(),
+ 'text' => (string) $moduleManagerResult->getMessage(),
'type' => 'error'
]);
- } catch (RuntimeException $e) {
+ } else {
Notification::pushFlashMessage([
- 'text' => $e->getMessage(),
- 'type' => 'error'
+ 'text' => 'Module deleded successfully',
+ 'type' => 'success'
]);
}
- return $this->redirect('/');
+ $module = $moduleManagerResult->getModule();
+ if ($module) {
+ return $this->redirectRef($module->getArchiveName(), $module->getVersion());
+ }
+
+ return $this->redirectRef($archiveName, $version);
}
public function invokeReportIssue()
diff --git a/src/Classes/DependencyManager/CombinationSatisfyer.php b/src/Classes/DependencyManager/CombinationSatisfyer.php
index e7fb471f..54a06dc5 100644
--- a/src/Classes/DependencyManager/CombinationSatisfyer.php
+++ b/src/Classes/DependencyManager/CombinationSatisfyer.php
@@ -42,7 +42,7 @@ public function satisfiesCominationsFromModuleTrees(
foreach ($combinations as $testCombination) {
$foundCombination = new Combination();
- $result = $this->satisfiesCominationFromModuleTrees(
+ $result = $this->satisfiesCombinationFromModuleTrees(
$moduleTrees,
$testCombination,
$foundCombination,
@@ -85,7 +85,7 @@ public function satisfiesCominationsFromModuleTree(
$failLog = new FailLog();
foreach ($combinations as $testCombination) {
- $result = $this->satisfiesCominationFromModuleTree(
+ $result = $this->satisfiesCombinationFromModuleTree(
$moduleTree,
$testCombination,
$foundCombination,
@@ -113,7 +113,7 @@ public function satisfiesCominationsFromModuleTree(
return $combinationSatisfyerResult;
}
- public function satisfiesCominationsFromModuleWithIterator(
+ public function satisfiesCombinationsFromModuleWithIterator(
ModuleTree $moduleTree,
CombinationIterator $combinationIterator
): CombinationSatisfyerResult {
@@ -121,7 +121,7 @@ public function satisfiesCominationsFromModuleWithIterator(
$foundCombination = new Combination();
$failLog = new FailLog();
$testCombination = $combinationIterator->current();
- $result = $this->satisfiesCominationFromModuleTree(
+ $result = $this->satisfiesCombinationFromModuleTree(
$moduleTree,
$testCombination,
$foundCombination,
@@ -160,7 +160,7 @@ public function satisfiesCominationsFromModuleWithIterator(
*
* @return bool
*/
- public function satisfiesCominationFromModuleTree(
+ public function satisfiesCombinationFromModuleTree(
ModuleTree $moduleTree,
Combination $combination,
Combination &$foundCombination,
@@ -198,7 +198,7 @@ public function satisfiesCominationFromModuleTree(
$moduleTree->versionConstraint
);
- return $this->satisfiesCominationFromModuleTrees(
+ return $this->satisfiesCombinationFromModuleTrees(
$moduleVersion->require,
$combination,
$foundCombination,
@@ -222,7 +222,7 @@ public function satisfiesCominationFromModuleTree(
*
* @return bool
*/
- public function satisfiesCominationFromModuleTrees(
+ public function satisfiesCombinationFromModuleTrees(
array $moduleTrees,
Combination $combination,
Combination &$foundCombination,
@@ -232,7 +232,7 @@ public function satisfiesCominationFromModuleTrees(
// Context: Expanded
$moduleResult = true;
foreach ($moduleTrees as $moduleTree) {
- $result = $this->satisfiesCominationFromModuleTree(
+ $result = $this->satisfiesCombinationFromModuleTree(
$moduleTree,
$combination,
$foundCombination,
diff --git a/src/Classes/DependencyManager/CombinationSatisfyerResult.php b/src/Classes/DependencyManager/CombinationSatisfyerResult.php
index df6cad59..c7d2985a 100644
--- a/src/Classes/DependencyManager/CombinationSatisfyerResult.php
+++ b/src/Classes/DependencyManager/CombinationSatisfyerResult.php
@@ -13,6 +13,9 @@
namespace RobinTheHood\ModifiedModuleLoaderClient\DependencyManager;
+/**
+ * Das CombinationSatisfyerResult Objekt liefert Information zum Ergebnis des CombinationStisfyer.
+ */
class CombinationSatisfyerResult
{
public const RESULT_COMBINATION_NOT_FOUND = 0;
@@ -21,10 +24,18 @@ class CombinationSatisfyerResult
/** @var int */
public $result = -1;
- /** @var ?Combination */
+ /**
+ * @var ?Combination $testCombination Beinhaltet eine Kombination an allen Modulen und PHP, MMLC und modified
+ * Versionen die durch ein SystemSet als Auswahl standen. Welche Kombination verwendet wird hängt vom
+ * CombinationStisfyer ab. Oft ist es die letzte Kombination die probiert wurde.
+ */
public $testCombination = null;
- /** @var ?Combination */
+ /**
+ * @var ?Combination $foundCombination Enthält nur die Elemente (Module, PHP, MMLC und modified Version) aus
+ * $testCombination die nötig sind, um die Voraussetung für ein Modul zu erfüllen. Ist das Ergbnis
+ * RESULT_COMBINATION_NOT_FOUND, fehlen in $foundCombination Elemente.
+ */
public $foundCombination = null;
/** @var ?FailLog */
diff --git a/src/Classes/DependencyManager/DependencyBuilder.php b/src/Classes/DependencyManager/DependencyBuilder.php
index bdd2f01a..c408db37 100644
--- a/src/Classes/DependencyManager/DependencyBuilder.php
+++ b/src/Classes/DependencyManager/DependencyBuilder.php
@@ -15,7 +15,6 @@
use RobinTheHood\ModifiedModuleLoaderClient\Config;
use RobinTheHood\ModifiedModuleLoaderClient\Loader\ModuleLoader;
use RobinTheHood\ModifiedModuleLoaderClient\Module;
-use RobinTheHood\ModifiedModuleLoaderClient\Semver\Comparator;
use RobinTheHood\ModifiedModuleLoaderClient\Semver\Constraint;
class DependencyBuilder
@@ -40,60 +39,104 @@ public function __construct(ModuleTreeBuilder $moduleTreeBuilder, ModuleLoader $
$this->moduleLoader = $moduleLoader;
}
- private function logFile($value, $file)
+ /**
+ * Testet, ob alle Bedingungen für ein Modul erfüllt sind. Als Ergbnis gibt die Methode ein
+ * CombinationSatisfyerResult zurück. Als $constraint kann eine konkrete Version oder ein Constraint wie z. B.
+ * ^1.0.0 angegeben werden. Die Methode versucht eine Kombination mit den neusten Versionen zu finden. Wenn eine
+ * Kombination gefunden wurde, befindet sich diese in CombinationSatisfyerResult::foundCombination. Das Modul auf
+ * das mit $archiveName getestet wurde befindet sich ebenfalls in CombinationSatisfyerResult::foundCombination
+ *
+ * @param string $archiveName
+ * @param string $constraint
+ * @param SystemSet $systemSet Mit $systemSet kann festgelegt werden, welche Module bereits installiert sind,
+ * welche PHP, MMLC und modified Version vorhanden ist.
+ *
+ * @return CombinationSatisfyerResult
+ */
+ public function satisfies(string $archiveName, string $constraint, SystemSet $systemSet): CombinationSatisfyerResult
{
- if (!Config::getLogging()) {
- return;
+ $systemSet->remove($archiveName);
+ $constraint = $this->createConstraint($archiveName, $constraint, $systemSet);
+
+ $moduleTree = $this->moduleTreeBuilder->buildByConstraints($archiveName, $constraint);
+ $this->logFile($moduleTree, '3-moduleTrees.json');
+
+ $flatEntryBuilder = new FlatEntryBuilder();
+ $flatEntries = $flatEntryBuilder->buildListFromModuleTree($moduleTree);
+ $this->logFile($flatEntries, '3-flatEntries.json');
+
+ $flatEntries = $flatEntryBuilder->fitSystemSet($flatEntries, $systemSet);
+ $this->logFile($flatEntries, '3-flatEntries-fit.json');
+
+ $combinationIterator = new CombinationIterator($flatEntries);
+ $combinationSatisfyer = new CombinationSatisfyer();
+ $combinationSatisfyerResult = $combinationSatisfyer->satisfiesCombinationsFromModuleWithIterator(
+ $moduleTree,
+ $combinationIterator
+ );
+
+ return $combinationSatisfyerResult;
+ }
+
+ /**
+ * Gehe alle Module durch, die in $systemSet sind und gleichzeitig das Modul $archiveName benötigen.
+ * Gibt ein $constraint zurück, sodass die Anforderungenden der Module in $systemSet erhaltenbleiben.
+ */
+ private function createConstraint(string $archiveName, string $constraint, SystemSet $systemSet): string
+ {
+ /** @var string[] */
+ $requiredConstraints = [$constraint];
+
+ $archives = $systemSet->getArchives();
+ foreach ($archives as $archiveNameB => $version) {
+ $installedModule = $this->getModuleByArchiveNameAndVersion($archiveNameB, $version);
+ if (!$installedModule) {
+ continue;
+ }
+
+ $requiredConstraint = $this->getRequiredConstraint($installedModule, $archiveName);
+ if (!$requiredConstraint) {
+ continue;
+ }
+
+ $requiredConstraints[] = $requiredConstraint;
}
- $logsRootPath = App::getLogsRoot();
+ $constraint = Constraint::createConstraintFromConstraints($requiredConstraints);
- @mkdir($logsRootPath);
- @mkdir($logsRootPath . '/debug');
- @mkdir($logsRootPath . '/debug/DependencyMananger/');
- $path = $logsRootPath . '/debug/DependencyMananger/' . $file;
- file_put_contents($path, json_encode($value, JSON_PRETTY_PRINT));
+ return $constraint;
}
- public function log($var)
+ private function getModuleByArchiveNameAndVersion(string $archiveName, string $version): ?Module
{
- print_r($var);
+ return $this->moduleLoader->loadByArchiveNameAndVersion($archiveName, $version);
}
- public function test()
+ private function getRequiredConstraint(Module $installedModule, string $archiveName): string
{
- $moduleLoader = ModuleLoader::create(Comparator::CARET_MODE_STRICT);
- $module = $moduleLoader->loadLatestVersionByArchiveName('firstweb/multi-order');
+ $required = $installedModule->getRequire();
+ return $required[$archiveName] ?? '';
+ }
- if (!$module) {
- die('Can not find base module');
+ private function logFile($value, $file)
+ {
+ if (!Config::getLogging()) {
+ return;
}
- $systemSet = new SystemSet();
- $systemSet->set([
- "modified" => '2.0.4.2',
- "php" => '7.4.0',
- "mmlc" => '1.19.0',
- "composer/autoload" => '1.3.0',
- "robinthehood/modified-std-module" => '0.9.0',
- "robinthehood/modified-orm" => '1.8.1',
- "robinthehood/pdf-bill" => '0.17.0'
- ]);
-
- $this->log('TEST: satisfiesContraints1');
- $combinationSatisfyerResult = $this->satisfiesContraints1($module, $systemSet);
- $this->log($combinationSatisfyerResult);
-
- $this->log('TEST: satisfiesContraints2');
- $combinationSatisfyerResult = $this->satisfiesContraints2('firstweb/multi-order', '^1.0.0', $systemSet);
- $this->log($combinationSatisfyerResult);
-
- // var_dump('TEST: satisfiesContraints3');
- $combinationSatisfyerResult = $this->satisfies('firstweb/multi-order', '^1.0.0', $systemSet);
- $this->log($combinationSatisfyerResult);
+ $logsRootPath = App::getLogsRoot();
+
+ @mkdir($logsRootPath);
+ @mkdir($logsRootPath . '/debug');
+ @mkdir($logsRootPath . '/debug/DependencyMananger/');
+ $path = $logsRootPath . '/debug/DependencyMananger/' . $file;
+ file_put_contents($path, json_encode($value, JSON_PRETTY_PRINT));
}
- public function satisfiesContraints1(Module $module, SystemSet $systemSet): CombinationSatisfyerResult
+ /**
+ * Diese Methode wird zurzeit nicht verwednet und wurde deswegen auf private gestellt.
+ */
+ private function satisfiesContraints1(Module $module, SystemSet $systemSet): CombinationSatisfyerResult
{
$moduleTrees = $this->moduleTreeBuilder->buildListByConstraints($module);
$this->logFile($moduleTrees, '1-moduleTrees.json');
@@ -118,8 +161,10 @@ public function satisfiesContraints1(Module $module, SystemSet $systemSet): Comb
return $combinationSatisfyerResult;
}
-
- public function satisfiesContraints2(
+ /**
+ * Diese Methode wird zurzeit nicht verwednet und wurde deswegen auf private gestellt.
+ */
+ private function satisfiesContraints2(
string $archiveName,
string $constraint,
SystemSet $systemSet
@@ -146,68 +191,4 @@ public function satisfiesContraints2(
return $combinationSatisfyerResult;
}
-
- public function satisfies(string $archiveName, string $constraint, SystemSet $systemSet): CombinationSatisfyerResult
- {
- $systemSet->remove($archiveName);
- $constraint = $this->createConstraint($archiveName, $constraint, $systemSet);
-
- $moduleTree = $this->moduleTreeBuilder->buildByConstraints($archiveName, $constraint);
- $this->logFile($moduleTree, '3-moduleTrees.json');
-
- $flatEntryBuilder = new FlatEntryBuilder();
- $flatEntries = $flatEntryBuilder->buildListFromModuleTree($moduleTree);
- $this->logFile($flatEntries, '3-flatEntries.json');
-
- $flatEntries = $flatEntryBuilder->fitSystemSet($flatEntries, $systemSet);
- $this->logFile($flatEntries, '3-flatEntries-fit.json');
-
- $combinationIterator = new CombinationIterator($flatEntries);
- $combinationSatisfyer = new CombinationSatisfyer();
- $combinationSatisfyerResult = $combinationSatisfyer->satisfiesCominationsFromModuleWithIterator(
- $moduleTree,
- $combinationIterator
- );
- return $combinationSatisfyerResult;
- }
-
- /**
- * Gehe alle Module durch, die in $systemSet sind und das gleichzeitig Modul $archiveName benötigen.
- * Gibt ein $constraint zurück, sodass die Anforderungenden der Module in $systemSet erhaltenbleiben.
- */
- private function createConstraint(string $archiveName, string $constraint, SystemSet $systemSet): string
- {
- /** @var string[] */
- $requiredConstraints = [$constraint];
-
- $archives = $systemSet->getArchives();
- foreach ($archives as $archiveNameB => $version) {
- $installedModule = $this->getModuleByArchiveNameAndVersion($archiveNameB, $version);
- if (!$installedModule) {
- continue;
- }
-
- $requiredConstraint = $this->getRequiredConstraint($installedModule, $archiveName);
- if (!$requiredConstraint) {
- continue;
- }
-
- $requiredConstraints[] = $requiredConstraint;
- }
-
- $constraint = Constraint::createConstraintFromConstraints($requiredConstraints);
-
- return $constraint;
- }
-
- private function getModuleByArchiveNameAndVersion(string $archiveName, string $version): ?Module
- {
- return $this->moduleLoader->loadByArchiveNameAndVersion($archiveName, $version);
- }
-
- private function getRequiredConstraint(Module $installedModule, string $archiveName): string
- {
- $required = $installedModule->getRequire();
- return $required[$archiveName] ?? '';
- }
}
diff --git a/src/Classes/DependencyManager/DependencyBuilderOld.php b/src/Classes/DependencyManager/DependencyBuilderOld.php
new file mode 100644
index 00000000..41c18ab6
--- /dev/null
+++ b/src/Classes/DependencyManager/DependencyBuilderOld.php
@@ -0,0 +1,213 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace RobinTheHood\ModifiedModuleLoaderClient\DependencyManager;
+
+use RobinTheHood\ModifiedModuleLoaderClient\App;
+use RobinTheHood\ModifiedModuleLoaderClient\Config;
+use RobinTheHood\ModifiedModuleLoaderClient\Loader\ModuleLoader;
+use RobinTheHood\ModifiedModuleLoaderClient\Module;
+use RobinTheHood\ModifiedModuleLoaderClient\Semver\Comparator;
+use RobinTheHood\ModifiedModuleLoaderClient\Semver\Constraint;
+
+class DependencyBuilderOld
+{
+ /** @var ModuleTreeBuilder*/
+ private $moduleTreeBuilder;
+
+ /** @var ModuleLoader*/
+ private $moduleLoader;
+
+ public static function create(int $mode): DependencyBuilder
+ {
+ $moduleTreeBuilder = ModuleTreeBuilder::create($mode);
+ $moduleLoader = ModuleLoader::create($mode);
+ $dependencyBuilder = new DependencyBuilder($moduleTreeBuilder, $moduleLoader);
+ return $dependencyBuilder;
+ }
+
+ public function __construct(ModuleTreeBuilder $moduleTreeBuilder, ModuleLoader $moduleLoader)
+ {
+ $this->moduleTreeBuilder = $moduleTreeBuilder;
+ $this->moduleLoader = $moduleLoader;
+ }
+
+ private function logFile($value, $file)
+ {
+ if (!Config::getLogging()) {
+ return;
+ }
+
+ $logsRootPath = App::getLogsRoot();
+
+ @mkdir($logsRootPath);
+ @mkdir($logsRootPath . '/debug');
+ @mkdir($logsRootPath . '/debug/DependencyMananger/');
+ $path = $logsRootPath . '/debug/DependencyMananger/' . $file;
+ file_put_contents($path, json_encode($value, JSON_PRETTY_PRINT));
+ }
+
+ public function log($var)
+ {
+ print_r($var);
+ }
+
+ public function test()
+ {
+ $moduleLoader = ModuleLoader::create(Comparator::CARET_MODE_STRICT);
+ $module = $moduleLoader->loadLatestVersionByArchiveName('firstweb/multi-order');
+
+ if (!$module) {
+ die('Can not find base module');
+ }
+
+ $systemSet = new SystemSet();
+ $systemSet->set([
+ "modified" => '2.0.4.2',
+ "php" => '7.4.0',
+ "mmlc" => '1.19.0',
+ "composer/autoload" => '1.3.0',
+ "robinthehood/modified-std-module" => '0.9.0',
+ "robinthehood/modified-orm" => '1.8.1',
+ "robinthehood/pdf-bill" => '0.17.0'
+ ]);
+
+ $this->log('TEST: satisfiesContraints1');
+ $combinationSatisfyerResult = $this->satisfiesContraints1($module, $systemSet);
+ $this->log($combinationSatisfyerResult);
+
+ $this->log('TEST: satisfiesContraints2');
+ $combinationSatisfyerResult = $this->satisfiesContraints2('firstweb/multi-order', '^1.0.0', $systemSet);
+ $this->log($combinationSatisfyerResult);
+
+ // var_dump('TEST: satisfiesContraints3');
+ $combinationSatisfyerResult = $this->satisfies('firstweb/multi-order', '^1.0.0', $systemSet);
+ $this->log($combinationSatisfyerResult);
+ }
+
+ public function satisfiesContraints1(Module $module, SystemSet $systemSet): CombinationSatisfyerResult
+ {
+ $moduleTrees = $this->moduleTreeBuilder->buildListByConstraints($module);
+ $this->logFile($moduleTrees, '1-moduleTrees.json');
+
+ $flatEntryBuilder = new FlatEntryBuilder();
+ $flatEntries = $flatEntryBuilder->buildListFromModuleTrees($moduleTrees);
+ $this->logFile($flatEntries, '1-flatEntries.json');
+
+ $flatEntries = $flatEntryBuilder->fitSystemSet($flatEntries, $systemSet);
+ $this->logFile($flatEntries, '1-flatEntries-fit.json');
+
+ $combinationBuilder = new CombinationBuilder();
+ $combinations = $combinationBuilder->buildAllFromModuleFlatEntries($flatEntries);
+ $this->logFile($combinations, '1-combinations.json');
+
+ $combinationSatisfyer = new CombinationSatisfyer();
+ $combinationSatisfyerResult = $combinationSatisfyer->satisfiesCominationsFromModuleTrees(
+ $moduleTrees,
+ $combinations
+ );
+
+ return $combinationSatisfyerResult;
+ }
+
+
+ public function satisfiesContraints2(
+ string $archiveName,
+ string $constraint,
+ SystemSet $systemSet
+ ): CombinationSatisfyerResult {
+ $moduleTree = $this->moduleTreeBuilder->buildByConstraints($archiveName, $constraint);
+ $this->logFile($moduleTree, '2-moduleTrees.json');
+
+ $flatEntryBuilder = new FlatEntryBuilder();
+ $flatEntries = $flatEntryBuilder->buildListFromModuleTree($moduleTree);
+ $this->logFile($flatEntries, '2-flatEntries.json');
+
+ $flatEntries = $flatEntryBuilder->fitSystemSet($flatEntries, $systemSet);
+ $this->logFile($flatEntries, '2-flatEntries-fit.json');
+
+ $combinationBuilder = new CombinationBuilder();
+ $combinations = $combinationBuilder->buildAllFromModuleFlatEntries($flatEntries);
+ $this->logFile($combinations, '2-combinations.json');
+
+ $combinationSatisfyer = new CombinationSatisfyer();
+ $combinationSatisfyerResult = $combinationSatisfyer->satisfiesCominationsFromModuleTree(
+ $moduleTree,
+ $combinations
+ );
+
+ return $combinationSatisfyerResult;
+ }
+
+ public function satisfies(string $archiveName, string $constraint, SystemSet $systemSet): CombinationSatisfyerResult
+ {
+ $systemSet->remove($archiveName);
+ $constraint = $this->createConstraint($archiveName, $constraint, $systemSet);
+
+ $moduleTree = $this->moduleTreeBuilder->buildByConstraints($archiveName, $constraint);
+ $this->logFile($moduleTree, '3-moduleTrees.json');
+
+ $flatEntryBuilder = new FlatEntryBuilder();
+ $flatEntries = $flatEntryBuilder->buildListFromModuleTree($moduleTree);
+ $this->logFile($flatEntries, '3-flatEntries.json');
+
+ $flatEntries = $flatEntryBuilder->fitSystemSet($flatEntries, $systemSet);
+ $this->logFile($flatEntries, '3-flatEntries-fit.json');
+
+ $combinationIterator = new CombinationIterator($flatEntries);
+ $combinationSatisfyer = new CombinationSatisfyer();
+ $combinationSatisfyerResult = $combinationSatisfyer->satisfiesCombinationsFromModuleWithIterator(
+ $moduleTree,
+ $combinationIterator
+ );
+ return $combinationSatisfyerResult;
+ }
+
+ /**
+ * Gehe alle Module durch, die in $systemSet sind und das gleichzeitig Modul $archiveName benötigen.
+ * Gibt ein $constraint zurück, sodass die Anforderungenden der Module in $systemSet erhaltenbleiben.
+ */
+ private function createConstraint(string $archiveName, string $constraint, SystemSet $systemSet): string
+ {
+ /** @var string[] */
+ $requiredConstraints = [$constraint];
+
+ $archives = $systemSet->getArchives();
+ foreach ($archives as $archiveNameB => $version) {
+ $installedModule = $this->getModuleByArchiveNameAndVersion($archiveNameB, $version);
+ if (!$installedModule) {
+ continue;
+ }
+
+ $requiredConstraint = $this->getRequiredConstraint($installedModule, $archiveName);
+ if (!$requiredConstraint) {
+ continue;
+ }
+
+ $requiredConstraints[] = $requiredConstraint;
+ }
+
+ $constraint = Constraint::createConstraintFromConstraints($requiredConstraints);
+
+ return $constraint;
+ }
+
+ private function getModuleByArchiveNameAndVersion(string $archiveName, string $version): ?Module
+ {
+ return $this->moduleLoader->loadByArchiveNameAndVersion($archiveName, $version);
+ }
+
+ private function getRequiredConstraint(Module $installedModule, string $archiveName): string
+ {
+ $required = $installedModule->getRequire();
+ return $required[$archiveName] ?? '';
+ }
+}
diff --git a/src/Classes/DependencyManager/DependencyManager.php b/src/Classes/DependencyManager/DependencyManager.php
index a6990760..044230a4 100644
--- a/src/Classes/DependencyManager/DependencyManager.php
+++ b/src/Classes/DependencyManager/DependencyManager.php
@@ -110,6 +110,9 @@ public function getAllModulesFromCombination(Combination $combination): array
}
/**
+ * Kontrolliert, ob ein Modul installiert werden kann. Es wird getestet, ob genau die Version installiert werden
+ * kann.
+ *
* @param Module $module
* @param string[] $doNotCheck
*
@@ -137,35 +140,45 @@ public function canBeInstalled(Module $module, array $doNotCheck = []): Combinat
. " The following combination is required: {$combinationSatisfyerResult->failLog}";
StaticLogger::log(LogLevel::WARNING, $message);
- throw new DependencyException($message);
}
- // $modules = $this->getAllModulesFromCombination($combinationSatisfyerResult->foundCombination);
- // $this->canBeInstalledTestChanged($module, $modules);
-
return $combinationSatisfyerResult;
}
/**
- * Testet, ob das Modul in $module installiert werden kann, ob das Modul $module
- * selbst oder eine Abhängigkeit in $modules im Status 'changed' ist.
+ * Kontrolliert, ob ein Modul aktuallisert werden kann, Es wird getestet, ob es eine neuerer Version gibt, die alle
+ * Bedingungen erfüllt. Wenn ja, steckt eine passende Kombination in CombinationSatisfyerResult::foundCombination.
*
- * @param Module[] $modules
+ * @param Module $module
+ * @param string[] $doNotCheck
+ *
+ * @return CombinationSatisfyerResult
*/
- private function canBeInstalledTestChanged(Module $module, array $modules): void
+ public function canBeUpdated(Module $module, array $doNotCheck = []): CombinationSatisfyerResult
{
- $module = $module->getInstalledVersion();
- if ($module && $module->isInstalled() && $module->isChanged()) {
- $a = $module->getArchiveName();
- throw new DependencyException("Module $a can not be installed because the Module has changes");
+ $systemSet = $this->systemSetFactory->getSystemSet();
+
+ foreach ($doNotCheck as $name) {
+ $systemSet->remove($name);
}
- foreach ($modules as $module) {
- if ($module && $module->isInstalled() && $module->isChanged()) {
- $a = $module->getArchiveName();
- throw new DependencyException("Required Module $a can not be installed because the Module has changes");
- }
+ $combinationSatisfyerResult = $this->dependencyBuilder->satisfies(
+ $module->getArchiveName(),
+ '>' . $module->getVersion(),
+ $systemSet
+ );
+
+ if ($combinationSatisfyerResult->result === CombinationSatisfyerResult::RESULT_COMBINATION_NOT_FOUND) {
+ $message = "Can not update module {$module->getArchiveName()} in version {$module->getVersion()} "
+ . "because there are conflicting version contraints. "
+ . "Perhaps you have installed a module that requires a different version, "
+ . "or there is no compatible combination of dependencies. "
+ . " The following combination is required: {$combinationSatisfyerResult->failLog}";
+
+ StaticLogger::log(LogLevel::WARNING, $message);
}
+
+ return $combinationSatisfyerResult;
}
/**
@@ -202,4 +215,26 @@ public function getMissingDependencies(Module $module): array
return $missing;
}
+
+ /**
+ * Testet, ob das Modul in $module installiert werden kann, ob das Modul $module
+ * selbst oder eine Abhängigkeit in $modules im Status 'changed' ist.
+ *
+ * @param Module[] $modules
+ */
+ private function canBeInstalledTestChanged(Module $module, array $modules): void
+ {
+ $module = $module->getInstalledVersion();
+ if ($module && $module->isInstalled() && $module->isChanged()) {
+ $a = $module->getArchiveName();
+ throw new DependencyException("Module $a can not be installed because the Module has changes");
+ }
+
+ foreach ($modules as $module) {
+ if ($module && $module->isInstalled() && $module->isChanged()) {
+ $a = $module->getArchiveName();
+ throw new DependencyException("Required Module $a can not be installed because the Module has changes");
+ }
+ }
+ }
}
diff --git a/src/Classes/Loader/LocalModuleLoader.php b/src/Classes/Loader/LocalModuleLoader.php
index 5b748ee7..e5027740 100644
--- a/src/Classes/Loader/LocalModuleLoader.php
+++ b/src/Classes/Loader/LocalModuleLoader.php
@@ -140,6 +140,19 @@ public function loadAllInstalledVersions(): array
return $installedModules;
}
+ /**
+ * Loads the installed module version by a given archiveName
+ *
+ * @return Module|null Returns a array of installed module versions.
+ */
+ public function loadInstalledVersionByArchiveName(string $arhciveName): ?Module
+ {
+ $modules = $this->loadAllVersions();
+ $installedModules = $this->moduleFilter->filterInstalled($modules);
+ $installedModules = $this->moduleFilter->filterByArchiveName($installedModules, $arhciveName);
+ return $installedModules[0] ?? null;
+ }
+
public function getVendorDirs()
{
return FileHelper::scanDir($this->modulesRootPath, FileHelper::DIRS_ONLY);
diff --git a/src/Classes/Module.php b/src/Classes/Module.php
index 871aad9d..b1b99a2c 100644
--- a/src/Classes/Module.php
+++ b/src/Classes/Module.php
@@ -23,8 +23,6 @@
use RobinTheHood\ModifiedModuleLoaderClient\Loader\ModuleLoader;
use RobinTheHood\ModifiedModuleLoaderClient\Loader\LocalModuleLoader;
use RobinTheHood\ModifiedModuleLoaderClient\Helpers\FileHelper;
-use RobinTheHood\ModifiedModuleLoaderClient\Semver\Comparator;
-use RobinTheHood\ModifiedModuleLoaderClient\Semver\Parser;
class Module extends ModuleInfo
{
diff --git a/src/Classes/ModuleChangeManager.php b/src/Classes/ModuleChangeManager.php
index 9bd14f92..1876ae3c 100644
--- a/src/Classes/ModuleChangeManager.php
+++ b/src/Classes/ModuleChangeManager.php
@@ -30,10 +30,6 @@ class ModuleChangeManager
*/
public static function getChangedFiles(Module $module): ChangedEntryCollection
{
- if ($module->getArchiveName() === 'robinthehood/modified-std-module') {
- $a = 1;
- }
-
$hashFileLoader = new HashFileLoader();
$hashFileLoader->setDefaultScope(ModuleHasher::SCOPE_SHOP_ROOT);
$hashFile = $hashFileLoader->load($module->getHashPath());
@@ -50,12 +46,6 @@ public static function getChangedFiles(Module $module): ChangedEntryCollection
$srcMmlcChangedEntiresCollection
]);
- // if ($module->getArchiveName() === 'robinthehood/modified-std-module') {
- // echo '
';
- // print_r($hashFile);
- // print_r($changedEntiresCollection);
- // die();
- // }
return $changedEntiresCollection;
}
diff --git a/src/Classes/ModuleHasher/ModuleHasher.php b/src/Classes/ModuleHasher/ModuleHasher.php
index d67d96df..04dedade 100644
--- a/src/Classes/ModuleHasher/ModuleHasher.php
+++ b/src/Classes/ModuleHasher/ModuleHasher.php
@@ -75,7 +75,8 @@ public function createShopRootHashes(Module $module): HashEntryCollection
public function createShopVendorMmlcHashes(Module $module): HashEntryCollection
{
$files = $module->getSrcMmlcFilePaths();
- $root = App::getShopRoot() . '/' . ModulePathMapper::moduleSrcMmlcToShopVendorMmlc('/', $module->getArchiveName());
+ $root =
+ App::getShopRoot() . '/' . ModulePathMapper::moduleSrcMmlcToShopVendorMmlc('/', $module->getArchiveName());
return $this->fileHasher->createHashes($files, $root, self::SCOPE_SHOP_VENDOR_MMLC);
}
}
diff --git a/src/Classes/ModuleInstaller.php b/src/Classes/ModuleInstaller.php
deleted file mode 100644
index 5116780a..00000000
--- a/src/Classes/ModuleInstaller.php
+++ /dev/null
@@ -1,465 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace RobinTheHood\ModifiedModuleLoaderClient;
-
-use RobinTheHood\ModifiedModuleLoaderClient\App;
-use RobinTheHood\ModifiedModuleLoaderClient\Archive;
-use RobinTheHood\ModifiedModuleLoaderClient\Config;
-use RobinTheHood\ModifiedModuleLoaderClient\FileInfo;
-use RobinTheHood\ModifiedModuleLoaderClient\Api\V1\ApiRequest;
-use RobinTheHood\ModifiedModuleLoaderClient\Archive\Archive as ArchiveArchive;
-use RobinTheHood\ModifiedModuleLoaderClient\Archive\ArchiveHandler;
-use RobinTheHood\ModifiedModuleLoaderClient\Archive\ArchiveName;
-use RobinTheHood\ModifiedModuleLoaderClient\Archive\ArchivePuller;
-use RobinTheHood\ModifiedModuleLoaderClient\DependencyManager\Combination;
-use RobinTheHood\ModifiedModuleLoaderClient\DependencyManager\DependencyManager;
-use RobinTheHood\ModifiedModuleLoaderClient\Loader\LocalModuleLoader;
-use RobinTheHood\ModifiedModuleLoaderClient\Helpers\FileHelper;
-use RobinTheHood\ModifiedModuleLoaderClient\Logger\LogLevel;
-use RobinTheHood\ModifiedModuleLoaderClient\Logger\StaticLogger;
-use RobinTheHood\ModifiedModuleLoaderClient\ModuleHasher\ModuleHashFileCreator;
-use RuntimeException;
-
-class ModuleInstaller
-{
- /** @var DependencyManager */
- private $dependencyManager;
-
- /** @var ModuleFilter */
- private $moduleFilter;
-
- /** @var LocalModuleLoader */
- private $localModuleLoader;
-
- /** @var ArchivePuller */
- private $archivePuller;
-
- /** @var ArchiveHandler */
- private $archiveHandler;
-
-
-
- // new ArchiveHandler($this->localModuleLoader, App::getModulesRoot());
- public static function create(int $mode): ModuleInstaller
- {
- $dependencyManager = DependencyManager::create($mode);
- $moduleFilter = ModuleFilter::create($mode);
- $localModuleLoader = LocalModuleLoader::create($mode);
- $archivePuller = ArchivePuller::create();
- $archiveHandler = ArchiveHandler::create($mode);
- $moduleInstaller = new ModuleInstaller(
- $dependencyManager,
- $moduleFilter,
- $localModuleLoader,
- $archivePuller,
- $archiveHandler
- );
- return $moduleInstaller;
- }
-
- public static function createFromConfig(): ModuleInstaller
- {
- return self::create(Config::getDependenyMode());
- }
-
- public function __construct(
- DependencyManager $dependencyManager,
- ModuleFilter $moduleFilter,
- LocalModuleLoader $localModuleLoader,
- ArchivePuller $archivePuller,
- ArchiveHandler $archiveHandler
- ) {
- $this->dependencyManager = $dependencyManager;
- $this->moduleFilter = $moduleFilter;
- $this->localModuleLoader = $localModuleLoader;
- $this->archivePuller = $archivePuller;
- $this->archiveHandler = $archiveHandler;
- }
-
- public function pull(Module $module): bool
- {
- if ($module->isLoaded()) {
- return true;
- }
-
- $apiRequest = new ApiRequest();
- $result = $apiRequest->getArchive($module->getArchiveName(), $module->getVersion());
-
- $content = $result['content'] ?? [];
- if (!$content) {
- return false;
- }
-
- $archiveUrl = $content['archiveUrl'] ?? '';
-
- if (!$archiveUrl) {
- return false;
- }
-
- try {
- // New
- $archive = $this->archivePuller->pull($module->getArchiveName(), $module->getVersion(), $archiveUrl);
- $this->archiveHandler->extract($archive);
- return true;
-
- // Old
- $archive = Archive::pullArchive($archiveUrl, $module->getArchiveName(), $module->getVersion());
- $archive->untarArchive();
- return true;
- } catch (RuntimeException $e) {
- //Can not pull Archive
- return false;
- }
- }
-
- public function delete(Module $module)
- {
- $path = $module->getLocalRootPath() . $module->getModulePath();
-
- $filePaths = FileHelper::scanDirRecursive($path, FileHelper::FILES_ONLY);
-
- $dirPaths = FileHelper::scanDirRecursive($path, FileHelper::DIRS_ONLY);
- $dirPaths = array_reverse($dirPaths);
- $dirPaths[] = $path;
- $dirPaths[] = dirname($path);
-
- // Delete Files
- foreach ($filePaths as $path) {
- if (file_exists($path)) {
- unlink($path);
- }
- }
-
- // Delete Folders
- foreach ($dirPaths as $path) {
- if (file_exists($path)) {
- @rmdir($path);
- }
- }
- }
-
- public function install(Module $module, bool $force = false): void
- {
- if (!$force) {
- $this->dependencyManager->canBeInstalled($module);
- }
-
- $this->internalInstall($module);
- $this->createAutoloadFile();
- }
-
- public function installWithDependencies(Module $module): void
- {
- $combinationSatisfyerResult = $this->dependencyManager->canBeInstalled($module, ['']);
-
- if (!$combinationSatisfyerResult->foundCombination) {
- $message =
- "Can not install module {$module->getArchiveName()} {$module->getVersion()} with dependencies. "
- . "No possible combination of versions found";
- StaticLogger::log(LogLevel::WARNING, $message);
- // NOTE: Vielleicht neue class ModuleException hinzufügen
- throw new RuntimeException($message);
- }
-
- $this->uninstall($module);
- $this->internalInstall($module);
- $this->internalInstallDependencies($module, $combinationSatisfyerResult->foundCombination);
- $this->createAutoloadFile();
- }
-
- private function internalInstall(Module $module): void
- {
- // Install Source Files to Shop Root
- $files = $module->getSrcFilePaths();
-
- foreach ($files as $file) {
- $src = $module->getLocalRootPath() . $module->getSrcRootPath() . '/' . $file;
-
- $files = $module->getTemplateFiles($file);
- foreach ($files as $file) {
- $overwrite = false;
- if (!FileInfo::isTemplateFile($file)) {
- $overwrite = true;
- }
-
- $file = ModulePathMapper::moduleSrcToShopRoot($file);
-
- $dest = App::getShopRoot() . $file;
- $this->installFile($src, $dest, $overwrite);
- }
- }
-
- // Install Source Mmlc Files to shop vendor-mmlc
- $files = $module->getSrcMmlcFilePaths();
- foreach ($files as $file) {
- $src = $module->getLocalRootPath() . $module->getSrcMmlcRootPath() . '/' . $file;
- $file = ModulePathMapper::moduleSrcMmlcToShopVendorMmlc($file, $module->getArchiveName());
- $dest = App::getShopRoot() . '/' . $file;
- $this->installFile($src, $dest, true);
- }
-
- $moduleHashFileCreator = new ModuleHashFileCreator();
- $moduleHashFile = $moduleHashFileCreator->createHashFile($module);
- $moduleHashFile->writeTo($module->getHashPath());
- }
-
- private function internalPullAndInstall(Module $module): void
- {
- if (!$module->isLoaded()) {
- $this->pull($module);
- }
-
- $reloaded = $this->reload($module);
-
- if (!$reloaded->isLoaded()) {
- $message =
- "Can not pull and install module {$module->getArchiveName()} {$module->getVersion()}. "
- . "Module is not loaded.";
- StaticLogger::log(LogLevel::WARNING, $message);
- // NOTE: Vielleicht neue class ModuleOperationException hinzufügen
- throw new RuntimeException($message);
- }
-
- if ($reloaded->isInstalled()) {
- return;
- }
-
- $this->uninstall($module);
- $this->internalInstall($module);
- }
-
- private function internalInstallDependencies(Module $parentModule, Combination $combination): void
- {
- $modules = $this->dependencyManager->getAllModulesFromCombination($combination);
-
- foreach ($modules as $module) {
- if ($parentModule->getArchiveName() === $module->getArchiveName()) {
- continue;
- }
- $this->internalPullAndInstall($module);
- }
- }
-
- public function update(Module $module): ?Module
- {
- $installedModule = $module->getInstalledVersion();
- $newModule = $module->getNewestVersion();
-
- $combinationSatisfyerResult = $this->dependencyManager->canBeInstalled($module);
-
- if (!$combinationSatisfyerResult->foundCombination) {
- $message =
- "Can not update module {$module->getArchiveName()} {$module->getVersion()}. "
- . "No possible combination of versions found";
- StaticLogger::log(LogLevel::WARNING, $message);
- // NOTE: Vielleicht neue class ModuleException hinzufügen
- throw new RuntimeException($message);
- }
-
- if ($installedModule) {
- $this->uninstall($installedModule);
- }
-
- $this->pull($newModule);
- $newModule = $this->reload($newModule);
-
- $this->internalInstall($newModule);
- $this->createAutoloadFile();
-
- return $newModule;
- }
-
- public function updateWithDependencies(Module $module): ?Module
- {
- $installedModule = $module->getInstalledVersion();
- $newModule = $module->getNewestVersion();
-
- $combinationSatisfyerResult = $this->dependencyManager->canBeInstalled($module);
-
- if (!$combinationSatisfyerResult->foundCombination) {
- $message =
- "Can not update module {$module->getArchiveName()} {$module->getVersion()} with dependencies. "
- . "No possible combination of versions found";
- StaticLogger::log(LogLevel::WARNING, $message);
- // NOTE: Vielleicht neue class ModuleException hinzufügen
- throw new RuntimeException($message);
- }
-
- if ($installedModule) {
- $this->uninstall($installedModule);
- }
-
- $this->pull($newModule);
- $newModule = $this->reload($newModule);
-
- $this->internalInstall($newModule);
- $this->internalInstallDependencies($newModule, $combinationSatisfyerResult->foundCombination);
- $this->createAutoloadFile();
-
- return $newModule;
- }
-
- private function reload(Module $module): Module
- {
- $this->localModuleLoader->resetCache();
- $reloadedModule = $this->localModuleLoader->loadByArchiveNameAndVersion(
- $module->getArchiveName(),
- $module->getVersion()
- );
-
- if (!$reloadedModule) {
- $message = "Can not reload module {$module->getArchiveName()} {$module->getVersion()}";
- StaticLogger::log(LogLevel::WARNING, $message);
- // NOTE: Vielleicht neue class ModuleException hinzufügen
- throw new RuntimeException($message);
- }
-
- return $reloadedModule;
- }
-
- public function revertChanges(Module $module): void
- {
- if (!$module->isInstalled()) {
- $message =
- "Can not revert changes because {$module->getArchiveName()} {$module->getVersion()} is not installed.";
- StaticLogger::log(LogLevel::WARNING, $message);
- // NOTE: Vielleicht neue class ModuleException hinzufügen
- throw new RuntimeException($message);
- }
-
- $this->internalInstall($module);
- }
-
- private function createAutoloadFile(): void
- {
- $this->localModuleLoader->resetCache();
- $localModules = $this->localModuleLoader->loadAllVersions();
- $installedLocalModules = $this->moduleFilter->filterInstalled($localModules);
-
- $namespaceEntrys = [];
- foreach ($installedLocalModules as $module) {
- $autoload = $module->getAutoload();
-
- if (!$autoload) {
- continue;
- }
-
- if (!$autoload['psr-4']) {
- continue;
- }
-
- foreach ($autoload['psr-4'] as $namespace => $path) {
- $path = str_replace($module->getSourceMmlcDir(), 'vendor-mmlc/' . $module->getArchiveName(), $path);
- $namespaceEntrys[] =
- '$loader->setPsr4(\'' . $namespace . '\\\', DIR_FS_DOCUMENT_ROOT . \'' . $path . '\');';
- }
- }
-
- $namespaceEntrys = array_unique($namespaceEntrys);
- $namespaceMapping = implode("\n", $namespaceEntrys);
-
- $template = \file_get_contents(App::getTemplatesRoot() . '/autoload.php.tmpl');
- $template = \str_replace('{VENDOR_PSR4_NAMESPACE_MAPPINGS}', $namespaceMapping, $template);
-
- if (!file_exists(App::getShopRoot() . '/vendor-no-composer')) {
- mkdir(App::getShopRoot() . '/vendor-no-composer');
- }
- \file_put_contents(App::getShopRoot() . '/vendor-no-composer/autoload.php', $template);
-
- if (!file_exists(App::getShopRoot() . '/vendor-mmlc')) {
- mkdir(App::getShopRoot() . '/vendor-mmlc');
- }
- \file_put_contents(App::getShopRoot() . '/vendor-mmlc/autoload.php', $template);
- }
-
- public function uninstall(Module $module): bool
- {
- $installedModule = $module->getInstalledVersion();
- if (!$installedModule) {
- return false;
- }
-
- if ($installedModule->isChanged()) {
- $message =
- "Can not uninstall module {$installedModule->getArchiveName()} {$installedModule->getVersion()} "
- . "because the module has changes.";
- StaticLogger::log(LogLevel::WARNING, $message);
- // NOTE: Vielleicht neue class ModuleException hinzufügen
- throw new RuntimeException($message);
- }
-
- $this->internalUninstall($installedModule);
- $this->createAutoloadFile();
-
- return true;
- }
-
- private function internalUninstall(Module $module): void
- {
- // Uninstall from shop-root
- $files = $module->getSrcFilePaths();
- foreach ($files as $file) {
- $file = ModulePathMapper::moduleSrcToShopRoot($file);
- $dest = App::getShopRoot() . $file;
- $this->uninstallFile($dest);
- }
-
- // Uninstall from shop-vendor-mmlc
- $files = $module->getSrcMmlcFilePaths();
- foreach ($files as $file) {
- $file = ModulePathMapper::moduleSrcMmlcToShopVendorMmlc($file, $module->getArchiveName());
- $dest = App::getShopRoot() . $file;
- $this->uninstallFile($dest);
- FileHelper::deletePathIsEmpty($dest);
- }
-
- if (file_exists($module->getHashPath())) {
- unlink($module->getHashPath());
- }
- }
-
- private function installFile(string $src, string $dest, bool $overwrite = false): bool
- {
- if (!file_exists($src)) {
- return false;
- }
-
- if ($overwrite == false && (file_exists($dest) || is_link($dest))) {
- return false;
- } elseif ($overwrite == true && (file_exists($dest) || is_link($dest))) {
- unlink($dest);
- }
-
- FileHelper::makeDirIfNotExists($dest);
-
- if (file_exists($dest) || is_link($dest)) {
- return false;
- }
-
- if (Config::getInstallMode() == 'link') {
- symlink($src, $dest);
- } else {
- copy($src, $dest);
- }
-
- return true;
- }
-
- private function uninstallFile(string $dest): void
- {
- if (file_exists($dest)) {
- unlink($dest);
- }
- }
-}
diff --git a/src/Classes/ModuleManager/AutoloadFileCreator.php b/src/Classes/ModuleManager/AutoloadFileCreator.php
new file mode 100644
index 00000000..c0ab1952
--- /dev/null
+++ b/src/Classes/ModuleManager/AutoloadFileCreator.php
@@ -0,0 +1,84 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace RobinTheHood\ModifiedModuleLoaderClient\ModuleManager;
+
+use RobinTheHood\ModifiedModuleLoaderClient\App;
+use RobinTheHood\ModifiedModuleLoaderClient\Loader\LocalModuleLoader;
+
+class AutoloadFileCreator
+{
+ // TODO: In createAutoloadFile() Exceptions werfen im Fehlerfall
+ public function createAutoloadFile(): void
+ {
+ $installedLocalModules = $this->getInstalledModules();
+ $autoloadFileContent = $this->buildAutoloadFile($installedLocalModules);
+ $this->writeAutoloadFile($autoloadFileContent);
+ }
+
+ private function getInstalledModules()
+ {
+ $localModuleLoader = LocalModuleLoader::createFromConfig();
+ $localModuleLoader->resetCache();
+ $installedModules = $localModuleLoader->loadAllInstalledVersions();
+ return $installedModules;
+ }
+
+ private function buildAutoloadFile(array $installedModules): string
+ {
+ $namespaceEntrys = [];
+ foreach ($installedModules as $installedModule) {
+ $autoload = $installedModule->getAutoload();
+
+ if (!$autoload) {
+ continue;
+ }
+
+ if (!$autoload['psr-4']) {
+ continue;
+ }
+
+ foreach ($autoload['psr-4'] as $namespace => $path) {
+ $path = str_replace(
+ $installedModule->getSourceMmlcDir(),
+ 'vendor-mmlc/' . $installedModule->getArchiveName(),
+ $path
+ );
+
+ $namespaceEntrys[] =
+ '$loader->setPsr4(\'' . $namespace . '\\\', DIR_FS_DOCUMENT_ROOT . \'' . $path . '\');';
+ }
+ }
+
+ $namespaceEntrys = array_unique($namespaceEntrys);
+ $namespaceMapping = implode("\n", $namespaceEntrys);
+
+ $template = file_get_contents(App::getTemplatesRoot() . '/autoload.php.tmpl');
+ $autoloadFileContent = str_replace('{VENDOR_PSR4_NAMESPACE_MAPPINGS}', $namespaceMapping, $template);
+
+ return $autoloadFileContent;
+ }
+
+ private function writeAutoloadFile(string $autoloadFileContent): void
+ {
+ if (!file_exists(App::getShopRoot() . '/vendor-no-composer')) {
+ mkdir(App::getShopRoot() . '/vendor-no-composer');
+ }
+ file_put_contents(App::getShopRoot() . '/vendor-no-composer/autoload.php', $autoloadFileContent);
+
+ if (!file_exists(App::getShopRoot() . '/vendor-mmlc')) {
+ mkdir(App::getShopRoot() . '/vendor-mmlc');
+ }
+ file_put_contents(App::getShopRoot() . '/vendor-mmlc/autoload.php', $autoloadFileContent);
+ }
+}
diff --git a/src/Classes/ModuleManager/ModuleFileInstaller.php b/src/Classes/ModuleManager/ModuleFileInstaller.php
new file mode 100644
index 00000000..b19a2ec5
--- /dev/null
+++ b/src/Classes/ModuleManager/ModuleFileInstaller.php
@@ -0,0 +1,187 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace RobinTheHood\ModifiedModuleLoaderClient\ModuleManager;
+
+use RobinTheHood\ModifiedModuleLoaderClient\App;
+use RobinTheHood\ModifiedModuleLoaderClient\Config;
+use RobinTheHood\ModifiedModuleLoaderClient\FileInfo;
+use RobinTheHood\ModifiedModuleLoaderClient\Helpers\FileHelper;
+use RobinTheHood\ModifiedModuleLoaderClient\Module;
+use RobinTheHood\ModifiedModuleLoaderClient\ModuleHasher\ModuleHashFileCreator;
+use RobinTheHood\ModifiedModuleLoaderClient\ModulePathMapper;
+use RuntimeException;
+
+class ModuleFileInstaller
+{
+ /**
+ * (Re-) Installiert / überschreibt ein Modul (archiveName, Version) ohne dabei auf Abhängigkeiten und den
+ * Modulstatus zu achten. Es wird nur auf Dateiebene kontrolliert, ob alle Dateien geschrieben werden konnten.
+ * Erzeugt die modulehash.json. Die Autoload Datei wird NICHT erzeugt / erneuert.
+ */
+ public function install(Module $module, bool $overwriteTemplateFiles = false): void
+ {
+ $this->installFiles($module, $overwriteTemplateFiles);
+ $this->createHashFile($module);
+ }
+
+ /**
+ * Deinstalliert / entfernt ein Modul (archiveName, Version) ohne dabei auf Abhängigkeiten und den Modulstatus zu
+ * achten. Es wird nur auf Dateiebene kontrolliert, ob alles Datien entfernt werden konnten. Die Autoload Datei
+ * wird NICHT aktualisiert.
+ */
+ public function uninstall(Module $module): void
+ {
+ $this->uninstallFiles($module);
+ $this->removeHashFile($module);
+ }
+
+ /**
+ * (Re-) Installiert / Überschreibt nur die Datei zu einem Modul (archiveName, Version). Es wird nur auf Datei-Ebene
+ * kontrolliert, ob alle Dateien geschrieben werden konnten. Die `modulehash.json` Datei wird NICHT erzeugt /
+ * erneuert.
+ */
+ private function installFiles(Module $module, bool $overwriteTemplateFiles): void
+ {
+ // Install Source Files to Shop Root
+ $files = $module->getSrcFilePaths();
+
+ foreach ($files as $file) {
+ $src = $module->getLocalRootPath() . $module->getSrcRootPath() . '/' . $file;
+
+ $expandedFiles = $module->getTemplateFiles($file);
+ foreach ($expandedFiles as $expandedFile) {
+ $overwrite = false;
+
+ if ($overwriteTemplateFiles === true) {
+ $overwrite = true;
+ }
+
+ if (!FileInfo::isTemplateFile($expandedFile)) {
+ $overwrite = true;
+ }
+
+ $expandedFile = ModulePathMapper::moduleSrcToShopRoot($expandedFile);
+
+ $dest = App::getShopRoot() . $expandedFile;
+ $this->installFile($src, $dest, $overwrite);
+ }
+ }
+
+ // Install Source Mmlc Files to shop vendor-mmlc
+ $files = $module->getSrcMmlcFilePaths();
+ foreach ($files as $file) {
+ $src = $module->getLocalRootPath() . $module->getSrcMmlcRootPath() . '/' . $file;
+ $file = ModulePathMapper::moduleSrcMmlcToShopVendorMmlc($file, $module->getArchiveName());
+ $dest = App::getShopRoot() . '/' . $file;
+ $this->installFile($src, $dest, true);
+ }
+ }
+
+ private function installFile(string $src, string $dest, bool $overwrite = false): bool
+ {
+ if (!file_exists($src)) {
+ throw new RuntimeException("Can not install file $src - File not exists.");
+ }
+
+ if ($this->fileOrLinkExists($dest) && $overwrite === false) {
+ // Die Datei existiert bereits und soll NICHT überschrieben werden.
+ return false;
+ } elseif ($this->fileOrLinkExists($dest) && $overwrite === true) {
+ // Die Datei existiert bereits soll überschrieben.
+ // Wir löschen die Datei zuerst, bevor wir sie überschreiben.
+ $this->removeFile($dest);
+ }
+
+ FileHelper::makeDirIfNotExists($dest);
+
+ // TODO: Kontrollieren ob hier eine Exception geworfen werden muss, wenn die Datei existiert.
+ if ($this->fileOrLinkExists($dest)) {
+ return false;
+ }
+
+ $this->copyFile($src, $dest);
+
+ return true;
+ }
+
+ private function copyFile(string $srcPath, string $destPath): void
+ {
+ if (Config::getInstallMode() === 'link') {
+ $result = symlink($srcPath, $destPath);
+ } else {
+ $result = copy($srcPath, $destPath);
+ }
+
+ if (!$result) {
+ throw new RuntimeException("Can not copy file $srcPath to $destPath");
+ }
+ }
+
+ /**
+ * Erzeugt / Überschreibt die `modulehash.json zu einem Modul (archive, Version)` Es wird nur auf Datei-Ebene
+ * kontrolliert, ob alle Dateien geschrieben werden konnten.
+ */
+ private function createHashFile(Module $module): void
+ {
+ $moduleHashFileCreator = new ModuleHashFileCreator();
+ $moduleHashFile = $moduleHashFileCreator->createHashFile($module);
+ $moduleHashFile->writeTo($module->getHashPath());
+ }
+
+ private function uninstallFiles(Module $module): void
+ {
+ // Uninstall from shop-root
+ $files = $module->getSrcFilePaths();
+ foreach ($files as $file) {
+ $file = ModulePathMapper::moduleSrcToShopRoot($file);
+ $dest = App::getShopRoot() . $file;
+ $this->removeIfFileExists($dest);
+ }
+
+ // Uninstall from shop-vendor-mmlc
+ $files = $module->getSrcMmlcFilePaths();
+ foreach ($files as $file) {
+ $file = ModulePathMapper::moduleSrcMmlcToShopVendorMmlc($file, $module->getArchiveName());
+ $dest = App::getShopRoot() . $file;
+ $this->removeIfFileExists($dest);
+ FileHelper::deletePathIsEmpty($dest);
+ }
+ }
+
+ private function fileOrLinkExists(string $path): bool
+ {
+ return file_exists($path) || is_link($path);
+ }
+
+ private function removeIfFileExists(string $path): void
+ {
+ if ($this->fileOrLinkExists($path)) {
+ $this->removeFile($path);
+ }
+ }
+
+ private function removeFile(string $path): void
+ {
+ $result = unlink($path);
+ if (!$result) {
+ throw new RuntimeException("Can not remove file $path");
+ }
+ }
+
+ private function removeHashFile(Module $module): void
+ {
+ $path = $module->getHashPath();
+ $this->removeIfFileExists($path);
+ }
+}
diff --git a/src/Classes/ModuleManager/ModuleInstaller.php b/src/Classes/ModuleManager/ModuleInstaller.php
new file mode 100644
index 00000000..3346d0aa
--- /dev/null
+++ b/src/Classes/ModuleManager/ModuleInstaller.php
@@ -0,0 +1,495 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace RobinTheHood\ModifiedModuleLoaderClient\ModuleManager;
+
+use RuntimeException;
+use RobinTheHood\ModifiedModuleLoaderClient\Config;
+use RobinTheHood\ModifiedModuleLoaderClient\Module;
+use RobinTheHood\ModifiedModuleLoaderClient\Api\V1\ApiRequest;
+use RobinTheHood\ModifiedModuleLoaderClient\Helpers\FileHelper;
+use RobinTheHood\ModifiedModuleLoaderClient\Loader\LocalModuleLoader;
+use RobinTheHood\ModifiedModuleLoaderClient\Archive\ArchivePuller;
+use RobinTheHood\ModifiedModuleLoaderClient\Archive\ArchiveHandler;
+use RobinTheHood\ModifiedModuleLoaderClient\DependencyManager\Combination;
+use RobinTheHood\ModifiedModuleLoaderClient\DependencyManager\DependencyManager;
+
+class ModuleInstaller
+{
+ /** @var DependencyManager */
+ private $dependencyManager;
+
+ /** @var LocalModuleLoader */
+ private $localModuleLoader;
+
+ /** @var ArchivePuller */
+ private $archivePuller;
+
+ /** @var ArchiveHandler */
+ private $archiveHandler;
+
+ public static function create(int $mode): ModuleInstaller
+ {
+ $dependencyManager = DependencyManager::create($mode);
+ $localModuleLoader = LocalModuleLoader::create($mode);
+ $archivePuller = ArchivePuller::create();
+ $archiveHandler = ArchiveHandler::create($mode);
+ $moduleInstaller = new ModuleInstaller(
+ $dependencyManager,
+ $localModuleLoader,
+ $archivePuller,
+ $archiveHandler
+ );
+ return $moduleInstaller;
+ }
+
+ public static function createFromConfig(): ModuleInstaller
+ {
+ return self::create(Config::getDependenyMode());
+ }
+
+ public function __construct(
+ DependencyManager $dependencyManager,
+ LocalModuleLoader $localModuleLoader,
+ ArchivePuller $archivePuller,
+ ArchiveHandler $archiveHandler
+ ) {
+ $this->dependencyManager = $dependencyManager;
+ $this->localModuleLoader = $localModuleLoader;
+ $this->archivePuller = $archivePuller;
+ $this->archiveHandler = $archiveHandler;
+ }
+
+ /**
+ * Downloads and prepares a module for installation.
+ *
+ * This method is responsible for downloading a module's archive, extracting its contents, and preparing it for
+ * installation. It performs several checks to ensure the module is not already loaded and retrieves the archive URL
+ * using the specified Module object. Upon successful execution, the method returns the Module instance representing
+ * the downloaded and prepared module.
+ *
+ * @param Module $module The Module to be pulled and prepared for installation.
+ *
+ * @return Module The Module instance representing the downloaded and prepared module.
+ *
+ * @throws RuntimeException
+ * If the module is already loaded or if any errors occur during the download, extraction, or preparation
+ * process, a RuntimeException is thrown with a detailed error message.
+ */
+ public function pull(Module $module): Module
+ {
+ $moduleText = "module {$module->getArchiveName()} {$module->getVersion()}";
+
+ if ($module->isLoaded()) {
+ $this->error("Can not pull $moduleText. Modul is already loaded.");
+ }
+
+ // Retrieve the module's archive URL
+ $archiveUrl = $this->getArchiveUrl($module);
+
+ // Download and extract the module's archive
+ $archive = $this->archivePuller->pull($module->getArchiveName(), $module->getVersion(), $archiveUrl);
+ $this->archiveHandler->extract($archive);
+
+ // Reload and return the Module instance
+ $pulledModule = $this->reload($module);
+ return $pulledModule;
+ }
+
+ /**
+ * Deletes a loaded module's files.
+ *
+ * This method is responsible for deleting the files associated with a loaded module. It checks whether the module
+ * is loaded and, if required, verifies whether it's uninstalled before proceeding with the deletion. If the 'force'
+ * parameter is set to true, the method will skip the installation check and forcefully delete the module. It then
+ * calls the 'deleteModuleFiles' method to remove the module's files from the system.
+ *
+ * @param Module $module The loaded module to be deleted.
+ * @param bool $force Set to true to force the deletion even if the module is installed.
+ *
+ * @throws RuntimeException
+ * If the module is not loaded or is installed (and 'force' is false), a RuntimeException is thrown with a
+ * detailed error message. Any errors encountered during the deletion process are also reported via exceptions.
+ */
+ public function delete(Module $module, bool $force = false): void
+ {
+ $moduleText = "module {$module->getArchiveName()} {$module->getVersion()}";
+
+ if (!$module->isLoaded()) {
+ $this->error("Can not delete $moduleText. Module is not loaded.");
+ }
+
+ if (!$force && $module->isInstalled()) {
+ $this->error("Can not delete $moduleText. Module is installed.");
+ }
+
+ $this->deleteModuleFiles($module);
+ }
+
+ /**
+ * Installs a module and its dependencies.
+ *
+ * This method is responsible for installing a module along with its dependencies into the shop system. It checks
+ * whether the module is already installed (unless 'force' is set to true) and ensures that a valid combination of
+ * versions for the module's dependencies can be found. If the installation is successful, it proceeds to install
+ * its dependencies. The method offers the flexibility to force the installation of the module even if it's already
+ * installed and skip the dependency check. Any errors encountered during the installation process are reported via
+ * exceptions.
+ *
+ * @param Module $module The module to be installed.
+ * @param bool $force Set to true to force the installation even if the module is already installed.
+ *
+ * @throws RuntimeException
+ * If the module is already installed (and 'force' is false) or if no valid combination of versions for the
+ * dependencies can be found, a RuntimeException is thrown with detailed error messages. Any other errors
+ * during the installation process are also reported via exceptions.
+ */
+ public function install(Module $module, bool $force = false): void
+ {
+ $moduleText = "module {$module->getArchiveName()} {$module->getVersion()}";
+
+ $installedModule = $module->getInstalledVersion();
+ if (!$force && $installedModule) {
+ $installedModuleText = "module {$installedModule->getArchiveName()} {$installedModule->getVersion()}";
+ $this->error("Can not install $moduleText, because $installedModuleText is already installed.");
+ }
+
+ $combinationSatisfyerResult = $this->dependencyManager->canBeInstalled($module);
+
+ if (!$combinationSatisfyerResult->foundCombination) {
+ $this->error("Can not install $moduleText with dependencies. No possible combination of versions found");
+ }
+
+ $this->installWithoutDependencies($module, true, true);
+ $this->installDependencies($module, $combinationSatisfyerResult->foundCombination);
+ }
+
+ /**
+ * Install a module without installing its dependencies.
+ *
+ * This method is responsible for installing a module into the shop system without installing its dependencies. It
+ * checks whether the module is already installed (unless 'force' is set to true) and optionally performs a
+ * dependency check to ensure that a valid combination of versions for the module can be found (unless
+ * 'skipDependencyCheck' is set to true). Any errors during the installation process are reported via exceptions.
+ *
+ * @param Module $module
+ * The module to be installed.
+ * @param bool $skipDependencyCheck
+ * 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,
+ bool $skipDependencyCheck = false,
+ bool $force = false
+ ): void {
+ $moduleText = "module {$module->getArchiveName()} {$module->getVersion()}";
+
+ if (!$force && $module->isInstalled()) {
+ $this->error("Can not install $moduleText. Module is already installed.");
+ }
+
+ if (!$skipDependencyCheck) {
+ $combinationSatisfyerResult = $this->dependencyManager->canBeInstalled($module);
+
+ if (!$combinationSatisfyerResult->foundCombination) {
+ $this->error("Can not update $moduleText. No possible combination of versions found");
+ }
+ }
+
+ $moduleFileInstaller = new ModuleFileInstaller();
+ $moduleFileInstaller->install($module);
+ $this->reload($module);
+ }
+
+ /**
+ * Update a module to its newest version while potentially updating its dependencies.
+ *
+ * This method is responsible for updating a module to its newest version. It verifies whether the module is
+ * installed (unless 'force' is set to true) and ensures that a valid combination of versions for the module's
+ * dependencies can be found. The newest version is pulled and installed, and its dependencies are also installed as
+ * necessary. Any errors during the update process are reported via exceptions, and the loaded new module is
+ * returned.
+ *
+ * @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
+ {
+ $moduleText = "module {$installedModule->getArchiveName()} {$installedModule->getVersion()}";
+
+ if (!$force && !$installedModule->isInstalled()) {
+ $this->error("Can not update $moduleText. Module is not installed.");
+ }
+
+ $moduleText = "module {$installedModule->getArchiveName()} {$installedModule->getVersion()}";
+ $newModuleText = "module {$newModule->getArchiveName()} {$newModule->getVersion()}";
+
+ if ($installedModule->getVersion() === $newModule->getVersion()) {
+ $this->error("Can not update $moduleText to $newModuleText.");
+ }
+
+ $combinationSatisfyerResult = $this->dependencyManager->canBeInstalled($newModule);
+ $foundCombination = $combinationSatisfyerResult->foundCombination;
+
+ if (!$foundCombination) {
+ $this->error(
+ "Can not update $moduleText to $newModuleText."
+ . " No possible combination of versions found"
+ );
+ }
+
+ if ($newModule->isLoaded()) {
+ $loadedNewModule = $newModule;
+ } else {
+ $loadedNewModule = $this->pull($newModule);
+ }
+
+ $this->uninstall($installedModule);
+ // Modul installieren
+ $this->installWithoutDependencies($loadedNewModule);
+ // Modul Abhängigkeiten installieren
+ $this->installDependencies($loadedNewModule, $foundCombination);
+ }
+
+ /**
+ * //TODO: Nicht zur Neusten sondern zu höchst möglichsten Version aktualisieren.
+ */
+ public function updateWithoutMissingDependencies(
+ Module $instaledModule,
+ Module $newModule,
+ bool $skipDependencyCheck = false,
+ bool $force = false
+ ): Module {
+ $moduleText = "module {$instaledModule->getArchiveName()} {$instaledModule->getVersion()}";
+
+ if (!$force && !$instaledModule->isInstalled()) {
+ $this->error("Can not update $moduleText. Module is not installed.");
+ }
+
+ $moduleText = "module {$instaledModule->getArchiveName()} {$instaledModule->getVersion()}";
+ $newModuleText = "module {$newModule->getArchiveName()} {$newModule->getVersion()}";
+
+ if (!$skipDependencyCheck) {
+ $combinationSatisfyerResult = $this->dependencyManager->canBeInstalled($newModule);
+
+ if (!$combinationSatisfyerResult->foundCombination) {
+ $this->error(
+ "Can not update $moduleText to $newModuleText."
+ . " No possible combination of versions found"
+ );
+ }
+ }
+
+ if ($newModule->isLoaded()) {
+ $loadedNewModule = $newModule;
+ } else {
+ $loadedNewModule = $this->pull($newModule);
+ }
+
+ $this->uninstall($instaledModule);
+ $this->installWithoutDependencies($loadedNewModule);
+
+ return $loadedNewModule;
+ }
+
+ public function discard(Module $module, bool $withTemplate, bool $force): void
+ {
+ $moduleText = "module {$module->getArchiveName()} {$module->getVersion()}";
+
+ if (!$force && !$module->isInstalled()) {
+ $this->error("Can not revert changes because $moduleText is not installed.");
+ }
+
+ $moduleFileInstaller = new ModuleFileInstaller();
+ $moduleFileInstaller->install($module, $withTemplate);
+ }
+
+ public function uninstall(Module $module, bool $force = false): void
+ {
+ $moduleText = "module {$module->getArchiveName()}";
+
+ if (!$module->isInstalled()) {
+ $this->error("Can not uninstall $moduleText because module is not installed.");
+ }
+
+ $moduleText = "module {$module->getArchiveName()} {$module->getVersion()}";
+
+
+ if ($module->isChanged() && $force === false) {
+ $this->error("Can not uninstall $moduleText because the module has changes.");
+ }
+
+ $moduleFileInstaller = new ModuleFileInstaller();
+ $moduleFileInstaller->uninstall($module);
+
+ $this->reload($module);
+ }
+
+ /**
+ * Installs the dependencies specified in the given Combination for a parent Module.
+ *
+ * This method is used internally to install the dependencies specified in a provided Combination for a parent
+ * Module. It retrieves the required modules from the Combination and iterates through them, checking for
+ * compatibility and installing each one. The parent Module is excluded from the installation process.
+ *
+ * @param Module $parentModule The parent Module for which dependencies need to be installed.
+ * @param Combination $combination The Combination specifying the dependencies to be installed.
+ *
+ * @throws \RobinTheHood\ModifiedModuleLoaderClient\DependencyManager\DependencyException
+ * If any of the dependencies cannot be installed due to conflicting versions or other issues,
+ * a DependencyException may be thrown with details.
+ */
+ private function installDependencies(Module $parentModule, Combination $combination): void
+ {
+ $modules = $this->dependencyManager->getAllModulesFromCombination($combination);
+
+ foreach ($modules as $module) {
+ if ($parentModule->getArchiveName() === $module->getArchiveName()) {
+ continue;
+ }
+ $this->pullAndInstallWithoutDependencies($module);
+ }
+ }
+
+ /**
+ * Loads and installs a module.
+ *
+ * This method is responsible for loading and installing a module specified by the provided Module object. It checks
+ * whether the module is already installed, and if not, it attempts to load and install it. The method also handles
+ * potential errors during the loading and installation process.
+ *
+ * @param Module $module The Module to be loaded and installed.
+ *
+ * @throws RuntimeException
+ * If the module cannot be loaded or installed successfully, a RuntimeException is thrown with a detailed
+ * error message.
+ */
+ private function pullAndInstallWithoutDependencies(Module $module): void
+ {
+ if ($module->isInstalled()) {
+ return;
+ }
+
+ if ($module->isLoaded()) {
+ $pulledModule = $module;
+ } else {
+ $pulledModule = $this->pull($module);
+ }
+
+ $this->installWithoutDependencies($pulledModule);
+ }
+
+ /**
+ * Retrieves the archive URL for a given module.
+ *
+ * This method is responsible for obtaining the archive URL for a specific module by making an API request. It
+ * constructs the URL to download the module's archive, handles potential errors in the API response, and returns
+ * the archive URL.
+ *
+ * @param Module $module The Module for which the archive URL should be retrieved.
+ *
+ * @return string The URL to download the module's archive.
+ *
+ * @throws \Exception
+ * If the API response is empty or lacks the necessary information to construct the archive URL, an Exception
+ * is thrown with a detailed error message.
+ */
+ private function getArchiveUrl(Module $module): string
+ {
+ $moduleText = "module {$module->getArchiveName()} {$module->getVersion()}";
+
+ $apiRequest = new ApiRequest();
+ $result = $apiRequest->getArchive($module->getArchiveName(), $module->getVersion());
+
+ $content = $result['content'] ?? [];
+ if (!$content) {
+ $this->error("Can not pull $moduleText. ApiRespond is empty.");
+ }
+
+ $archiveUrl = $content['archiveUrl'] ?? '';
+ if (!$archiveUrl) {
+ $this->error("Can not pull $moduleText. archiveUrl is empty.");
+ }
+
+ return $archiveUrl;
+ }
+
+ /**
+ * Löscht alle Module Dateien aus dem Verzeichnis Modules. Es wird nicht kontrolliert ob das Modul geladen oder
+ * installiert ist.
+ */
+ private function deleteModuleFiles(Module $module): void
+ {
+ $path = $module->getLocalRootPath() . $module->getModulePath();
+
+ $filePaths = FileHelper::scanDirRecursive($path, FileHelper::FILES_ONLY);
+
+ $dirPaths = FileHelper::scanDirRecursive($path, FileHelper::DIRS_ONLY);
+ $dirPaths = array_reverse($dirPaths);
+ $dirPaths[] = $path;
+ $dirPaths[] = dirname($path);
+
+ // Delete Files
+ foreach ($filePaths as $path) {
+ if (file_exists($path)) {
+ unlink($path);
+ }
+ }
+
+ // Delete Folders
+ foreach ($dirPaths as $path) {
+ if (file_exists($path)) {
+ @rmdir($path);
+ }
+ }
+ }
+
+ private function reload(Module $module): Module
+ {
+ $moduleText = "module {$module->getArchiveName()} {$module->getVersion()}";
+
+ $this->localModuleLoader->resetCache();
+ $reloadedModule = $this->localModuleLoader->loadByArchiveNameAndVersion(
+ $module->getArchiveName(),
+ $module->getVersion()
+ );
+
+ if (!$reloadedModule) {
+ $this->error("Can not reload $moduleText.");
+ }
+
+ return $reloadedModule;
+ }
+
+ /**
+ * // NOTE: Vielleicht neue class ModuleInstallerException hinzufügen
+ * @return never
+ */
+ private function error(string $message): void
+ {
+ // StaticLogger::log(LogLevel::WARNING, $message);
+ throw new RuntimeException($message);
+ }
+}
diff --git a/src/Classes/ModuleManager/ModuleManager.php b/src/Classes/ModuleManager/ModuleManager.php
new file mode 100644
index 00000000..f6557ced
--- /dev/null
+++ b/src/Classes/ModuleManager/ModuleManager.php
@@ -0,0 +1,519 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace RobinTheHood\ModifiedModuleLoaderClient\ModuleManager;
+
+use RobinTheHood\ModifiedModuleLoaderClient\Config;
+use RobinTheHood\ModifiedModuleLoaderClient\DependencyManager\CombinationSatisfyerResult;
+use RobinTheHood\ModifiedModuleLoaderClient\DependencyManager\DependencyBuilder;
+use RobinTheHood\ModifiedModuleLoaderClient\DependencyManager\SystemSetFactory;
+use RobinTheHood\ModifiedModuleLoaderClient\Loader\LocalModuleLoader;
+use RobinTheHood\ModifiedModuleLoaderClient\Loader\ModuleLoader;
+
+class ModuleManager
+{
+ /** @var ModuleInstaller */
+ private $moduleInstaller;
+
+ /** @var ModuleLoader */
+ private $moduleLoader;
+
+ /** @var LocalModuleLoader */
+ private $localModuleLoader;
+
+ /** @var DependencyBuilder */
+ private $dependencyBuilder;
+
+ /** @var SystemSetFactory */
+ private $systemSetFactory;
+
+ /** @var ModuleManagerLoggerInterface */
+ private $logger;
+
+ public static function create(int $mode): ModuleManager
+ {
+ $moduleInstaller = ModuleInstaller::create($mode);
+ $moduleLoader = ModuleLoader::create($mode);
+ $localModuleLoader = LocalModuleLoader::create($mode);
+ $dependencyBuilder = DependencyBuilder::create($mode);
+ $systemSetFactory = SystemSetFactory::create($mode);
+
+ $moduleInstaller = new ModuleManager(
+ $moduleInstaller,
+ $moduleLoader,
+ $localModuleLoader,
+ $dependencyBuilder,
+ $systemSetFactory
+ );
+
+ return $moduleInstaller;
+ }
+
+ public static function createFromConfig(): ModuleManager
+ {
+ return self::create(Config::getDependenyMode());
+ }
+
+ public function __construct(
+ ModuleInstaller $moduleInstaller,
+ ModuleLoader $moduleLoader,
+ LocalModuleLoader $localModuleLoader,
+ DependencyBuilder $dependencyBuilder,
+ SystemSetFactory $systemSetFactory
+ ) {
+ $this->moduleInstaller = $moduleInstaller;
+ $this->moduleLoader = $moduleLoader;
+ $this->localModuleLoader = $localModuleLoader;
+ $this->dependencyBuilder = $dependencyBuilder;
+ $this->systemSetFactory = $systemSetFactory;
+
+ $this->logger = new ModuleManagerNullLogger();
+ }
+
+ public function setLogger(ModuleManagerLoggerInterface $logger): void
+ {
+ $this->logger = $logger;
+ }
+
+ private function error(ModuleManagerMessage $message): ModuleManagerResult
+ {
+ $this->logger->error($message);
+ return ModuleManagerResult::error($message);
+ }
+
+ private function info(ModuleManagerMessage $message): void
+ {
+ $this->logger->info($message);
+ }
+
+ /**
+ * Lädt ein Modul vom Server herunter.
+ */
+ public function pull(string $archiveName, string $versionConstraint): ModuleManagerResult
+ {
+ if ($versionConstraint) {
+ $module = $this->moduleLoader->loadLatestByArchiveNameAndConstraint($archiveName, $versionConstraint);
+ } else {
+ $module = $this->moduleLoader->loadLatestVersionByArchiveName($archiveName);
+ }
+
+ if (!$module) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::PULL_ERROR_MODULE_NOT_FOUND)
+ ->setArchiveName($archiveName)
+ ->setVersionConstraint($versionConstraint)
+ );
+ }
+
+ if ($module->isLoaded()) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::PULL_ERROR_MODULE_ALLREADY_LOADED)
+ ->setArchiveName($archiveName)
+ ->setVersionConstraint($versionConstraint)
+ );
+ }
+
+ $this->info(
+ ModuleManagerMessage::create(ModuleManagerMessage::PULL_INFO_START)
+ ->setModule($module)
+ );
+
+ $module = $this->moduleInstaller->pull($module);
+ return ModuleManagerResult::success()
+ ->setModule($module);
+ }
+
+ /**
+ * Löscht ein Modul das bereits heruntergeladen wurde.
+ */
+ public function delete(string $archiveName, string $version): ModuleManagerResult
+ {
+ $module = $this->localModuleLoader->loadByArchiveNameAndVersion($archiveName, $version);
+
+ if (!$module) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::DELETE_ERROR_MODULE_NOT_FOUND)
+ ->setArchiveName($archiveName)
+ ->setVersion($version)
+ );
+ }
+
+ if ($module->isInstalled()) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::DELETE_ERROR_MODULE_IS_INSTALED)
+ ->setModule($module)
+ );
+ }
+
+ $this->info(
+ ModuleManagerMessage::create(ModuleManagerMessage::DELETE_INFO_START)
+ ->setModule($module)
+ );
+
+ $this->moduleInstaller->delete($module, false);
+ return ModuleManagerResult::success();
+ }
+
+ /**
+ * Lädt und installiert ein Modul in das Shop System UND lädt und installiert alle Abhängigkeiten bzw.
+ * abhängige Module nach.
+ */
+ public function install(string $archiveName, $versionConstraint): ModuleManagerResult
+ {
+ $moduleLoader = ModuleLoader::createFromConfig();
+ $module = $moduleLoader->loadLatestByArchiveNameAndConstraint($archiveName, $versionConstraint);
+
+ if (!$module) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::INSTALL_ERROR_MODULE_NOT_FOUND)
+ ->setArchiveName($archiveName)
+ ->setVersionConstraint($versionConstraint)
+ );
+ }
+
+ $systemSet = $this->systemSetFactory->getSystemSet();
+
+ $combinationSatisfyerResult = $this->dependencyBuilder->satisfies($archiveName, $versionConstraint, $systemSet);
+ if (
+ $combinationSatisfyerResult->result === CombinationSatisfyerResult::RESULT_COMBINATION_NOT_FOUND
+ || !$combinationSatisfyerResult->foundCombination
+ ) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::INSTALL_ERROR_MODULE_MISSING_REQUIREMENTS)
+ ->setArchiveName($archiveName)
+ ->setVersionConstraint($versionConstraint)
+ ->setCombinationSatisfyerResult($combinationSatisfyerResult)
+ );
+ }
+
+ $version = $combinationSatisfyerResult->foundCombination->getVersion($archiveName);
+
+ $module = $this->moduleLoader->loadByArchiveNameAndVersion($archiveName, $version);
+
+ if (!$module) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::INSTALL_ERROR_MODULE_NOT_FOUND)
+ ->setArchiveName($archiveName)
+ ->setVersionConstraint($versionConstraint)
+ );
+ }
+
+ if ($module->isInstalled()) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::INSTALL_ERROR_MODULE_ALLREADY_INSTALED)
+ ->setModule($module)
+ );
+ }
+
+ if (!$module->isLoaded()) {
+ $this->info(
+ ModuleManagerMessage::create(ModuleManagerMessage::INSTALL_INFO_PULL_MODULE_START)
+ ->setModule($module)
+ );
+ $module = $this->moduleInstaller->pull($module);
+ }
+
+ $this->info(
+ ModuleManagerMessage::create(ModuleManagerMessage::INSTALL_INFO_START)
+ ->setModule($module)
+ );
+ $this->moduleInstaller->install($module);
+
+ $this->info(
+ ModuleManagerMessage::create(ModuleManagerMessage::INSTALL_INFO_UPDATE_AUTOLOAD_START)
+ );
+ $autoloadFileCreator = new AutoloadFileCreator();
+ $autoloadFileCreator->createAutoloadFile();
+
+ return ModuleManagerResult::success()
+ ->setModule($module);
+ }
+
+ /**
+ * Installiert ein Modul in das Shop System ABER lädt und installiert KEINE Abhängigkeiten / abhängige Module nach.
+ *
+ * @param bool $skipDependencyCheck skip dependency check.
+ */
+ public function installWithoutDependencies(
+ string $archiveName,
+ string $versionConstraint,
+ bool $skipDependencyCheck = false
+ ): ModuleManagerResult {
+ $moduleLoader = ModuleLoader::createFromConfig();
+ $module = $moduleLoader->loadLatestByArchiveNameAndConstraint($archiveName, $versionConstraint);
+
+ if (!$module) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::INSTALL_ERROR_MODULE_NOT_FOUND)
+ ->setArchiveName($archiveName)
+ ->setVersionConstraint($versionConstraint)
+ );
+ }
+
+ if ($skipDependencyCheck === false) {
+ $systemSet = $this->systemSetFactory->getSystemSet();
+
+ $combinationSatisfyerResult
+ = $this->dependencyBuilder->satisfies($archiveName, $versionConstraint, $systemSet);
+ if (
+ $combinationSatisfyerResult->result === CombinationSatisfyerResult::RESULT_COMBINATION_NOT_FOUND
+ || !$combinationSatisfyerResult->foundCombination
+ ) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::INSTALL_ERROR_MODULE_MISSING_REQUIREMENTS)
+ ->setArchiveName($archiveName)
+ ->setVersionConstraint($versionConstraint)
+ ->setCombinationSatisfyerResult($combinationSatisfyerResult)
+ );
+ }
+
+ $version = $combinationSatisfyerResult->foundCombination->getVersion($archiveName);
+
+ $module = $this->moduleLoader->loadByArchiveNameAndVersion($archiveName, $version);
+
+ if (!$module) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::INSTALL_ERROR_MODULE_NOT_FOUND)
+ ->setArchiveName($archiveName)
+ ->setVersionConstraint($versionConstraint)
+ );
+ }
+ }
+
+ if ($module->isInstalled()) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::INSTALL_ERROR_MODULE_ALLREADY_INSTALED)
+ ->setModule($module)
+ );
+ }
+
+ if (!$module->isLoaded()) {
+ $this->info(
+ ModuleManagerMessage::create(ModuleManagerMessage::INSTALL_INFO_PULL_MODULE_START)
+ ->setModule($module)
+ );
+ $module = $this->moduleInstaller->pull($module);
+ }
+
+ $this->info(
+ ModuleManagerMessage::create(ModuleManagerMessage::INSTALL_INFO_START)
+ ->setModule($module)
+ );
+ $this->moduleInstaller->installWithoutDependencies($module, true, true);
+
+ $this->info(
+ ModuleManagerMessage::create(ModuleManagerMessage::INSTALL_INFO_UPDATE_AUTOLOAD_START)
+ );
+ $autoloadFileCreator = new AutoloadFileCreator();
+ $autoloadFileCreator->createAutoloadFile();
+
+ return ModuleManagerResult::success()
+ ->setModule($module);
+ }
+
+ /**
+ * Aktuallisiert das Modul auf die neuste 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.
+ */
+ public function update(string $archiveName): 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)
+ );
+ }
+
+ $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);
+
+ 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->update($module, $newModule, false);
+
+ $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);
+ }
+
+ /**
+ * Aktualiseirt NUR das Modul auf die neuste 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.
+ */
+ // public function updateWithoutMissingDependencies(string $archvieName, bool $skipDependencyCheck = false): Module
+ // {
+ // $loadedNewModul = $this->moduleInstaller->updateWithoutMissingDependencies(
+ // $module,
+ // $skipDependencyCheck,
+ // false
+ // );
+
+ // $autoloadFileCreator = new AutoloadFileCreator();
+ // $autoloadFileCreator->createAutoloadFile();
+
+ // return $loadedNewModul;
+ // }
+
+ /**
+ * Entfernt alle Änderungen die an den Modul-Dateien im Shop gemacht wurden. Änderungen an Template Dateien werden
+ * nicht rückgängig gemacht.
+ */
+ public function discard(string $archiveName, bool $withTemplate = false): ModuleManagerResult
+ {
+ $moduleLoader = LocalModuleLoader::createFromConfig();
+ $module = $moduleLoader->loadInstalledVersionByArchiveName($archiveName);
+
+ if (!$module) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::DISCARD_ERROR_MODULE_NOT_FOUND)
+ ->setArchiveName($archiveName)
+ );
+ }
+
+ if (!$module->isChanged()) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::DISCARD_ERROR_MODULE_NOT_CHANGED)
+ ->setModule($module)
+ );
+ }
+
+ $this->info(
+ ModuleManagerMessage::create(ModuleManagerMessage::DISCARD_INFO_START)
+ ->setModule($module)
+ );
+
+ $this->moduleInstaller->discard($module, $withTemplate, false);
+ return ModuleManagerResult::success()
+ ->setModule($module);
+ }
+
+ /**
+ * Deinstalliert nur das Modul, wenn es installiert und nicht mehr als abhänigkeit von einem anderen Modul benötigt
+ * wird. Es werden keine Abhängigkeiten deinstalliert.
+ *
+ * Mit der force Option, kann der Abhängigkeits check übersprungen werden und das Modul wird trozdem deinstalliert.
+ * Das kann aber zur folge haben, dass andere Module nicht mehr funktionieren.
+ */
+ public function uninstall(string $archiveName, bool $force = false): ModuleManagerResult
+ {
+ $moduleLoader = LocalModuleLoader::createFromConfig();
+ $module = $moduleLoader->loadInstalledVersionByArchiveName($archiveName);
+
+ if (!$module) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::UNINSTALL_ERROR_MODULE_NOT_FOUND)
+ ->setArchiveName($archiveName)
+ );
+ }
+
+ if (!$module->isInstalled()) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::UNINSTALL_ERROR_MODULE_NOT_INSTALLED)
+ ->setModule($module)
+ );
+ }
+
+ if ($module->isChanged() && $force === false) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::UNINSTALL_ERROR_MODULE_IS_CHANGED)
+ ->setModule($module)
+ );
+ }
+
+ if ($module->getUsedBy() && $force === false) {
+ return $this->error(
+ ModuleManagerMessage::create(ModuleManagerMessage::UNINSTALL_ERROR_MODULE_IS_USED_BY)
+ ->setModule($module)
+ );
+ }
+
+ $this->info(
+ ModuleManagerMessage::create(ModuleManagerMessage::UNINSTALL_INFO_START)
+ ->setModule($module)
+ );
+
+ $this->moduleInstaller->uninstall($module, $force);
+
+ $this->info(
+ ModuleManagerMessage::create(ModuleManagerMessage::UNINSTALL_INFO_UPDATE_AUTOLOAD_START)
+ );
+ $autoloadFileCreator = new AutoloadFileCreator();
+ $autoloadFileCreator->createAutoloadFile();
+
+ return ModuleManagerResult::success()
+ ->setModule($module);
+ }
+}
diff --git a/src/Classes/ModuleManager/ModuleManagerLog.php b/src/Classes/ModuleManager/ModuleManagerLog.php
new file mode 100644
index 00000000..af5124cb
--- /dev/null
+++ b/src/Classes/ModuleManager/ModuleManagerLog.php
@@ -0,0 +1,47 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace RobinTheHood\ModifiedModuleLoaderClient\ModuleManager;
+
+use RobinTheHood\ModifiedModuleLoaderClient\Module;
+
+class ModuleManagerLog
+{
+ /** @var callable */
+ private $writeFunction;
+
+ /** @var callable */
+ private $errorFunction;
+
+ public function setWriteFunction(callable $writeFunction)
+ {
+ $this->writeFunction = $writeFunction;
+ }
+
+ public function setErrorFunction(callable $errorFunction)
+ {
+ $this->errorFunction = $errorFunction;
+ }
+
+ public function write(string $message, $data1 = null, $data2 = null): void
+ {
+ $function = $this->writeFunction;
+ $function($message, $data1, $data2);
+ }
+
+ public function error(int $errorNo, string $message, $data1 = null, $data2 = null): void
+ {
+ $function = $this->errorFunction;
+ $function($errorNo, $message, $data1, $data2);
+ }
+}
diff --git a/src/Classes/ModuleManager/ModuleManagerLoggerInterface.php b/src/Classes/ModuleManager/ModuleManagerLoggerInterface.php
new file mode 100644
index 00000000..e34bc356
--- /dev/null
+++ b/src/Classes/ModuleManager/ModuleManagerLoggerInterface.php
@@ -0,0 +1,23 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace RobinTheHood\ModifiedModuleLoaderClient\ModuleManager;
+
+interface ModuleManagerLoggerInterface
+{
+ public function debug(ModuleManagerMessage $message): void;
+ public function info(ModuleManagerMessage $message): void;
+ public function notice(ModuleManagerMessage $message): void;
+ public function warning(ModuleManagerMessage $message): void;
+ public function error(ModuleManagerMessage $message): void;
+}
diff --git a/src/Classes/ModuleManager/ModuleManagerMessage.php b/src/Classes/ModuleManager/ModuleManagerMessage.php
new file mode 100644
index 00000000..fd718a21
--- /dev/null
+++ b/src/Classes/ModuleManager/ModuleManagerMessage.php
@@ -0,0 +1,232 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace RobinTheHood\ModifiedModuleLoaderClient\ModuleManager;
+
+use RobinTheHood\ModifiedModuleLoaderClient\DependencyManager\CombinationSatisfyerResult;
+use RobinTheHood\ModifiedModuleLoaderClient\Module;
+
+class ModuleManagerMessage
+{
+ public const PULL_INFO_START = 100;
+ public const PULL_ERROR_MODULE_NOT_FOUND = 151;
+ public const PULL_ERROR_MODULE_ALLREADY_LOADED = 152;
+
+ public const DELETE_INFO_START = 200;
+ public const DELETE_ERROR_MODULE_NOT_FOUND = 251;
+ public const DELETE_ERROR_MODULE_IS_INSTALED = 252;
+
+ public const INSTALL_INFO_START = 300;
+ public const INSTALL_INFO_PULL_MODULE_START = 301;
+ public const INSTALL_INFO_UPDATE_AUTOLOAD_START = 302;
+ public const INSTALL_ERROR_MODULE_NOT_FOUND = 351;
+ public const INSTALL_ERROR_MODULE_MISSING_REQUIREMENTS = 352;
+ public const INSTALL_ERROR_MODULE_ALLREADY_INSTALED = 353;
+
+ public const UPDATE_INFO_START = 400;
+ public const UDPATE_INFO_PULL_MODULE_START = 401;
+ public const UPDATE_INFO_UPDATE_AUTOLOAD_START = 402;
+ public const UPDATE_INFO_TO = 403;
+ public const UPDATE_ERROR_MODULE_NOT_FOUND = 451;
+ public const UPDATE_ERROR_MODULE_NOT_INSTALLED = 452;
+ public const UPDATE_ERROR_MODULE_MISSING_REQUIREMENTS = 453;
+ public const UPDATE_ERROR_MODULE_IS_CHANGED = 454;
+
+ public const DISCARD_INFO_START = 500;
+ public const DISCARD_ERROR_MODULE_NOT_FOUND = 551;
+ public const DISCARD_ERROR_MODULE_NOT_CHANGED = 552;
+
+ public const UNINSTALL_INFO_START = 600;
+ public const UNINSTALL_INFO_UPDATE_AUTOLOAD_START = 601;
+ public const UNINSTALL_ERROR_MODULE_NOT_FOUND = 651;
+ public const UNINSTALL_ERROR_MODULE_NOT_INSTALLED = 652;
+ public const UNINSTALL_ERROR_MODULE_IS_CHANGED = 653;
+ public const UNINSTALL_ERROR_MODULE_IS_USED_BY = 654;
+
+ /** @var int */
+ private $code = 0;
+
+ /** @var string */
+ private $message = '';
+
+ /** @var string */
+ private $archiveName = '';
+
+ /** @var string */
+ private $version = '';
+
+ /** @var string */
+ private $versionContraint = '';
+
+ /** @var Module */
+ private $module;
+
+ /** @var CombinationSatisfyerResult */
+ private $combinationSatisfyerResult;
+
+ public static function create(int $code): ModuleManagerMessage
+ {
+ return new ModuleManagerMessage($code);
+ }
+
+ public function __construct(int $code)
+ {
+ $this->code = $code;
+ }
+
+ public function setMessage(string $message): ModuleManagerMessage
+ {
+ $this->message = $message;
+ return $this;
+ }
+
+ public function setArchiveName(string $archiveName): ModuleManagerMessage
+ {
+ $this->archiveName = $archiveName;
+ return $this;
+ }
+
+ public function setVersion(string $version): ModuleManagerMessage
+ {
+ $this->version = $version;
+ return $this;
+ }
+
+ public function setVersionConstraint(string $versionContraint): ModuleManagerMessage
+ {
+ $this->versionContraint = $versionContraint;
+ return $this;
+ }
+
+ public function setModule(Module $module): ModuleManagerMessage
+ {
+ $this->module = $module;
+ return $this;
+ }
+
+ public function setCombinationSatisfyerResult(
+ CombinationSatisfyerResult $combinationSatisfyerResult
+ ): ModuleManagerMessage {
+ $this->combinationSatisfyerResult = $combinationSatisfyerResult;
+ return $this;
+ }
+
+ public function getCode(): int
+ {
+ return $this->code;
+ }
+
+ private function getModulName(): string
+ {
+ if ($this->module) {
+ $name = "{$this->module->getArchiveName()} version {$this->module->getVersion()}";
+ } elseif ($this->archiveName && $this->version) {
+ $name = "{$this->archiveName} version {$this->version}";
+ } elseif ($this->archiveName && $this->versionContraint) {
+ $name = "{$this->archiveName} version {$this->versionContraint}";
+ } elseif ($this->archiveName) {
+ $name = "{$this->archiveName}";
+ } else {
+ $name = "unknown";
+ }
+
+ return "module $name";
+ }
+
+ private function getUsedBy(): string
+ {
+ $subModulesArchiveNames = [];
+ foreach ($this->module->getUsedBy() as $subModule) {
+ $subModulesArchiveNames[] .= $subModule->getArchiveName();
+ }
+ $usedBy = implode("\n", $subModulesArchiveNames);
+ return $usedBy;
+ }
+
+ public function __toString()
+ {
+ if ($this->code === self::PULL_INFO_START) {
+ return sprintf("Pulling %s ...", $this->getModulName());
+ } elseif ($this->code === self::PULL_ERROR_MODULE_NOT_FOUND) {
+ return sprintf("Can not pull %s, because module not found.", $this->getModulName());
+ } elseif ($this->code === self::PULL_ERROR_MODULE_ALLREADY_LOADED) {
+ return sprintf("Can not pull %s, because module is already loaded.", $this->getModulName());
+ } elseif ($this->code === self::DELETE_INFO_START) {
+ return sprintf("Deleting %s ...", $this->getModulName());
+ } elseif ($this->code === self::DELETE_ERROR_MODULE_NOT_FOUND) {
+ return sprintf("Can not delete %s, because module not found.", $this->getModulName());
+ } elseif ($this->code === self::DELETE_ERROR_MODULE_IS_INSTALED) {
+ return sprintf("Can not delete %s, because it is installed.", $this->getModulName());
+ } elseif ($this->code === self::INSTALL_INFO_START) {
+ return sprintf("Installing %s ...", $this->getModulName());
+ } elseif ($this->code === self::INSTALL_INFO_PULL_MODULE_START) {
+ return sprintf("Pulling %s ...", $this->getModulName());
+ } elseif ($this->code === self::INSTALL_INFO_UPDATE_AUTOLOAD_START) {
+ return sprintf("Updating autotoload file ...");
+ } elseif ($this->code === self::INSTALL_ERROR_MODULE_NOT_FOUND) {
+ return sprintf("Can not install %s, because module not found.", $this->getModulName());
+ } elseif ($this->code === self::INSTALL_ERROR_MODULE_MISSING_REQUIREMENTS) {
+ return sprintf(
+ "Can not install %s, because not all requirements are met.\n%s",
+ $this->getModulName(),
+ '' . $this->combinationSatisfyerResult->failLog
+ );
+ } elseif ($this->code === self::INSTALL_ERROR_MODULE_ALLREADY_INSTALED) {
+ return sprintf("Can not install %s, because it is already installed.", $this->getModulName());
+ } elseif ($this->code === self::UPDATE_INFO_START) {
+ return sprintf("Updating %s ...", $this->getModulName());
+ } elseif ($this->code === self::UDPATE_INFO_PULL_MODULE_START) {
+ return sprintf("Pulling %s ...", $this->getModulName());
+ } elseif ($this->code === self::UPDATE_INFO_TO) {
+ return sprintf("Updated to %s.", $this->getModulName());
+ } elseif ($this->code === self::UPDATE_INFO_UPDATE_AUTOLOAD_START) {
+ return sprintf("Updating autotoload file ...", $this->getModulName());
+ } elseif ($this->code === self::UPDATE_ERROR_MODULE_NOT_FOUND) {
+ return sprintf("Can not update %s, because module not found.", $this->getModulName());
+ } elseif ($this->code === self::UPDATE_ERROR_MODULE_NOT_INSTALLED) {
+ return sprintf("Can not update %s, because module is not installed.", $this->getModulName());
+ } elseif ($this->code === self::UPDATE_ERROR_MODULE_MISSING_REQUIREMENTS) {
+ return sprintf(
+ "Can not update %s, because not all requirements are met.\n%s",
+ $this->getModulName(),
+ '' . $this->combinationSatisfyerResult->failLog
+ );
+ } elseif ($this->code === self::UPDATE_ERROR_MODULE_IS_CHANGED) {
+ return sprintf("Can not update %s, because module has changes.", $this->getModulName());
+ } elseif ($this->code === self::DISCARD_INFO_START) {
+ return sprintf("Discarding %s ...", $this->getModulName());
+ } elseif ($this->code === self::DISCARD_ERROR_MODULE_NOT_FOUND) {
+ return sprintf("Can not discard %s, because module not found.", $this->getModulName());
+ } elseif ($this->code === self::DISCARD_ERROR_MODULE_NOT_CHANGED) {
+ return sprintf("Can not discard %s, because module has no changes.", $this->getModulName());
+ } elseif ($this->code === self::UNINSTALL_INFO_START) {
+ return sprintf("Uninstalling %s ...", $this->getModulName());
+ } elseif ($this->code === self::UNINSTALL_INFO_UPDATE_AUTOLOAD_START) {
+ return sprintf("Updating autotoload file ...", $this->getModulName());
+ } elseif ($this->code === self::UNINSTALL_ERROR_MODULE_NOT_FOUND) {
+ return sprintf("Can not uninstall %s, because module not found.", $this->getModulName());
+ } elseif ($this->code === self::UNINSTALL_ERROR_MODULE_NOT_INSTALLED) {
+ return sprintf("Can not uninstall %s, because module is not installed.", $this->getModulName());
+ } elseif ($this->code === self::UNINSTALL_ERROR_MODULE_IS_CHANGED) {
+ return sprintf("Can not uninstall %s, because module has changes.", $this->getModulName());
+ } elseif ($this->code === self::UNINSTALL_ERROR_MODULE_IS_USED_BY) {
+ return sprintf(
+ "Can not uninstall %s, because module is used by other modules.\n%s",
+ $this->getModulName(),
+ $this->getUsedBy()
+ );
+ }
+
+ return "Unknown message";
+ }
+}
diff --git a/src/Classes/ModuleManager/ModuleManagerNullLogger.php b/src/Classes/ModuleManager/ModuleManagerNullLogger.php
new file mode 100644
index 00000000..9177f2bf
--- /dev/null
+++ b/src/Classes/ModuleManager/ModuleManagerNullLogger.php
@@ -0,0 +1,37 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace RobinTheHood\ModifiedModuleLoaderClient\ModuleManager;
+
+class ModuleManagerNullLogger implements ModuleManagerLoggerInterface
+{
+ public function debug(ModuleManagerMessage $message): void
+ {
+ }
+
+ public function info(ModuleManagerMessage $message): void
+ {
+ }
+
+ public function notice(ModuleManagerMessage $message): void
+ {
+ }
+
+ public function warning(ModuleManagerMessage $message): void
+ {
+ }
+
+ public function error(ModuleManagerMessage $message): void
+ {
+ }
+}
diff --git a/src/Classes/ModuleManager/ModuleManagerResult.php b/src/Classes/ModuleManager/ModuleManagerResult.php
new file mode 100644
index 00000000..2d563b0c
--- /dev/null
+++ b/src/Classes/ModuleManager/ModuleManagerResult.php
@@ -0,0 +1,76 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace RobinTheHood\ModifiedModuleLoaderClient\ModuleManager;
+
+use RobinTheHood\ModifiedModuleLoaderClient\Module;
+
+class ModuleManagerResult
+{
+ public const TYPE_ERROR = 1;
+ public const TYPE_SUCCESS = 2;
+
+ /** @var int */
+ private $type;
+
+ /** @var ModuleManagerMessage */
+ private $message;
+
+ /** @var Module */
+ private $module;
+
+ public function __construct(int $type)
+ {
+ $this->type = $type;
+ }
+
+ public static function success(): ModuleManagerResult
+ {
+ $moduleManagerResult = new ModuleManagerResult(self::TYPE_SUCCESS);
+ return $moduleManagerResult;
+ }
+
+ public static function error(ModuleManagerMessage $message): ModuleManagerResult
+ {
+ $moduleManagerResult = new ModuleManagerResult(self::TYPE_ERROR);
+ $moduleManagerResult->setMessage($message);
+ return $moduleManagerResult;
+ }
+
+ public function setModule(Module $module): ModuleManagerResult
+ {
+ $this->module = $module;
+ return $this;
+ }
+
+ public function setMessage(ModuleManagerMessage $message): ModuleManagerResult
+ {
+ $this->message = $message;
+ return $this;
+ }
+
+ public function getType(): int
+ {
+ return $this->type;
+ }
+
+ public function getModule(): ?Module
+ {
+ return $this->module;
+ }
+
+ public function getMessage(): ?ModuleManagerMessage
+ {
+ return $this->message;
+ }
+}
diff --git a/src/Classes/ViewModels/ModuleViewModel.php b/src/Classes/ViewModels/ModuleViewModel.php
index fae5a649..6762e508 100644
--- a/src/Classes/ViewModels/ModuleViewModel.php
+++ b/src/Classes/ViewModels/ModuleViewModel.php
@@ -16,7 +16,6 @@
use RobinTheHood\ModifiedModuleLoaderClient\App;
use RobinTheHood\ModifiedModuleLoaderClient\Module;
use RobinTheHood\ModifiedModuleLoaderClient\ModuleStatus;
-use RobinTheHood\ModifiedModuleLoaderClient\Notification;
use RobinTheHood\ModifiedModuleLoaderClient\Semver\ParseErrorException;
use RobinTheHood\ModifiedModuleLoaderClient\ShopInfo;
@@ -39,11 +38,21 @@ public function getInstallUrl(string $ref = ''): string
return $this->getUrl('install', $ref);
}
+ public function getForceInstallUrl(string $ref = ''): string
+ {
+ return $this->getUrl('install', $ref, null, ['force' => 'true']);
+ }
+
public function getRevertChangesUrl(string $ref = ''): string
{
return $this->getUrl('revertChanges', $ref);
}
+ public function getRevertChangesWithTemplateUrl(string $ref = ''): string
+ {
+ return $this->getUrl('revertChanges', $ref, null, ['withTemplate' => 'true']);
+ }
+
public function getLoadAndInstallUrl(string $ref = ''): string
{
return $this->getUrl('loadAndInstall', $ref);
@@ -194,17 +203,31 @@ public function isChanged(): bool
return $this->module->isChanged();
}
- private function getUrl(string $action, string $ref, ?Module $module = null): string
+ /**
+ * @param string $action
+ * @param string $ref
+ * @param ?Module $module
+ * @param string[] $queryParams
+ *
+ * @return string
+ */
+ private function getUrl(string $action, string $ref, ?Module $module = null, array $queryParams = []): string
{
if (!$module) {
$module = $this->module;
}
+ $queryString = http_build_query($queryParams);
+ if ($queryString) {
+ $queryString = '&' . $queryString;
+ }
+
return
'?action=' . $action .
'&archiveName=' . $module->getArchiveName() .
'&version=' . $module->getVersion() .
- '&ref=' . $ref;
+ '&ref=' . $ref
+ . $queryString;
}
/**
@@ -217,7 +240,8 @@ public function getCompatibleStrings(): array
if (!$this->module->isCompatibleWithModified()) {
$version = ShopInfo::getModifiedVersion();
$array[] = [
- 'text' => "Dieses Modul wurde noch nicht mit deiner Version von modified getestet. Du hast modifed Version $version installiert.",
+ 'text' => "Dieses Modul wurde nicht mit deiner Version von modified getestet. Du hast modifed Version
+ $version installiert.",
'type' => 'warning'
];
}
@@ -226,7 +250,8 @@ public function getCompatibleStrings(): array
if (!$this->module->isCompatibleWithPhp()) {
$version = phpversion();
$array[] = [
- 'text' => "Dieses Modul wurde noch nicht mit deiner PHP Version getestet. Du verwendest die PHP Version $version.",
+ 'text' => "Dieses Modul wurde noch nicht mit deiner PHP Version getestet. Du verwendest die PHP
+ Version $version.",
'type' => 'warning'
];
}
@@ -241,7 +266,8 @@ public function getCompatibleStrings(): array
if (!$this->module->isCompatibleWithMmlc()) {
$version = App::getMmlcVersion();
$array[] = [
- 'text' => "Dieses Modul wurde noch nicht mit deiner MMLC Version getestet. Du verwendest die MMLC Version $version.",
+ 'text' => "Dieses Modul wurde noch nicht mit deiner MMLC Version getestet. Du verwendest die MMLC
+ Version $version.",
'type' => 'warning'
];
}
diff --git a/src/Templates/ModuleInfo.tmpl.php b/src/Templates/ModuleInfo.tmpl.php
index 13152c49..2eea5f9c 100644
--- a/src/Templates/ModuleInfo.tmpl.php
+++ b/src/Templates/ModuleInfo.tmpl.php
@@ -97,8 +97,7 @@
isRepairable()) { ?>
-
+
Änderungen verwerfen
@@ -112,6 +111,16 @@
+
+
+
+
+ Änderungen verwerfen inkl. Templates
+
+
+ Änderungen übernehmen inkl. Templates (Link-Mode)
+
+
isCompatibleLoadableAndInstallable()) { ?>
@@ -127,7 +136,7 @@
Installieren
isIncompatibleInstallable()) { ?>
- Installieren (inkompatible Version)
+ Installieren (inkompatible Version)
hasInstalledVersion()) { ?>
Zur installierten Version
diff --git a/src/Templates/ModuleListingModule.tmpl.php b/src/Templates/ModuleListingModule.tmpl.php
index a68c377e..d3910bdf 100644
--- a/src/Templates/ModuleListingModule.tmpl.php
+++ b/src/Templates/ModuleListingModule.tmpl.php
@@ -1,5 +1,9 @@
isInstalled() ? 'installiert' : $moduleView->getPriceFormated();
diff --git a/src/Templates/Navi.tmpl.php b/src/Templates/Navi.tmpl.php
index 393e43a3..d7e0ab25 100644
--- a/src/Templates/Navi.tmpl.php
+++ b/src/Templates/Navi.tmpl.php
@@ -1,6 +1,13 @@
-
+
+/**
+ * @phpcs:disable Generic.Files.LineLength.TooLong
+ */
+
+defined('LOADED_FROM_INDEX') && LOADED_FROM_INDEX ?? die('Access denied.');
+
+use RobinTheHood\ModifiedModuleLoaderClient\ShopInfo;
+?>