diff --git a/src/Service/Addon/Addon.php b/src/Service/Addon/Addon.php index efbb480916..41ed3cd791 100644 --- a/src/Service/Addon/Addon.php +++ b/src/Service/Addon/Addon.php @@ -14,6 +14,8 @@ namespace Friendica\Service\Addon; */ interface Addon { + public function getId(): string; + public function getRequiredDependencies(): array; public function getSubscribedEvents(): array; diff --git a/src/Service/Addon/AddonFactory.php b/src/Service/Addon/AddonFactory.php index 2daefa3a00..b8ff773939 100644 --- a/src/Service/Addon/AddonFactory.php +++ b/src/Service/Addon/AddonFactory.php @@ -65,7 +65,7 @@ final class AddonFactory implements AddonLoader throw new \RuntimeException(sprintf('Bootstrap file for addon "%s" MUST return an instance of AddonBootstrap.', $addonName)); } - $addon = new AddonProxy($bootstrap); + $addon = new AddonProxy($addonName, $bootstrap); $this->logger->info(sprintf('Addon "%s" loaded.', $addonName)); diff --git a/src/Service/Addon/AddonManager.php b/src/Service/Addon/AddonManager.php index 5988e5e8be..17e7c82768 100644 --- a/src/Service/Addon/AddonManager.php +++ b/src/Service/Addon/AddonManager.php @@ -41,6 +41,18 @@ final class AddonManager return array_unique($dependencies); } + public function getRequiredDependencies(): array + { + $dependencies = []; + + foreach ($this->addons as $addon) { + // @TODO Here we can filter or deny dependencies from addons + $dependencies[$addon->getId()] = $addon->getRequiredDependencies(); + } + + return $dependencies; + } + public function getProvidedDependencyRules(): array { $dependencyRules = []; diff --git a/src/Service/Addon/AddonProxy.php b/src/Service/Addon/AddonProxy.php index 3874d5c637..8db404c035 100644 --- a/src/Service/Addon/AddonProxy.php +++ b/src/Service/Addon/AddonProxy.php @@ -19,15 +19,23 @@ use Friendica\Addon\InstallableAddon; */ final class AddonProxy implements Addon { + private string $id; + private AddonBootstrap $bootstrap; private bool $isInit = false; - public function __construct(AddonBootstrap $bootstrap) + public function __construct(string $id, AddonBootstrap $bootstrap) { + $this->id = $id; $this->bootstrap = $bootstrap; } + public function getId(): string + { + return $this->id; + } + public function getRequiredDependencies(): array { return $this->bootstrap->getRequiredDependencies(); diff --git a/src/Service/Addon/LegacyAddonProxy.php b/src/Service/Addon/LegacyAddonProxy.php index 913eff6990..5ab98b2fa8 100644 --- a/src/Service/Addon/LegacyAddonProxy.php +++ b/src/Service/Addon/LegacyAddonProxy.php @@ -14,18 +14,23 @@ namespace Friendica\Service\Addon; */ final class LegacyAddonProxy implements Addon { - private string $name; + private string $id; private string $path; private bool $isInit = false; - public function __construct(string $name, string $path) + public function __construct(string $id, string $path) { - $this->name = $name; + $this->id = $id; $this->path = $path; } + public function getId(): string + { + return $this->id; + } + public function getRequiredDependencies(): array { return []; @@ -38,7 +43,7 @@ final class LegacyAddonProxy implements Addon public function getProvidedDependencyRules(): array { - $fileName = $this->path . '/' . $this->name . '/static/dependencies.config.php'; + $fileName = $this->path . '/' . $this->id . '/static/dependencies.config.php'; if (is_file($fileName)) { return include_once($fileName); @@ -55,20 +60,20 @@ final class LegacyAddonProxy implements Addon $this->isInit = true; - include_once($this->path . '/' . $this->name . '/' . $this->name . '.php'); + include_once($this->path . '/' . $this->id . '/' . $this->id . '.php'); } public function installAddon(): void { - if (function_exists($this->name . '_install')) { - call_user_func($this->name . '_install'); + if (function_exists($this->id . '_install')) { + call_user_func($this->id . '_install'); } } public function uninstallAddon(): void { - if (function_exists($this->name . '_uninstall')) { - call_user_func($this->name . '_uninstall'); + if (function_exists($this->id . '_uninstall')) { + call_user_func($this->id . '_uninstall'); } } } diff --git a/tests/Unit/Service/Addon/AddonManagerTest.php b/tests/Unit/Service/Addon/AddonManagerTest.php index 864c8cc2be..ca6502b028 100644 --- a/tests/Unit/Service/Addon/AddonManagerTest.php +++ b/tests/Unit/Service/Addon/AddonManagerTest.php @@ -29,11 +29,11 @@ class AddonManagerTest extends TestCase public function testGetAllSubscribedEventsReturnsEvents(): void { - $addon = $this->createMock(Addon::class); - $addon->expects($this->once())->method('getSubscribedEvents')->willReturn([[HtmlFilterEvent::PAGE_END, [Addon::class, 'onPageEnd']]]); + $addon = $this->createStub(Addon::class); + $addon->method('getSubscribedEvents')->willReturn([[HtmlFilterEvent::PAGE_END, [Addon::class, 'onPageEnd']]]); - $loader = $this->createMock(AddonLoader::class); - $loader->expects($this->once())->method('getAddons')->willReturn(['helloaddon' => $addon]); + $loader = $this->createStub(AddonLoader::class); + $loader->method('getAddons')->willReturn(['helloaddon' => $addon]); $manager = new AddonManager($loader); @@ -44,4 +44,23 @@ class AddonManagerTest extends TestCase $manager->getAllSubscribedEvents() ); } + + public function testGetRequiredDependenciesReturnsArray(): void + { + $addon = $this->createStub(Addon::class); + $addon->method('getId')->willReturn('helloaddon'); + $addon->method('getRequiredDependencies')->willReturn(['foo', 'bar']); + + $loader = $this->createStub(AddonLoader::class); + $loader->method('getAddons')->willReturn(['helloaddon' => $addon]); + + $manager = new AddonManager($loader); + + $manager->bootstrapAddons(['helloaddon' => []]); + + $this->assertSame( + ['helloaddon' => ['foo', 'bar']], + $manager->getRequiredDependencies() + ); + } } diff --git a/tests/Unit/Service/Addon/AddonProxyTest.php b/tests/Unit/Service/Addon/AddonProxyTest.php index 65cfbf0e69..3c0864483a 100644 --- a/tests/Unit/Service/Addon/AddonProxyTest.php +++ b/tests/Unit/Service/Addon/AddonProxyTest.php @@ -38,17 +38,26 @@ class AddonProxyTest extends TestCase { $bootstrap = $this->createStub(AddonBootstrap::class); - $addon = new AddonProxy($bootstrap); + $addon = new AddonProxy('id', $bootstrap); $this->assertInstanceOf(Addon::class, $addon); } + public function testGetIdReturnsId(): void + { + $bootstrap = $this->createStub(AddonBootstrap::class); + + $addon = new AddonProxy('id', $bootstrap); + + $this->assertSame('id', $addon->getId()); + } + public function testGetRequiredDependenciesCallsBootstrap(): void { $bootstrap = $this->createMock(AddonBootstrap::class); $bootstrap->expects($this->once())->method('getRequiredDependencies')->willReturn([]); - $addon = new AddonProxy($bootstrap); + $addon = new AddonProxy('id', $bootstrap); $addon->getRequiredDependencies(); } @@ -58,7 +67,7 @@ class AddonProxyTest extends TestCase $bootstrap = $this->createMock(CombinedAddonBootstrapDependencyProvider::class); $bootstrap->expects($this->once())->method('provideDependencyRules')->willReturn([]); - $addon = new AddonProxy($bootstrap); + $addon = new AddonProxy('id', $bootstrap); $addon->getProvidedDependencyRules(); } @@ -68,7 +77,7 @@ class AddonProxyTest extends TestCase $bootstrap = $this->createMock(AddonBootstrap::class); $bootstrap->expects($this->once())->method('getSubscribedEvents')->willReturn(['foo' => 'bar']); - $addon = new AddonProxy($bootstrap); + $addon = new AddonProxy('id', $bootstrap); $this->assertSame( [ @@ -86,7 +95,7 @@ class AddonProxyTest extends TestCase $this->assertInstanceOf(AddonStartEvent::class, $event); }); - $addon = new AddonProxy($bootstrap); + $addon = new AddonProxy('id', $bootstrap); $addon->initAddon([]); } @@ -98,7 +107,7 @@ class AddonProxyTest extends TestCase $this->assertInstanceOf(AddonStartEvent::class, $event); }); - $addon = new AddonProxy($bootstrap); + $addon = new AddonProxy('id', $bootstrap); $addon->initAddon([]); $addon->initAddon([]); @@ -115,7 +124,7 @@ class AddonProxyTest extends TestCase $this->assertInstanceOf(LoggerInterface::class, $dependencies[LoggerInterface::class]); }); - $addon = new AddonProxy($bootstrap); + $addon = new AddonProxy('id', $bootstrap); $addon->initAddon( [LoggerInterface::class => $this->createStub(LoggerInterface::class)] @@ -127,7 +136,7 @@ class AddonProxyTest extends TestCase $bootstrap = $this->createMock(CombinedAddonBootstrapInstallableAddon::class); $bootstrap->expects($this->once())->method('install'); - $addon = new AddonProxy($bootstrap); + $addon = new AddonProxy('id', $bootstrap); $addon->initAddon([]); $addon->installAddon(); @@ -138,7 +147,7 @@ class AddonProxyTest extends TestCase $bootstrap = $this->createMock(CombinedAddonBootstrapInstallableAddon::class); $bootstrap->expects($this->once())->method('uninstall'); - $addon = new AddonProxy($bootstrap); + $addon = new AddonProxy('id', $bootstrap); $addon->initAddon([]); $addon->uninstallAddon(); diff --git a/tests/Unit/Service/Addon/LegacyAddonProxyTest.php b/tests/Unit/Service/Addon/LegacyAddonProxyTest.php index 00e74a01c7..c3b54326fe 100644 --- a/tests/Unit/Service/Addon/LegacyAddonProxyTest.php +++ b/tests/Unit/Service/Addon/LegacyAddonProxyTest.php @@ -16,7 +16,7 @@ use PHPUnit\Framework\TestCase; class LegacyAddonProxyTest extends TestCase { - public function testCreateWithNameAndPath(): void + public function testCreateWithIdAndPath(): void { $root = vfsStream::setup('addons', 0777, ['helloaddon' => []]); @@ -25,6 +25,15 @@ class LegacyAddonProxyTest extends TestCase $this->assertInstanceOf(Addon::class, $addon); } + public function testGetIdReturnsId(): void + { + $root = vfsStream::setup('addons', 0777, ['helloaddon' => []]); + + $addon = new LegacyAddonProxy('helloaddon', $root->url()); + + $this->assertSame('helloaddon', $addon->getId()); + } + public function testGetRequiredDependenciesReturnsEmptyArray(): void { $root = vfsStream::setup('addons', 0777, ['helloaddon' => []]);