Implement register subscribed events from addons

This commit is contained in:
Art4 2025-01-03 14:04:15 +00:00
parent a85343dbed
commit 57ddf69d1c
6 changed files with 77 additions and 7 deletions

View file

@ -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

View file

@ -16,6 +16,8 @@ interface Addon
{
public function getRequiredDependencies(): array;
public function getSubscribedEvents(): array;
public function getProvidedDependencyRules(): array;
public function initAddon(array $dependencies): void;

View file

@ -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);

View file

@ -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) {

View file

@ -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()
);
}
}

View file

@ -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);