1
0
mirror of https://github.com/flarum/core.git synced 2025-07-30 21:20:24 +02:00

Add subscribe method to event extender (#2535)

Historically, extensions using subscribers has caused problems because subscribers were constructed/applied at extension boot. This caused some classes (e.g. UrlGenerator) to be resolved early, breaking parts of Flarum. For this reason, subscriber support wasn't included in the initial version of the Event extender.

However, updating extensions has shown that there is a legitimate use case for subscribers in organizing clean code; for instance, core's own `DiscussionMetadataUpdater`.

This commit introduces support for subscribers, but only applies them after the app has booted, which avoids the early resolution issues. Since event listeners/subscribers are only intended to be used with domain events, which would never be dispatched during app boot, the late activation of subscribers should not cause issue.
This commit is contained in:
Alexander Skvortsov
2021-01-15 20:33:29 -05:00
committed by GitHub
parent f93ec1b3b8
commit 9b2d7856d1
2 changed files with 81 additions and 3 deletions

View File

@@ -10,12 +10,14 @@
namespace Flarum\Tests\integration\extenders;
use Flarum\Extend;
use Flarum\Foundation\Application;
use Flarum\Group\Command\CreateGroup;
use Flarum\Group\Event\Created;
use Flarum\Tests\integration\RetrievesAuthorizedUsers;
use Flarum\Tests\integration\TestCase;
use Flarum\User\User;
use Illuminate\Contracts\Bus\Dispatcher;
use Illuminate\Contracts\Bus\Dispatcher as BusDispatcher;
use Illuminate\Contracts\Events\Dispatcher;
use Symfony\Component\Translation\TranslatorInterface;
class EventTest extends TestCase
@@ -24,7 +26,7 @@ class EventTest extends TestCase
protected function buildGroup()
{
$bus = $this->app()->getContainer()->make(Dispatcher::class);
$bus = $this->app()->getContainer()->make(BusDispatcher::class);
return $bus->dispatch(
new CreateGroup(User::find(1), ['attributes' => [
@@ -72,6 +74,32 @@ class EventTest extends TestCase
$this->assertEquals('core.group.admin', $group->name_singular);
}
/**
* @test
*/
public function custom_subscriber_works()
{
// Because it injects a translator, this also tests that stuff can be injected into this callback.
$this->extend((new Extend\Event)->subscribe(CustomSubscriber::class));
$group = $this->buildGroup();
$this->assertEquals('core.group.admin', $group->name_singular);
}
/**
* @test
*/
public function custom_subscriber_applied_after_app_booted()
{
// Because it injects a translator, this also tests that stuff can be injected into this callback.
$this->extend((new Extend\Event)->subscribe(CustomSubscriber::class));
$group = $this->buildGroup();
$this->assertEquals('booted', $group->name_plural);
}
}
class CustomListener
@@ -88,3 +116,26 @@ class CustomListener
$event->group->name_singular = $this->translator->trans('core.group.admin');
}
}
class CustomSubscriber
{
protected $bootedAtConstruct;
protected $translator;
public function __construct(Application $app, TranslatorInterface $translator)
{
$this->bootedAtConstruct = $app->isBooted();
$this->translator = $translator;
}
public function subscribe(Dispatcher $events)
{
$events->listen(Created::class, [$this, 'whenGroupCreated']);
}
public function whenGroupCreated(Created $event)
{
$event->group->name_singular = $this->translator->trans('core.group.admin');
$event->group->name_plural = $this->bootedAtConstruct ? 'booted' : 'not booted';
}
}