Random thoughts

using aura dispatcher in silex

2 days back Paul M Jones wrote an awesome post A Peek At Aura v2 – Aura.Dispatcher the idea behind Aura.Dispatcher and how it was born.

So today, let us try to integrate Aura.Dispatcher with Silex. This post is inspired by the comment made by Luis Cordova. Thank you.

composer create-project silex/silex --no-dev silexproject
cd silexproject
composer require aura/dispatcher dev-develop-2

I hope you have composer installed else get composer.

I am not going to explain each and everything, the code is self explanatory. You can move the classes according to your wish (may be to another folder). I am trying to show a simple use case.

<?php
require __DIR__ . '/vendor/autoload.php';

use Aura\Dispatcher\Dispatcher;

$dispatcher = new Dispatcher;

$dispatcher->setMethodParam('action');
$dispatcher->setObjectParam('controller');

class Blog
{
    public function browse()
    {
        // ...
    }

    public function hello($name, $app)
    {
        return 'Hello '. ucfirst($app->escape($name));
    }

    public function edit($id)
    {
        echo "Here";
        exit;
        // ...
    }

    public function add()
    {
        // ...
    }

    public function delete($id)
    {
        // ...
    }
}

$dispatcher->setObject('blog', function () {
    return new Blog;
});

$app = new Silex\Application();

$app->get('/hello/{name}', function ($name) use ($dispatcher, $app) {
    $params = [
        'controller' => 'blog',
        'action' => 'hello',
        'name' => $name,
        'app' => $app,
    ];
    $result = $dispatcher->__invoke($params);    
    return $result;
});

$app->run();

See how we moved the return 'Hello '. ucfirst($app->escape($name)); to a controller and action. I haven't used Silex extensively, so there can be better ways for integration.

Update : I was asking Beau D. Simensen on the integration, and he gave another shot.

<?php
// all code as same as above, upto the route

$app->get('/hello/{name}', function ($name) use ($app) {
    return [
        'controller' => 'blog',
        'action' => 'hello',
        'name' => $name,
        'app' => $app,
    ];
});

$app->on(\Symfony\Component\HttpKernel\KernelEvents::VIEW, function ($event) use ($app, $dispatcher) {
    $view = $event->getControllerResult();

    if (is_null($view) || is_string($view)) {
        return;
    }
    
    if ( ! is_array($view)) {
        // we can only handle array data in the view
        return;
    }
    
    if (! (isset($view['controller']) && isset($view['action']))) {
        // at this point we don't know what is going on.
        return;
    }

    $response = $dispatcher($view);

    if ( ! $response instanceof \Symfony\Component\HttpFoundation\Response) {
        // If the response is not a Response instance, wrap it in one
        // and assume that it was something appropriate as a response
        // body.
        $response = new \Symfony\Component\HttpFoundation\Response($response);
    }

    $event->setResponse($response);
});

$app->run();

I have purposefully kept the full path like \Symfony\Component\HttpFoundation\Response

Hope you love Aura.Dispatcher and use when you need architecural changes.

Please do take time to read Refactoring To Architecture Changes

Thank you and if you loved the post please do a tweet :-).

Happy PhPing!

Menu