Use AddonLoader in AddonManager

This commit is contained in:
Art4 2025-01-04 10:12:19 +00:00
parent 247e9c5fba
commit ee480130ad
4 changed files with 22 additions and 52 deletions

View file

@ -15,7 +15,7 @@ use Psr\Log\LoggerInterface;
/** /**
* Factory for all addons. * Factory for all addons.
*/ */
final class AddonFactory final class AddonFactory implements AddonLoader
{ {
private string $addonPath; private string $addonPath;
@ -30,6 +30,9 @@ final class AddonFactory
$this->logger = $logger; $this->logger = $logger;
} }
/**
* @return Addon[] Returns an array of Addon instances.
*/
public function getAddons(array $addonNames): array public function getAddons(array $addonNames): array
{ {
foreach ($addonNames as $addonName => $addonDetails) { foreach ($addonNames as $addonName => $addonDetails) {

View file

@ -17,29 +17,19 @@ use Psr\Log\LoggerInterface;
*/ */
final class AddonManager final class AddonManager
{ {
private string $addonPath; private AddonLoader $addonFactory;
private LoggerInterface $logger;
/** @var Addon[] */ /** @var Addon[] */
private array $addons = []; private array $addons = [];
public function __construct(string $addonPath, LoggerInterface $logger) public function __construct(AddonLoader $addonFactory)
{ {
$this->addonPath = $addonPath; $this->addonFactory = $addonFactory;
$this->logger = $logger;
} }
public function bootstrapAddons(array $addonNames): void public function bootstrapAddons(array $addonNames): void
{ {
foreach ($addonNames as $addonName => $addonDetails) { $this->addons = $this->addonFactory->getAddons($addonNames);
try {
$this->bootstrapAddon($addonName);
} catch (\Throwable $th) {
// @TODO Here we can check if we have a Legacy addon and try to load it
// throw $th;
}
}
} }
public function getAllRequiredDependencies(): array public function getAllRequiredDependencies(): array
@ -76,29 +66,6 @@ final class AddonManager
return $events; return $events;
} }
private function bootstrapAddon(string $addonName): void
{
$bootstrapFile = sprintf('%s/%s/bootstrap.php', $this->addonPath, $addonName);
if (!file_exists($bootstrapFile)) {
throw new \RuntimeException(sprintf('Bootstrap file for addon "%s" not found.', $addonName));
}
try {
$bootstrap = require $bootstrapFile;
} catch (\Throwable $th) {
throw new \RuntimeException(sprintf('Something went wrong loading the Bootstrap file for addon "%s".', $addonName), $th->getCode(), $th);
}
if (!($bootstrap instanceof AddonBootstrap)) {
throw new \RuntimeException(sprintf('Bootstrap file for addon "%s" MUST return an instance of AddonBootstrap.', $addonName));
}
$this->addons[$addonName] = new AddonProxy($bootstrap);
$this->logger->info(sprintf('Addon "%s" loaded.', $addonName));
}
public function initAddons(array $dependencies): void public function initAddons(array $dependencies): void
{ {
foreach ($this->addons as $addon) { foreach ($this->addons as $addon) {

View file

@ -165,7 +165,8 @@ return (function(string $basepath, array $getVars, array $serverVars, array $coo
\Psr\EventDispatcher\EventDispatcherInterface::class => [ \Psr\EventDispatcher\EventDispatcherInterface::class => [
'instanceOf' => \Friendica\Event\EventDispatcher::class, 'instanceOf' => \Friendica\Event\EventDispatcher::class,
], ],
\Friendica\Service\Addon\AddonManager::class => [ \Friendica\Service\Addon\AddonLoader::class => [
'instanceOf' => \Friendica\Service\Addon\AddonFactory::class,
'constructParams' => [ 'constructParams' => [
$basepath . '/addon', $basepath . '/addon',
], ],

View file

@ -10,6 +10,8 @@ declare(strict_types=1);
namespace Friendica\Test\Unit\Service\Addon; namespace Friendica\Test\Unit\Service\Addon;
use Friendica\Event\HtmlFilterEvent; use Friendica\Event\HtmlFilterEvent;
use Friendica\Service\Addon\Addon;
use Friendica\Service\Addon\AddonLoader;
use Friendica\Service\Addon\AddonManager; use Friendica\Service\Addon\AddonManager;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
@ -18,31 +20,28 @@ class AddonManagerTest extends TestCase
{ {
public function testBootstrapAddonsLoadsTheAddon(): void public function testBootstrapAddonsLoadsTheAddon(): void
{ {
$logger = $this->createMock(LoggerInterface::class); $loader = $this->createMock(AddonLoader::class);
$logger->expects($this->once())->method('info')->with('Addon "helloaddon" loaded.'); $loader->expects($this->once())->method('getAddons')->willReturn(['helloaddon' => $this->createMock(Addon::class)]);
$manager = new AddonManager( $manager = new AddonManager($loader);
dirname(__DIR__, 3) . '/Util',
$logger
);
$manager->bootstrapAddons(['helloaddon' => []]); $manager->bootstrapAddons(['helloaddon' => []]);
} }
public function testGetAllSubscribedEventsReturnsEvents(): void public function testGetAllSubscribedEventsReturnsEvents(): void
{ {
$logger = $this->createMock(LoggerInterface::class); $addon = $this->createMock(Addon::class);
$logger->expects($this->once())->method('info')->with('Addon "helloaddon" loaded.'); $addon->expects($this->once())->method('getSubscribedEvents')->willReturn([[HtmlFilterEvent::PAGE_END, [Addon::class, 'onPageEnd']]]);
$manager = new AddonManager( $loader = $this->createMock(AddonLoader::class);
dirname(__DIR__, 3) . '/Util', $loader->expects($this->once())->method('getAddons')->willReturn(['helloaddon' => $addon]);
$logger
); $manager = new AddonManager($loader);
$manager->bootstrapAddons(['helloaddon' => []]); $manager->bootstrapAddons(['helloaddon' => []]);
$this->assertSame( $this->assertSame(
[[HtmlFilterEvent::PAGE_END, ['', 'onPageEnd']]], [[HtmlFilterEvent::PAGE_END, [Addon::class, 'onPageEnd']]],
$manager->getAllSubscribedEvents() $manager->getAllSubscribedEvents()
); );
} }