PHP code example of crell / tukio

1. Go to this page and download the library: Download crell/tukio library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

crell / tukio example snippets


$provider = new SomeProvider();
// Do some sort of setup on $provider so that it knows what Listeners it should match to what Events.
// This could be pretty much anything depending on the implementation.

$dispatcher = new SomeDispatcher($provider);

// Pass $dispatcher to some client code somewhere, and then:

$thingHappened = new ThingHappened($thing);

$dispatcher->dispatch($thingHappened);

$reactions = $dispatcher->dispatch(new ThingHappened($thing))->getReactions();

use Crell\Tukio\Dispatcher;
use Crell\Tukio\DebugEventDispatcher;

$provider = new SomeProvider();

$logger = new SomeLogger();

$dispatcher = new Dispatcher($provider, $logger);

$debugDispatcher = new DebugEventDispatcher($dispatcher, $logger);

// Now pass $debugDispatcher around and use it like any other dispatcher.

use Crell\Tukio\OrderedListenerProvider;

class StuffHappened {}

class SpecificStuffHappened extends StuffHappened {}

function handleStuff(StuffHappened $stuff) { ... }


$provider = new OrderedListenerProvider();

$provider->listener(function(SpecificStuffHappened) {
    // ...  
});

$provider->listener('handleStuff');

use Crell\Tukio\OrderedListenerProvider;

$provider = new OrderedListenerProvider();

$provider->listener(function(SpecificStuffHappened) {
    // ...  
}, priority: 10);

$provider->listener('handleStuff', priority: 20);

use Crell\Tukio\OrderedListenerProvider;

$provider = new OrderedListenerProvider();

// The ID will be "handleStuff", unless there is such an ID already,
//in which case it would be "handleStuff-1" or similar.
$id = $provider->listener('handleStuff');

// This Listener will get called before handleStuff does. If you want to specify an ID
// you can, since anonymous functions just get a random string as their generated ID.
$provider->listener($id, function(SpecificStuffHappened) {
    // ...  
}, before: ['my_specifics']);

public function listener(
    callable $listener,
    ?int $priority = null,
    array $before = [],
    array $after = [],
    ?string $id = null,
    ?string $type = null
): string;

public function listenerService(
    string $service,
    ?string $method = null,
    ?string $type = null,
    ?int $priority = null,
    array $before = [],
    array $after = [],
    ?string $id = null
): string;

use Crell\Tukio\OrderedListenerProvider;

class SomeService
{
    public function methodA(ThingHappened $event): void { ... }

    public function methodB(SpecificThingHappened $event): void { ... }
}

class MyListeners
{
    public function methodC(WhatHappened $event): void { ... }
    
    public function somethingElse(string $beep): string { ... }
}

class EasyListening
{
    public function __invoke(SpecificThingHappened $event): void { ... } 
}

$container = new SomePsr11Container();
// Configure the container somehow.
$container->register('some_service', SomeService::class);
$container->register(MyListeners::class, MyListeners::class);
$container->register(EasyListening::class, EasyListening::class);

$provider = new OrderedListenerProvider($container);

// Manually register two methods on the same service.
$idA = $provider->listenerService('some_service', 'methodA', ThingHappened::class);
$idB = $provider->listenerService('some_service', 'methodB', SpecificThingHappened::class);

// Register a specific method on a derivable service class.
// The type (WhatHappened) will be derived automatically.
$idC = $provider->listenerService(MyListeners::class, 'methodC', after: 'some_service-methodB');

// Auto-everything!  This is the easiest option.
$provider->listenerService(EasyListening::class, before: $idC);

#[Listener(id: 'a_listener'), ListenerBefore('other'), ListenerAfter('something', 'else')]
function my_listener(SomeEvent $event): void { ... }

// Or just use the one before/after you care about:
#[ListenerAfter('something_early')]
function other(SomeEvent $event): void { ... }

$provider->addSubscriber(SomeCollectionOfListeners::class, 'service_name');

class SomeCollectionOfListeners
{
    // Registers, with a custom ID.
    #[Listener(id: 'a')]
    public function onA(CollectingEvent $event) : void
    {
        $event->add('A');
    }

    // Registers, with a custom priority.
    #[ListenerPriority(priority: 5)]
    public function onB(CollectingEvent $event) : void
    {
        $event->add('B');
    }

    // Registers, before listener "a" above.
    #[ListenerBefore(before: 'a')]
    public function onC(CollectingEvent $event) : void
    {
        $event->add('C');
    }

    // Registers, after listener "a" above.
    #[ListenerAfter(after: 'a')]
    public function onD(CollectingEvent $event) : void
    {
        $event->add('D');
    }

    // This still self-registers because of the name.
    public function onE(CollectingEvent $event) : void
    {
        $event->add('E');
    }

    // Registers, with a given priority despite its non-standard name.
    #[ListenerPriority(priority: -5)]
    public function notNormalName(CollectingEvent $event) : void
    {
        $event->add('F');
    }

    // No attribute, non-standard name, this method is not registered.
    public function ignoredMethodThatDoesNothing() : void
    {
        throw new \Exception('What are you doing here?');
    }
}

class ListenerOne
{
    public function __construct(
        private readonly DependencyA $depA,
        private readonly DependencyB $depB,
    ) {}
    
    public function __invoke(MyEvent $event): void { ... }
}

#[ListenerBefore(ListenerOne::class)]
class ListenerTwo
{
    public function __invoke(MyEvent $event): void { ... }
}

$provider->listenerService(ListenerOne::class);
$provider->listenerService(ListenerTwo::class);

public function addListener(callable $listener, ?int $priority = null, ?string $id = null, ?string $type = null): string;

public function addListenerBefore(string $before, callable $listener, ?string $id = null, ?string $type = null): string;

public function addListenerAfter(string $after, callable $listener, ?string $id = null, ?string $type = null): string;

public function addListenerService(string $service, string $method, string $type, ?int $priority = null, ?string $id = null): string;

public function addListenerServiceBefore(string $before, string $service, string $method, string $type, ?string $id = null): string;

public function addListenerServiceAfter(string $after, string $service, string $method, string $type, ?string $id = null): string;

use Crell\Tukio\OrderedListenerProvider;
use Crell\Tukio\SubscriberInterface;

class Subscriber implements SubscriberInterface
{
    public function onThingsHappening(ThingHappened $event) : void { ... }

    public function onSpecialEvent(SpecificThingHappened $event) : void { ... }

    public function somethingElse(ThingHappened $event) : void { ... }

    public static function registerListeners(ListenerProxy $proxy) : void
    {
        $id = $proxy->addListener('somethingElse', 10);
        $proxy->addListenerAfter($id, 'onSpecialEvent');
    }
}

$container = new SomePsr11Container();
// Configure the container so that the service 'listeners' is an instance of Subscriber above.

$provider = new OrderedListenerProvider($container);

$provider->addSubscriber(Subscriber::class, 'listeners');

use Crell\Tukio\ProviderBuilder;
use Crell\Tukio\ProviderCompiler;

$builder = new ProviderBuilder();

$builder->listener('listenerA', priority: 100);
$builder->listener('listenerB', after: 'listenerA');
$builder->listener([Listen::class, 'listen']);
$builder->listenerService(MyListener::class);
$builder->addSubscriber('subscriberId', Subscriber::class);

$compiler = new ProviderCompiler();

// Write the generated compiler out to a file.
$filename = 'MyCompiledProvider.php';
$out = fopen($filename, 'w');

// Here's the magic:
$compiler->compile($builder, $out, 'MyCompiledProvider', '\\Name\\Space\\Of\\My\\App');

fclose($out);

// Configure the container such that it has a service "listeners"
// and another named "subscriber".

$container = new Psr11Container();
$container->addService('D', new ListenService());


// Write the generated compiler out to a file.
$filename = 'MyCompiledProvider.php';
$out = fopen($filename, 'w');

$compiler->compileAnonymous($builder, $out);

fclose($out);

$compiler = new ProviderCompiler();

$provider = $compiler->loadAnonymous($filename, $containerInstance);

use Crell\Tukio\ProviderBuilder;
use Crell\Tukio\ProviderCompiler;

$builder = new ProviderBuilder();

$builder->listener('listenerA', priority: 100);
$builder->listener('listenerB', after: 'listenerA');
$builder->listener([Listen::class, 'listen']);
$builder->listenerService(MyListener::class);
$builder->addSubscriber('subscriberId', Subscriber::class);

// Here's where you specify what events you know you will have.
// Returning the listeners for these events will be near instant.
$builder->optimizeEvent(EvenOne::class);
$builder->optimizeEvent(EvenTwo::class);

$compiler = new ProviderCompiler();

// Write the generated compiler out to a file.
$filename = 'MyCompiledProvider.php';
$out = fopen($filename, 'w');

$compiler->compileAnonymous($builder, $out);

fclose($out);

use Crell\Tukio\CallbackEventInterface;
use Crell\Tukio\CallbackProvider;

class LifecycleEvent implements CallbackEventInterface
{
    protected $entity;

    public function __construct(FakeEntity $entity)
    {
        $this->entity = $entity;
    }

    public function getSubject() : object
    {
        return $this->entity;
    }
}

class LoadEvent extends LifecycleEvent {}

class SaveEvent extends LifecycleEvent {}

class FakeEntity
{

    public function load(LoadEvent $event) : void { ... }

    public function save(SaveEvent $event) : void { ... }

    public function stuff(StuffEvent $event) : void { ... }

    public function all(LifecycleEvent $event) : void { ... }
}

$provider = new CallbackProvider();

$entity = new FakeEntity();

$provider->addCallbackMethod(LoadEvent::class, 'load');
$provider->addCallbackMethod(SaveEvent::class, 'save');
$provider->addCallbackMethod(LifecycleEvent::class, 'all');

$event = new LoadEvent($entity);

$provider->getListenersForEvent($event);