Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
58.06% covered (warning)
58.06%
36 / 62
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
SystemEventDispatcher
57.38% covered (warning)
57.38%
35 / 61
50.00% covered (danger)
50.00%
1 / 2
10.79
0.00% covered (danger)
0.00%
0 / 1
 __construct
56.67% covered (warning)
56.67%
34 / 60
0.00% covered (danger)
0.00%
0 / 1
8.93
 dispatch
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5/** @license For full copyright and license information, please see the LICENSE.md file. */
6
7namespace App\Core\Event;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use App\Core\Engine\Domain\Event\RecordCreatedEvent;
12use App\Core\Engine\Domain\Event\RecordDeletedEvent;
13use App\Core\Engine\Domain\Event\RecordReadEvent;
14use App\Core\Engine\Domain\Event\RecordUpdatedEvent;
15use App\Core\Engine\Infrastructure\Listener\AuditCreateListener;
16use App\Core\Engine\Infrastructure\Listener\AuditDeleteListener;
17use App\Core\Engine\Infrastructure\Listener\AuditReadListener;
18use App\Core\Engine\Infrastructure\Listener\AuditUpdateListener;
19use App\Core\Engine\Infrastructure\Repository\SqlAuditRepository;
20use App\Core\Engine\Infrastructure\Settings\EngineSettings;
21use App\Modules\Automation\Application\Listener\WorkflowRecordLifecycleListener;
22use App\Modules\Calendar\Application\Listener\CalendarInvitationRecordListener;
23use App\Modules\Dav\Application\Listener\DavSyncRecordListener;
24use Psr\EventDispatcher\EventDispatcherInterface;
25use Psr\EventDispatcher\ListenerProviderInterface;
26use Yiisoft\EventDispatcher\Dispatcher\Dispatcher;
27use Yiisoft\EventDispatcher\Provider\ListenerCollection;
28use Yiisoft\EventDispatcher\Provider\Provider;
29
30/**
31 * System Event Dispatcher.
32 *
33 * Wraps Yii3 EventDispatcher and registers audit, DAV sync, workflow, and calendar invitation listeners.
34 *
35 * @package App\Core\Event
36 */
37final readonly class SystemEventDispatcher implements EventDispatcherInterface
38{
39    private Dispatcher $dispatcher;
40
41    /**
42     * SystemEventDispatcher constructor.
43     *
44     * @param SqlAuditRepository|ListenerProviderInterface $source Audit repository or listener provider.
45     * @param EngineSettings|null $settings Engine settings repository.
46     * @param DavSyncRecordListener|null $davListener Optional DAV sync event listener.
47     * @param WorkflowRecordLifecycleListener|null $workflowListener Optional workflow event listener.
48     * @param CalendarInvitationRecordListener|null $calendarListener Optional calendar invitation listener.
49     */
50    public function __construct(
51        SqlAuditRepository|ListenerProviderInterface $source,
52        ?EngineSettings $settings = null,
53        ?DavSyncRecordListener $davListener = null,
54        ?WorkflowRecordLifecycleListener $workflowListener = null,
55        ?CalendarInvitationRecordListener $calendarListener = null,
56    ) {
57        if ($source instanceof ListenerProviderInterface) {
58            $this->dispatcher = new Dispatcher($source);
59            return;
60        }
61
62        $collection = new ListenerCollection();
63        $createListener = new AuditCreateListener($source);
64        $updateListener = new AuditUpdateListener($source);
65        $deleteListener = new AuditDeleteListener($source);
66
67        $collection = $collection
68            ->add(static fn(RecordCreatedEvent $e) => ($createListener)($e), RecordCreatedEvent::class)
69            ->add(static fn(RecordUpdatedEvent $e) => ($updateListener)($e), RecordUpdatedEvent::class)
70            ->add(static fn(RecordDeletedEvent $e) => ($deleteListener)($e), RecordDeletedEvent::class);
71
72        if ($davListener !== null) {
73            $collection = $collection
74                ->add(
75                    static fn(RecordCreatedEvent $e) => $davListener->onRecordCreated($e),
76                    RecordCreatedEvent::class
77                )
78                ->add(
79                    static fn(RecordUpdatedEvent $e) => $davListener->onRecordUpdated($e),
80                    RecordUpdatedEvent::class
81                )
82                ->add(
83                    static fn(RecordDeletedEvent $e) => $davListener->onRecordDeleted($e),
84                    RecordDeletedEvent::class
85                );
86        }
87
88        if ($workflowListener !== null) {
89            $collection = $collection
90                ->add(
91                    static fn(RecordCreatedEvent $e) => $workflowListener->onRecordCreated($e),
92                    RecordCreatedEvent::class
93                )
94                ->add(
95                    static fn(RecordUpdatedEvent $e) => $workflowListener->onRecordUpdated($e),
96                    RecordUpdatedEvent::class
97                )
98                ->add(
99                    static fn(RecordDeletedEvent $e) => $workflowListener->onRecordDeleted($e),
100                    RecordDeletedEvent::class
101                );
102        }
103
104        if ($calendarListener !== null) {
105            $collection = $collection
106                ->add(
107                    static fn(RecordCreatedEvent $e) => $calendarListener->onRecordCreated($e),
108                    RecordCreatedEvent::class
109                )
110                ->add(
111                    static fn(RecordUpdatedEvent $e) => $calendarListener->onRecordUpdated($e),
112                    RecordUpdatedEvent::class
113                )
114                ->add(
115                    static fn(RecordDeletedEvent $e) => $calendarListener->onRecordDeleted($e),
116                    RecordDeletedEvent::class
117                );
118        }
119
120        if ($settings !== null) {
121            $readListener = new AuditReadListener($source, $settings);
122            $collection = $collection->add(
123                static fn(RecordReadEvent $e) => ($readListener)($e),
124                RecordReadEvent::class
125            );
126        }
127
128        $this->dispatcher = new Dispatcher(new Provider($collection));
129    }
130
131    /**
132     * Dispatches an event to relevant listeners.
133     *
134     * @param object $event Domain event instance.
135     * @return object The passed event object.
136     */
137    public function dispatch(object $event): object
138    {
139        return $this->dispatcher->dispatch($event);
140    }
141}