From 57ddf69d1c18f8211b788c3f890d7787b41b7204 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 3 Jan 2025 14:04:15 +0000 Subject: [PATCH] Implement register subscribed events from addons --- src/App.php | 25 +++++++++++++------ src/Service/Addon/Addon.php | 2 ++ src/Service/Addon/AddonManager.php | 11 ++++++++ src/Service/Addon/AddonProxy.php | 11 ++++++++ tests/Unit/Service/Addon/AddonManagerTest.php | 19 ++++++++++++++ tests/Unit/Service/Addon/AddonProxyTest.php | 16 ++++++++++++ 6 files changed, 77 insertions(+), 7 deletions(-) diff --git a/src/App.php b/src/App.php index 664117b428..512be57b05 100644 --- a/src/App.php +++ b/src/App.php @@ -39,6 +39,7 @@ use Friendica\Network\HTTPException; use Friendica\Protocol\ATProtocol\DID; use Friendica\Security\ExAuth; use Friendica\Security\OpenWebAuth; +use Friendica\Service\Addon\AddonManager; use Friendica\Util\BasePath; use Friendica\Util\DateTimeFormat; use Friendica\Util\HTTPInputData; @@ -125,6 +126,8 @@ class App */ private $appHelper; + private AddonManager $addonManager; + private function __construct(Dice $container) { $this->container = $container; @@ -270,18 +273,22 @@ class App $processRepository->delete($process); } - private function setupContainerForAddons(): void + private function setupAddonManager(): void { $config = $this->container->create(IManageConfigValues::class); - /** @var \Friendica\Service\Addon\AddonManager $addonManager */ - $addonManager = $this->container->create(\Friendica\Service\Addon\AddonManager::class); + $this->addonManager = $this->container->create(\Friendica\Service\Addon\AddonManager::class); - $addonManager->bootstrapAddons($config->get('addons') ?? []); + $this->addonManager->bootstrapAddons($config->get('addons') ?? []); + } + + private function setupContainerForAddons(): void + { + $this->setupAddonManager(); // At this place we should be careful because addons can change the container // Maybe we should create a new container especially for the addons - $this->container = $this->container->addRules($addonManager->getProvidedDependencyRules()); + $this->container = $this->container->addRules($this->addonManager->getProvidedDependencyRules()); /** @var \Friendica\Core\Addon\Capability\ICanLoadAddons $addonLoader */ $addonLoader = $this->container->create(\Friendica\Core\Addon\Capability\ICanLoadAddons::class); @@ -290,11 +297,11 @@ class App $dependencies = []; - foreach ($addonManager->getAllRequiredDependencies() as $dependency) { + foreach ($this->addonManager->getAllRequiredDependencies() as $dependency) { $dependencies[$dependency] = $this->container->create($dependency); } - $addonManager->initAddons($dependencies); + $this->addonManager->initAddons($dependencies); } private function setupContainerForLogger(string $logChannel): void @@ -312,6 +319,10 @@ class App foreach (HookEventBridge::getStaticSubscribedEvents() as $eventName => $methodName) { $eventDispatcher->addListener($eventName, [HookEventBridge::class, $methodName]); } + + foreach ($this->addonManager->getAllSubscribedEvents() as $listener) { + $eventDispatcher->addListener($listener[0], $listener[1]); + } } private function setupLegacyServiceLocator(): void diff --git a/src/Service/Addon/Addon.php b/src/Service/Addon/Addon.php index f71df992c6..f4d4fb94ce 100644 --- a/src/Service/Addon/Addon.php +++ b/src/Service/Addon/Addon.php @@ -16,6 +16,8 @@ interface Addon { public function getRequiredDependencies(): array; + public function getSubscribedEvents(): array; + public function getProvidedDependencyRules(): array; public function initAddon(array $dependencies): void; diff --git a/src/Service/Addon/AddonManager.php b/src/Service/Addon/AddonManager.php index eb85132e3a..c8d33de44a 100644 --- a/src/Service/Addon/AddonManager.php +++ b/src/Service/Addon/AddonManager.php @@ -65,6 +65,17 @@ final class AddonManager return $dependencyRules; } + public function getAllSubscribedEvents(): array + { + $events = []; + + foreach ($this->addons as $addon) { + $events = array_merge($events, $addon->getSubscribedEvents()); + } + + return $events; + } + private function bootstrapAddon(string $addonName): void { $bootstrapFile = sprintf('%s/%s/bootstrap.php', $this->addonPath, $addonName); diff --git a/src/Service/Addon/AddonProxy.php b/src/Service/Addon/AddonProxy.php index 20704521e6..09ba386053 100644 --- a/src/Service/Addon/AddonProxy.php +++ b/src/Service/Addon/AddonProxy.php @@ -32,6 +32,17 @@ final class AddonProxy implements Addon return $this->bootstrap->getRequiredDependencies(); } + public function getSubscribedEvents(): array + { + $events = []; + + foreach ($this->bootstrap->getSubscribedEvents() as $eventName => $methodName) { + $events[] = [$eventName, [$this->bootstrap, $methodName]]; + } + + return $events; + } + public function getProvidedDependencyRules(): array { if ($this->bootstrap instanceof DependencyProvider) { diff --git a/tests/Unit/Service/Addon/AddonManagerTest.php b/tests/Unit/Service/Addon/AddonManagerTest.php index 6c0f7c9707..8847668c58 100644 --- a/tests/Unit/Service/Addon/AddonManagerTest.php +++ b/tests/Unit/Service/Addon/AddonManagerTest.php @@ -9,6 +9,7 @@ declare(strict_types=1); namespace Friendica\Test\Unit\Service\Addon; +use Friendica\Event\HtmlFilterEvent; use Friendica\Service\Addon\AddonManager; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; @@ -27,4 +28,22 @@ class AddonManagerTest extends TestCase $manager->bootstrapAddons(['helloaddon' => []]); } + + public function testGetAllSubscribedEventsReturnsEvents(): void + { + $logger = $this->createMock(LoggerInterface::class); + $logger->expects($this->once())->method('info')->with('Addon "helloaddon" loaded.'); + + $manager = new AddonManager( + dirname(__DIR__, 3) . '/Util', + $logger + ); + + $manager->bootstrapAddons(['helloaddon' => []]); + + $this->assertSame( + [[HtmlFilterEvent::PAGE_END, ['', 'onPageEnd']]], + $manager->getAllSubscribedEvents() + ); + } } diff --git a/tests/Unit/Service/Addon/AddonProxyTest.php b/tests/Unit/Service/Addon/AddonProxyTest.php index ac86aff936..d0f8294fa8 100644 --- a/tests/Unit/Service/Addon/AddonProxyTest.php +++ b/tests/Unit/Service/Addon/AddonProxyTest.php @@ -55,6 +55,22 @@ class AddonProxyTest extends TestCase $addon->getProvidedDependencyRules(); } + public function testGetSubscribedEventsCallsBootstrap(): void + { + $bootstrap = $this->createMock(AddonBootstrap::class); + $bootstrap->expects($this->once())->method('getSubscribedEvents')->willReturn(['foo' => 'bar']); + + $addon = new AddonProxy($bootstrap); + + $this->assertSame( + [ + ['foo', [$bootstrap, 'bar']], + ], + $addon->getSubscribedEvents() + ); + + } + public function testInitAddonCallsBootstrap(): void { $bootstrap = $this->createMock(AddonBootstrap::class);