Implement reloadAddons()

This commit is contained in:
Art4 2025-05-15 06:59:37 +00:00
parent 33398298d5
commit 5cf2b7d7bd
3 changed files with 82 additions and 15 deletions

View file

@ -55,7 +55,7 @@ interface AddonHelper
public function loadAddons(): void; public function loadAddons(): void;
/** /**
* Reload (uninstall and install) all updated addons. * Reload (uninstall and install) all installed and modified addons.
*/ */
public function reloadAddons(): void; public function reloadAddons(): void;

View file

@ -201,11 +201,31 @@ final class AddonManagerHelper implements AddonHelper
} }
/** /**
* Reload (uninstall and install) all updated addons. * Reload (uninstall and install) all installed and modified addons.
*/ */
public function reloadAddons(): void public function reloadAddons(): void
{ {
$this->proxy->reloadAddons(); $addons = array_filter($this->config->get('addons') ?? []);
foreach ($addons as $addonName => $data) {
$addonId = Strings::sanitizeFilePathItem(trim($addonName));
$addon_file_path = $this->getAddonPath() . '/' . $addonId . '/' . $addonId . '.php';
if (!file_exists($addon_file_path)) {
continue;
}
if (array_key_exists('last_update', $data) && intval($data['last_update']) === filemtime($addon_file_path)) {
// Addon unmodified, skipping
continue;
}
$this->logger->debug("Addon {addon}: {action}", ['action' => 'reload', 'addon' => $addonId]);
$this->uninstallAddon($addonId);
$this->installAddon($addonId);
}
} }
/** /**

View file

@ -162,12 +162,12 @@ class AddonManagerHelperTest extends TestCase
$root = vfsStream::setup(__FUNCTION__ . '_addons', 0777, [ $root = vfsStream::setup(__FUNCTION__ . '_addons', 0777, [
$addonName => [ $addonName => [
$addonName . '.php' => <<<PHP $addonName . '.php' => <<<PHP
<?php <?php
function {$addonName}_install() function {$addonName}_install()
{ {
throw new \Exception("Addon installed"); throw new \Exception("Addon installed");
} }
PHP, PHP,
] ]
]); ]);
@ -270,12 +270,12 @@ class AddonManagerHelperTest extends TestCase
$root = vfsStream::setup(__FUNCTION__ . '_addons', 0777, [ $root = vfsStream::setup(__FUNCTION__ . '_addons', 0777, [
$addonName => [ $addonName => [
$addonName . '.php' => <<<PHP $addonName . '.php' => <<<PHP
<?php <?php
function {$addonName}_uninstall() function {$addonName}_uninstall()
{ {
throw new \Exception("Addon uninstalled"); throw new \Exception("Addon uninstalled");
} }
PHP, PHP,
] ]
]); ]);
@ -355,4 +355,51 @@ class AddonManagerHelperTest extends TestCase
$this->assertSame([], $addonManagerHelper->getEnabledAddons()); $this->assertSame([], $addonManagerHelper->getEnabledAddons());
} }
public function testReloadAddonsInstallsAddon(): void
{
// We need a unique name for the addon to avoid conflicts
// with other tests that may define the same install function.
$addonName = __FUNCTION__;
$root = vfsStream::setup(__FUNCTION__ . '_addons', 0777, [
$addonName => [
$addonName . '.php' => <<<PHP
<?php
function {$addonName}_install()
{
throw new \Exception("Addon reinstalled");
}
PHP,
]
]);
$root->getChild($addonName . '/' . $addonName . '.php')->lastModified(1234567890);
$config = $this->createStub(IManageConfigValues::class);
$config->method('get')->willReturn([
$addonName => [
'last_update' => 0,
'admin' => false,
],
]);
$addonManagerHelper = new AddonManagerHelper(
$root->url(),
$this->createStub(Database::class),
$config,
$this->createStub(ICanCache::class),
$this->createStub(LoggerInterface::class),
$this->createStub(Profiler::class)
);
$addonManagerHelper->loadAddons();
$this->assertSame([$addonName], $addonManagerHelper->getEnabledAddons());
$this->expectException(Exception::class);
$this->expectExceptionMessage('Addon reinstalled');
$addonManagerHelper->reloadAddons();
}
} }