namespace Friendica\App;
-use Dice\Dice;
use FastRoute\DataGenerator\GroupCountBased;
use FastRoute\Dispatcher;
use FastRoute\RouteCollector;
use FastRoute\RouteParser\Std;
-use Friendica\Capabilities\ICanHandleRequests;
use Friendica\Core\Addon;
use Friendica\Core\Cache\Enum\Duration;
use Friendica\Core\Cache\Capability\ICanCache;
use Friendica\Core\L10n;
use Friendica\Core\Lock\Capability\ICanLock;
use Friendica\Core\Session\Capability\IHandleUserSessions;
+use Friendica\Event\CollectRoutesEvent;
use Friendica\LegacyModule;
use Friendica\Module\HTTPException\MethodNotAllowed;
use Friendica\Module\HTTPException\PageNotFound;
use Friendica\Network\HTTPException\MethodNotAllowedException;
use Friendica\Network\HTTPException\NotFoundException;
use Friendica\Util\Router\FriendicaGroupCountBased;
+use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Log\LoggerInterface;
/**
/** @var LoggerInterface */
private $logger;
+ private EventDispatcherInterface $eventDispatcher;
+
/** @var bool */
private $isLocalUser;
* @param IHandleUserSessions $userSession
* @param RouteCollector|null $routeCollector
*/
- public function __construct(array $server, string $baseRoutesFilepath, L10n $l10n, ICanCache $cache, ICanLock $lock, IManageConfigValues $config, Arguments $args, LoggerInterface $logger, IHandleUserSessions $userSession, RouteCollector $routeCollector = null)
+ public function __construct(array $server, string $baseRoutesFilepath, L10n $l10n, ICanCache $cache, ICanLock $lock, IManageConfigValues $config, Arguments $args, LoggerInterface $logger, EventDispatcherInterface $eventDispatcher, IHandleUserSessions $userSession, RouteCollector $routeCollector = null)
{
$this->baseRoutesFilepath = $baseRoutesFilepath;
$this->l10n = $l10n;
$this->config = $config;
$this->server = $server;
$this->logger = $logger;
+ $this->eventDispatcher = $eventDispatcher;
$this->isLocalUser = !empty($userSession->getLocalUserId());
$this->routeCollector = $routeCollector ?? new RouteCollector(new Std(), new GroupCountBased());
$this->addRoutes($routeCollector, $routes);
- $this->routeCollector = $routeCollector;
-
// Add routes from addons
- Hook::callAll('route_collection', $this->routeCollector);
+ $routeCollector = $this->eventDispatcher->dispatch(
+ new CollectRoutesEvent(CollectRoutesEvent::COLLECT_ROUTES, $routeCollector),
+ )->getRouteCollector();
+
+ $this->routeCollector = $routeCollector;
return $this;
}
use Friendica\Core\Hook;
use Friendica\Event\ArrayFilterEvent;
+use Friendica\Event\CollectRoutesEvent;
use Friendica\Event\ConfigLoadedEvent;
use Friendica\Event\Event;
use Friendica\Event\HtmlFilterEvent;
Event::INIT => 'init_1',
Event::HOME_INIT => 'home_init',
ConfigLoadedEvent::CONFIG_LOADED => 'load_config',
+ CollectRoutesEvent::COLLECT_ROUTES => 'route_collection',
ArrayFilterEvent::APP_MENU => 'app_menu',
ArrayFilterEvent::NAV_INFO => 'nav_info',
ArrayFilterEvent::FEATURE_ENABLED => 'isEnabled',
Event::INIT => 'onNamedEvent',
Event::HOME_INIT => 'onNamedEvent',
ConfigLoadedEvent::CONFIG_LOADED => 'onConfigLoadedEvent',
+ CollectRoutesEvent::COLLECT_ROUTES => 'onCollectRoutesEvent',
ArrayFilterEvent::APP_MENU => 'onArrayFilterEvent',
ArrayFilterEvent::NAV_INFO => 'onArrayFilterEvent',
ArrayFilterEvent::FEATURE_ENABLED => 'onArrayFilterEvent',
static::callHook($event->getName(), $event->getConfig());
}
+ public static function onCollectRoutesEvent(CollectRoutesEvent $event): void
+ {
+ $event->setRouteCollector(
+ static::callHook($event->getName(), $event->getRouteCollector())
+ );
+ }
+
public static function onArrayFilterEvent(ArrayFilterEvent $event): void
{
$event->setArray(
--- /dev/null
+<?php
+
+// Copyright (C) 2010-2024, the Friendica project
+// SPDX-FileCopyrightText: 2010-2024 the Friendica project
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+declare(strict_types=1);
+
+namespace Friendica\Event;
+
+use FastRoute\RouteCollector;
+
+/**
+ * Allow addons to collect routes.
+ *
+ * @internal
+ */
+final class CollectRoutesEvent extends Event
+{
+ public const COLLECT_ROUTES = 'friendica.collect_routes';
+
+ private RouteCollector $routeCollector;
+
+ public function __construct(string $name, RouteCollector $routeCollector)
+ {
+ parent::__construct($name);
+
+ $this->routeCollector = $routeCollector;
+ }
+
+ public function getRouteCollector(): RouteCollector
+ {
+ return $this->routeCollector;
+ }
+
+ public function setRouteCollector(RouteCollector $routeCollector): void
+ {
+ $this->routeCollector = $routeCollector;
+ }
+}
namespace Friendica\Test\Unit\Core\Hooks;
+use FastRoute\RouteCollector;
use Friendica\Core\Config\Util\ConfigFileManager;
use Friendica\Core\Hooks\HookEventBridge;
use Friendica\Event\ArrayFilterEvent;
+use Friendica\Event\CollectRoutesEvent;
use Friendica\Event\ConfigLoadedEvent;
use Friendica\Event\Event;
use Friendica\Event\HtmlFilterEvent;
Event::INIT => 'onNamedEvent',
Event::HOME_INIT => 'onNamedEvent',
ConfigLoadedEvent::CONFIG_LOADED => 'onConfigLoadedEvent',
+ CollectRoutesEvent::COLLECT_ROUTES => 'onCollectRoutesEvent',
ArrayFilterEvent::APP_MENU => 'onArrayFilterEvent',
ArrayFilterEvent::NAV_INFO => 'onArrayFilterEvent',
ArrayFilterEvent::FEATURE_ENABLED => 'onArrayFilterEvent',
HookEventBridge::onConfigLoadedEvent($event);
}
+ public static function getCollectRoutesEventData(): array
+ {
+ return [
+ ['test', 'test'],
+ [CollectRoutesEvent::COLLECT_ROUTES, 'route_collection'],
+ ];
+ }
+
+ /**
+ * @dataProvider getCollectRoutesEventData
+ */
+ public function testOnCollectRoutesEventCallsHookWithCorrectValue($name, $expected): void
+ {
+ $routeCollector = $this->createStub(RouteCollector::class);
+
+ $event = new CollectRoutesEvent($name, $routeCollector);
+
+ $reflectionProperty = new \ReflectionProperty(HookEventBridge::class, 'mockedCallHook');
+ $reflectionProperty->setAccessible(true);
+
+ $reflectionProperty->setValue(null, function (string $name, $data) use ($expected, $routeCollector) {
+ $this->assertSame($expected, $name);
+ $this->assertSame($routeCollector, $data);
+
+ return $data;
+ });
+
+ HookEventBridge::onCollectRoutesEvent($event);
+ }
+
public static function getArrayFilterEventData(): array
{
return [
--- /dev/null
+<?php
+
+// Copyright (C) 2010-2024, the Friendica project
+// SPDX-FileCopyrightText: 2010-2024 the Friendica project
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+declare(strict_types=1);
+
+namespace Friendica\Test\Unit\Event;
+
+use FastRoute\RouteCollector;
+use Friendica\Event\CollectRoutesEvent;
+use Friendica\Event\NamedEvent;
+use PHPUnit\Framework\TestCase;
+
+class CollectRoutesEventTest extends TestCase
+{
+ public function testImplementationOfInstances(): void
+ {
+ $event = new CollectRoutesEvent('test', $this->createStub(RouteCollector::class));
+
+ $this->assertInstanceOf(NamedEvent::class, $event);
+ }
+
+ public static function getPublicConstants(): array
+ {
+ return [
+ [CollectRoutesEvent::COLLECT_ROUTES, 'friendica.collect_routes'],
+ ];
+ }
+
+ /**
+ * @dataProvider getPublicConstants
+ */
+ public function testPublicConstantsAreAvailable($value, $expected): void
+ {
+ $this->assertSame($expected, $value);
+ }
+
+ public function testGetNameReturnsName(): void
+ {
+ $event = new CollectRoutesEvent('test', $this->createStub(RouteCollector::class));
+
+ $this->assertSame('test', $event->getName());
+ }
+
+ public function testGetRouteCollectorReturnsCorrectString(): void
+ {
+ $routeCollector = $this->createStub(RouteCollector::class);
+
+ $event = new CollectRoutesEvent('test', $routeCollector);
+
+ $this->assertSame($routeCollector, $event->getRouteCollector());
+ }
+
+ public function testSetRouteCollector(): void
+ {
+ $event = new CollectRoutesEvent('test', $this->createStub(RouteCollector::class));
+
+ $routeCollector = $this->createStub(RouteCollector::class);
+
+ $event->setRouteCollector($routeCollector);
+
+ $this->assertSame($routeCollector, $event->getRouteCollector());
+ }
+}