small-swoole-events
Tags: php, openswoole, showdev
Published: 2023-06-23 14:19:29

I've published first version of small-swoole-events.

You can find it at :
- [framagit](https://framagit.org/small/swoole-events)
- [packagist](https://packagist.org/packages/small/swoole-events)

## install

```bash
$ composer require small/swoole-events
```

## Event

An event is every class that extends AbstractEvent.

The event data must be defined in constructor via setData method in order to allow multithreading data share.

```php
class SimpleEvent extends AbstractEvent
{

    public function __construct(int $data1, int $data2)
    {

        $this->setId(1);
        $this->data = new Collection(['data1' => $data1, 'data2' => $data2]);
        $this->createDataTable();
        $this->setData('data1', $data1);
        $this->setData('data2', $data2);

    }

    public function getData($field): mixed
    {

        $data = $this->gatherResult();
        return $data[$field];

    }

    public function jsonSerialize(): mixed
    {

        return $this->gatherResult();;

    }

}
```

# Event Listener

An event listener is a class that handle event by doing some task and/or update event data.

It must implement ListenerInterface, which imply that you implement at least :
- getPriority : return the priority of listener
- getHandleableEvents : return list of events types (class) that listener ca handle
- handle : handle an event

For example, here is a listener that can handle the previous SimpleEvent :
```php
class AppListener implements ListenerInterface
{

    public static function getPriority(): string
    {
        return Priority::getPriorityByName(Priority::APP_EXTERNAL_LOW);
    }

    public static function getHandleableEvents(): array
    {

        return [SimpleEvent::class];

    }

    /**
     * @param SimpleEvent $event
     * @return ListenerInterface
     * @throws \Exception
     */
    public function handle(AbstractEvent $event): ListenerInterface
    {

        $event->setData('data1', 1);
        $event->setData('data2', $event->getData('data2') + 1);

        return $this;

    }

}
```

The priority of handling event by listeners is defined in Priority class :
```php
\Small\SwooleEvents\Listener\Priority::KERNEL_HIGH;
\Small\SwooleEvents\Listener\Priority::KERNEL_MIDDLE;
\Small\SwooleEvents\Listener\Priority::KERNEL_LOW;
\Small\SwooleEvents\Listener\Priority::APP_INTERNAL_HIGH;
\Small\SwooleEvents\Listener\Priority::APP_INTERNAL_MIDDLE;
\Small\SwooleEvents\Listener\Priority::APP_INTERNAL_LOW;
\Small\SwooleEvents\Listener\Priority::APP_EXTERNAL_HIGH;
\Small\SwooleEvents\Listener\Priority::APP_EXTERNAL_MIDDLE;
\Small\SwooleEvents\Listener\Priority::APP_EXTERNAL_LOW;
```

The execution will be done from KERNEL (first) to APP_EXTERNAL (last) and from HIGH to LOW.

## Event Dispatch

### Create events provider and register listeners

```php
$listenerProvider = new ListenerProvider();
$listenerProvider->addListener(new KernelSimpleEventListener());
$listenerProvider->addListener(new AppSimpleEventListener());
```

### Create event dispatcher

```php
$event = new EventDispatcher(
    $listenerProvider,
    $this->container, // The psr container of your favorite framework
);
```

### Create events and disptatch them

```php
$listenerProvider->dispatch(new SimpleEvent(0, 2));
```

### Order of execution

The events are submitted to listener by batch segmented by priority from KERNEL to APP_EXTERNAL.

Each event handling in batch is executed asynchronous.