marcmascarell/artificer

Application hooks

Closed this issue · 2 comments

We want to be able to hook on virtually all core parts of the app. This way, plugins could be able to perform any needed task.

Example:

protected function foo()
{
    $this->hook('before.field.show', function($params) {
        $this->next();

        // Eloquent instance
        $field = $params['field'];

        $field->title = '[Mandatory] - ' . $field->title;    
    });
}

As happens with middlewares you would be able to decide when to apply. Using for example a $this->next() syntax.

I add a proof of concept I wrote a time ago as example using Laravel's built in event system.

(It's missing the next() functionality)

class Hook {
    protected $classes = [];
    protected $hooks = [];

    public function with($classes) {
        $this->classes = $classes;

        return $this;   
    }

    public function to($hookName) {
        $classes = [];

        if (isset($this->hooks[$hookName])) {
            $classes = $this->hooks[$hookName];
        }

        $classes = array_merge($classes, $this->classes);

        Event::listen('hook.' . $hookName, function() use ($classes) {
            return $classes;
        });
    }

    public function fire($hookName, $data) {
        $classes = Event::fire('hook.' . $hookName);
        $classes = array_flatten($classes);

        foreach ($classes as $key => $class) {
            print_r($class);
        }
        // (new $class)->handle($data); 
    }
}

$hook = new Hook();
$hook->with([\App\Mascame\HelloWorldPlugin::class])->to('test');

$response = $hook->fire('test', \App\User::all());

dd($response);

Now fields listen to eloquent events:

protected static $hooks = [
        ModelHook::CREATING  => 'creatingHook',
        ModelHook::CREATED   => 'createdHook',
        ModelHook::UPDATING  => 'updatingHook',
        ModelHook::UPDATED   => 'updatedHook',
        ModelHook::SAVING    => 'savingHook',
        ModelHook::SAVED     => 'savedHook',
        ModelHook::DELETING  => 'deletingHook',
        ModelHook::DELETED   => 'deletedHook',
        ModelHook::RESTORING => 'restoringHook',
        ModelHook::RESTORED  => 'restoredHook',
]