Implement uninstallAddon
This commit is contained in:
parent
a39850871e
commit
33398298d5
2 changed files with 172 additions and 1 deletions
|
@ -9,7 +9,9 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Friendica\Core\Addon;
|
namespace Friendica\Core\Addon;
|
||||||
|
|
||||||
|
use Friendica\Core\Cache\Capability\ICanCache;
|
||||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
|
use Friendica\Database\Database;
|
||||||
use Friendica\Util\Profiler;
|
use Friendica\Util\Profiler;
|
||||||
use Friendica\Util\Strings;
|
use Friendica\Util\Strings;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
@ -23,8 +25,12 @@ final class AddonManagerHelper implements AddonHelper
|
||||||
{
|
{
|
||||||
private string $addonPath;
|
private string $addonPath;
|
||||||
|
|
||||||
|
private Database $database;
|
||||||
|
|
||||||
private IManageConfigValues $config;
|
private IManageConfigValues $config;
|
||||||
|
|
||||||
|
private ICanCache $cache;
|
||||||
|
|
||||||
private LoggerInterface $logger;
|
private LoggerInterface $logger;
|
||||||
|
|
||||||
private Profiler $profiler;
|
private Profiler $profiler;
|
||||||
|
@ -37,12 +43,16 @@ final class AddonManagerHelper implements AddonHelper
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
string $addonPath,
|
string $addonPath,
|
||||||
|
Database $database,
|
||||||
IManageConfigValues $config,
|
IManageConfigValues $config,
|
||||||
|
ICanCache $cache,
|
||||||
LoggerInterface $logger,
|
LoggerInterface $logger,
|
||||||
Profiler $profiler
|
Profiler $profiler
|
||||||
) {
|
) {
|
||||||
$this->addonPath = $addonPath;
|
$this->addonPath = $addonPath;
|
||||||
|
$this->database = $database;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
|
$this->cache = $cache;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
$this->profiler = $profiler;
|
$this->profiler = $profiler;
|
||||||
|
|
||||||
|
@ -153,7 +163,31 @@ final class AddonManagerHelper implements AddonHelper
|
||||||
*/
|
*/
|
||||||
public function uninstallAddon(string $addonId): void
|
public function uninstallAddon(string $addonId): void
|
||||||
{
|
{
|
||||||
$this->proxy->uninstallAddon($addonId);
|
$addonId = Strings::sanitizeFilePathItem($addonId);
|
||||||
|
|
||||||
|
$this->logger->debug("Addon {addon}: {action}", ['action' => 'uninstall', 'addon' => $addonId]);
|
||||||
|
$this->config->delete('addons', $addonId);
|
||||||
|
|
||||||
|
$addon_file_path = $this->getAddonPath() . '/' . $addonId . '/' . $addonId . '.php';
|
||||||
|
|
||||||
|
@include_once($addon_file_path);
|
||||||
|
|
||||||
|
if (function_exists($addonId . '_uninstall')) {
|
||||||
|
$func = $addonId . '_uninstall';
|
||||||
|
$func();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove registered hooks for the addon
|
||||||
|
// Handles both relative and absolute file paths
|
||||||
|
$condition = ['`file` LIKE ?', "%/$addonId/$addonId.php"];
|
||||||
|
|
||||||
|
$result = $this->database->delete('hook', $condition);
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
$this->cache->delete('routerDispatchData');
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($this->addons[array_search($addonId, $this->addons)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,7 +12,9 @@ namespace Friendica\Test\Unit\Core\Addon;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Friendica\Core\Addon\AddonInfo;
|
use Friendica\Core\Addon\AddonInfo;
|
||||||
use Friendica\Core\Addon\AddonManagerHelper;
|
use Friendica\Core\Addon\AddonManagerHelper;
|
||||||
|
use Friendica\Core\Cache\Capability\ICanCache;
|
||||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
|
use Friendica\Database\Database;
|
||||||
use Friendica\Util\Profiler;
|
use Friendica\Util\Profiler;
|
||||||
use org\bovigo\vfs\vfsStream;
|
use org\bovigo\vfs\vfsStream;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
@ -24,7 +26,9 @@ class AddonManagerHelperTest extends TestCase
|
||||||
{
|
{
|
||||||
$addonManagerHelper = new AddonManagerHelper(
|
$addonManagerHelper = new AddonManagerHelper(
|
||||||
__DIR__ . '/../../../Util/addons',
|
__DIR__ . '/../../../Util/addons',
|
||||||
|
$this->createStub(Database::class),
|
||||||
$this->createStub(IManageConfigValues::class),
|
$this->createStub(IManageConfigValues::class),
|
||||||
|
$this->createStub(ICanCache::class),
|
||||||
$this->createStub(LoggerInterface::class),
|
$this->createStub(LoggerInterface::class),
|
||||||
$this->createStub(Profiler::class)
|
$this->createStub(Profiler::class)
|
||||||
);
|
);
|
||||||
|
@ -48,7 +52,9 @@ class AddonManagerHelperTest extends TestCase
|
||||||
|
|
||||||
$addonManagerHelper = new AddonManagerHelper(
|
$addonManagerHelper = new AddonManagerHelper(
|
||||||
__DIR__ . '/../../../Util/addons',
|
__DIR__ . '/../../../Util/addons',
|
||||||
|
$this->createStub(Database::class),
|
||||||
$config,
|
$config,
|
||||||
|
$this->createStub(ICanCache::class),
|
||||||
$this->createStub(LoggerInterface::class),
|
$this->createStub(LoggerInterface::class),
|
||||||
$this->createStub(Profiler::class)
|
$this->createStub(Profiler::class)
|
||||||
);
|
);
|
||||||
|
@ -74,7 +80,9 @@ class AddonManagerHelperTest extends TestCase
|
||||||
|
|
||||||
$addonManagerHelper = new AddonManagerHelper(
|
$addonManagerHelper = new AddonManagerHelper(
|
||||||
__DIR__ . '/../../../Util/addons',
|
__DIR__ . '/../../../Util/addons',
|
||||||
|
$this->createStub(Database::class),
|
||||||
$config,
|
$config,
|
||||||
|
$this->createStub(ICanCache::class),
|
||||||
$this->createStub(LoggerInterface::class),
|
$this->createStub(LoggerInterface::class),
|
||||||
$this->createStub(Profiler::class)
|
$this->createStub(Profiler::class)
|
||||||
);
|
);
|
||||||
|
@ -98,7 +106,9 @@ class AddonManagerHelperTest extends TestCase
|
||||||
|
|
||||||
$addonManagerHelper = new AddonManagerHelper(
|
$addonManagerHelper = new AddonManagerHelper(
|
||||||
__DIR__ . '/../../../Util/addons',
|
__DIR__ . '/../../../Util/addons',
|
||||||
|
$this->createStub(Database::class),
|
||||||
$config,
|
$config,
|
||||||
|
$this->createStub(ICanCache::class),
|
||||||
$this->createStub(LoggerInterface::class),
|
$this->createStub(LoggerInterface::class),
|
||||||
$this->createStub(Profiler::class)
|
$this->createStub(Profiler::class)
|
||||||
);
|
);
|
||||||
|
@ -110,7 +120,9 @@ class AddonManagerHelperTest extends TestCase
|
||||||
{
|
{
|
||||||
$addonManagerHelper = new AddonManagerHelper(
|
$addonManagerHelper = new AddonManagerHelper(
|
||||||
__DIR__ . '/../../../Util/addons',
|
__DIR__ . '/../../../Util/addons',
|
||||||
|
$this->createStub(Database::class),
|
||||||
$this->createStub(IManageConfigValues::class),
|
$this->createStub(IManageConfigValues::class),
|
||||||
|
$this->createStub(ICanCache::class),
|
||||||
$this->createStub(LoggerInterface::class),
|
$this->createStub(LoggerInterface::class),
|
||||||
$this->createStub(Profiler::class)
|
$this->createStub(Profiler::class)
|
||||||
);
|
);
|
||||||
|
@ -128,7 +140,9 @@ class AddonManagerHelperTest extends TestCase
|
||||||
|
|
||||||
$addonManagerHelper = new AddonManagerHelper(
|
$addonManagerHelper = new AddonManagerHelper(
|
||||||
$root->url(),
|
$root->url(),
|
||||||
|
$this->createStub(Database::class),
|
||||||
$this->createStub(IManageConfigValues::class),
|
$this->createStub(IManageConfigValues::class),
|
||||||
|
$this->createStub(ICanCache::class),
|
||||||
$this->createStub(LoggerInterface::class),
|
$this->createStub(LoggerInterface::class),
|
||||||
$this->createStub(Profiler::class)
|
$this->createStub(Profiler::class)
|
||||||
);
|
);
|
||||||
|
@ -159,7 +173,9 @@ class AddonManagerHelperTest extends TestCase
|
||||||
|
|
||||||
$addonManagerHelper = new AddonManagerHelper(
|
$addonManagerHelper = new AddonManagerHelper(
|
||||||
$root->url(),
|
$root->url(),
|
||||||
|
$this->createStub(Database::class),
|
||||||
$this->createStub(IManageConfigValues::class),
|
$this->createStub(IManageConfigValues::class),
|
||||||
|
$this->createStub(ICanCache::class),
|
||||||
$this->createStub(LoggerInterface::class),
|
$this->createStub(LoggerInterface::class),
|
||||||
$this->createStub(Profiler::class)
|
$this->createStub(Profiler::class)
|
||||||
);
|
);
|
||||||
|
@ -189,7 +205,9 @@ class AddonManagerHelperTest extends TestCase
|
||||||
|
|
||||||
$addonManagerHelper = new AddonManagerHelper(
|
$addonManagerHelper = new AddonManagerHelper(
|
||||||
$root->url(),
|
$root->url(),
|
||||||
|
$this->createStub(Database::class),
|
||||||
$config,
|
$config,
|
||||||
|
$this->createStub(ICanCache::class),
|
||||||
$this->createStub(LoggerInterface::class),
|
$this->createStub(LoggerInterface::class),
|
||||||
$this->createStub(Profiler::class)
|
$this->createStub(Profiler::class)
|
||||||
);
|
);
|
||||||
|
@ -207,7 +225,9 @@ class AddonManagerHelperTest extends TestCase
|
||||||
|
|
||||||
$addonManagerHelper = new AddonManagerHelper(
|
$addonManagerHelper = new AddonManagerHelper(
|
||||||
$root->url(),
|
$root->url(),
|
||||||
|
$this->createStub(Database::class),
|
||||||
$this->createStub(IManageConfigValues::class),
|
$this->createStub(IManageConfigValues::class),
|
||||||
|
$this->createStub(ICanCache::class),
|
||||||
$this->createStub(LoggerInterface::class),
|
$this->createStub(LoggerInterface::class),
|
||||||
$this->createStub(Profiler::class)
|
$this->createStub(Profiler::class)
|
||||||
);
|
);
|
||||||
|
@ -218,4 +238,121 @@ class AddonManagerHelperTest extends TestCase
|
||||||
|
|
||||||
$this->assertSame(['helloaddon'], $addonManagerHelper->getEnabledAddons());
|
$this->assertSame(['helloaddon'], $addonManagerHelper->getEnabledAddons());
|
||||||
}
|
}
|
||||||
|
public function testUninstallAddonIncludesAddonFile(): void
|
||||||
|
{
|
||||||
|
$root = vfsStream::setup(__FUNCTION__ . '_addons', 0777, [
|
||||||
|
'helloaddon' => [
|
||||||
|
'helloaddon.php' => '<?php throw new \Exception("Addon file loaded");',
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$addonManagerHelper = new AddonManagerHelper(
|
||||||
|
$root->url(),
|
||||||
|
$this->createStub(Database::class),
|
||||||
|
$this->createStub(IManageConfigValues::class),
|
||||||
|
$this->createStub(ICanCache::class),
|
||||||
|
$this->createStub(LoggerInterface::class),
|
||||||
|
$this->createStub(Profiler::class)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->expectException(Exception::class);
|
||||||
|
$this->expectExceptionMessage('Addon file loaded');
|
||||||
|
|
||||||
|
$addonManagerHelper->uninstallAddon('helloaddon');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUninstallAddonCallsUninstallFunction(): 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}_uninstall()
|
||||||
|
{
|
||||||
|
throw new \Exception("Addon uninstalled");
|
||||||
|
}
|
||||||
|
PHP,
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$addonManagerHelper = new AddonManagerHelper(
|
||||||
|
$root->url(),
|
||||||
|
$this->createStub(Database::class),
|
||||||
|
$this->createStub(IManageConfigValues::class),
|
||||||
|
$this->createStub(ICanCache::class),
|
||||||
|
$this->createStub(LoggerInterface::class),
|
||||||
|
$this->createStub(Profiler::class)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->expectException(Exception::class);
|
||||||
|
$this->expectExceptionMessage('Addon uninstalled');
|
||||||
|
|
||||||
|
$addonManagerHelper->uninstallAddon($addonName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUninstallAddonRemovesHooksFromDatabase(): void
|
||||||
|
{
|
||||||
|
$root = vfsStream::setup(__FUNCTION__ . '_addons', 0777, [
|
||||||
|
'helloaddon' => [
|
||||||
|
'helloaddon.php' => '<?php',
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$database = $this->createMock(Database::class);
|
||||||
|
$database->expects($this->once())
|
||||||
|
->method('delete')
|
||||||
|
->with(
|
||||||
|
'hook',
|
||||||
|
['`file` LIKE ?', '%/helloaddon/helloaddon.php']
|
||||||
|
);
|
||||||
|
|
||||||
|
$addonManagerHelper = new AddonManagerHelper(
|
||||||
|
$root->url(),
|
||||||
|
$database,
|
||||||
|
$this->createStub(IManageConfigValues::class),
|
||||||
|
$this->createStub(ICanCache::class),
|
||||||
|
$this->createStub(LoggerInterface::class),
|
||||||
|
$this->createStub(Profiler::class)
|
||||||
|
);
|
||||||
|
|
||||||
|
$addonManagerHelper->uninstallAddon('helloaddon');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUninstallAddonDisablesAddon(): void
|
||||||
|
{
|
||||||
|
$root = vfsStream::setup(__FUNCTION__ . '_addons', 0777, [
|
||||||
|
'helloaddon' => [
|
||||||
|
'helloaddon.php' => '<?php',
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$config = $this->createStub(IManageConfigValues::class);
|
||||||
|
$config->method('get')->willReturn([
|
||||||
|
'helloaddon' => [
|
||||||
|
'last_update' => 1234567890,
|
||||||
|
'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(['helloaddon'], $addonManagerHelper->getEnabledAddons());
|
||||||
|
|
||||||
|
$addonManagerHelper->uninstallAddon('helloaddon');
|
||||||
|
|
||||||
|
$this->assertSame([], $addonManagerHelper->getEnabledAddons());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue