Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for outside listeners #145

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft

Add support for outside listeners #145

wants to merge 9 commits into from

Conversation

inxilpro
Copy link
Contributor

@inxilpro inxilpro commented Jul 5, 2024

This lets you register outside listeners for events. Say you have an analytics process, or some secondary reporting functionality that you want to add. Sometimes it doesn't make sense for those to exist on the event itself. Now you can do something like:

class AnalyticsProjector
{
  // This will implicitly run when `handle` is called
  public function onDownload(ProductDownloaded $event)
  {
    Analytics::incrementDownloads();
  }

  // Or you can use attributes to be explicit and set phases
  #[Listen(ProductDownloaded::class)]
  #[Listen(ProductUpdated::class)]
  #[Listen(ProductDiscontinued::class)]
  #[On(Phase::Fired)]
  public function genericListener($event)
  {
    // will get called during the "fired" phase when any of those events fire
  }
}

Then you just register with:

Verbs::listen(AnalyticsProjector::class);

@inxilpro inxilpro marked this pull request as draft July 5, 2024 20:59
@inxilpro
Copy link
Contributor Author

inxilpro commented Jul 5, 2024

Ugh. I accidentally ran pint on everything. I'll revert before marking as ready.

@inmanturbo
Copy link

inmanturbo commented Aug 1, 2024

What is the status on this? Is it currently possible to listen or subscribe to verb events outside of the event definition itself?

In our case the event itself will be inaccessible to the developer writing projections in some cases, as it will be in another code base (composer package) handled by another team. In other words for some parts of the system we will have one development team publishing events and another team subscribing to them.

@inmanturbo
Copy link

inmanturbo commented Aug 1, 2024

As a workaround I'll be testing a POC using circular dependency. I.E.:

// after apply()
 
public function handle()
{
    $listeners = app(CustomerHandlers::class)->getListeners();

    foreach ($listeners as $listener) {
        $listener->handle($this);
    }
}
// meanwhile, somewhere in a whole 'nother code base ...

class SubscriptionHandler implements CustomerHandler
{
    public function handle(Event $event): mixed
    {
        return match(get_class($event))  {
            CustomerBeganTrial::class => Subscription::create([
                'customer_id' => $event->customer_id,
                'expires_at' => now()->addDays(30),
            ]),
            default => null,
        };
    }
}

Copy link
Collaborator

@skylerkatz skylerkatz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants