zot24's avatar

I need to add PROPFIND HTTP method to Lumen route system

Basically I need to be able to specify my own HTTP methods on a Lumen app. I got it working right now but is a very messy solution I just extended Laravel\Lumen\Application and added the following:

public function propfind($uri, $action)
{
    $this->addRoute('PROPFIND', $uri, $action);

    return $this;
}

However I really don't wanna by using my extended class instead of the Laravel\Lumen\Application one.

I realise that there is a setDispatcher method on Application and I was wondering if I can create my own dispatcher that accept a PROPFIND HTTP method and attached to the Lumen\Application using setDispatcher

Here is an explanation about how to override the dispatcher however I'm not sure if that's gonna fix my problem.

0 likes
5 replies
phildawson's avatar

What's the issue in updating the bootstrap/app.php and updating the $app = new Laravel\Lumen\Application( line to yours and extending with your method. Or is this asking is there a better way?

It's a shame addRoute is protected rather than public as it would be simple do this:

$app->addRoute('PROPFIND', 'foo', function(){ return 'bar';});
curl -X PROPFIND http://localhost/foo
bar
phildawson's avatar

Ok so just playing about I noticed the setDispatcher is public which means this works fine.

$app->get('/', function() use ($app) {
    return view('home');
});

$app->setDispatcher(\FastRoute\simpleDispatcher(function ($r) {
    $r->addRoute('PROPFIND', '/foo', [function(){ return 'bar';}]);
}));

$app->get('baz', function() use ($app) {
    return 'qux';
});
zot24's avatar

Thanks for your answer I'm gonna try this last option it's look like a better/cleaner way to do it rather than extending the Application class.

zot24's avatar

The idea is good but is not working properly I can't have both $app->XMETHOD and the $app->setDispatcher it's seem like the setDispatcher method is overwriting the others routes:

...
 /**
     * Principals
     */
    $app->get('/addressbooks'.'/{id}', 'WebDavController@addressbooks');

    $app->setDispatcher(\FastRoute\simpleDispatcher(function ($r) {
        $r->addRoute('PROPFIND', '/principals', 'WebDavController@principals');
        $r->addRoute('PROPFIND', '/principals/{id}', 'WebDavController@principals');
...

Apart of that all the wrapping around $app->group won't be applied, no middleware, no namespace:

...
$app->group(['middleware' => 'auth.basic', 'namespace' => 'Motty\Core\Http\Controllers'], function ($app) {
    /**
     * Principals
     */
...

I'm getting the following error I think because of that:

[2015-06-08 10:09:07] lumen.ERROR: exception 'ErrorException' with message 'Invalid argument supplied for foreach()' in /var/www/core/vendor/laravel/lumen-framework/src/Application.php:1189
Stack trace:
#0 /var/www/core/vendor/laravel/lumen-framework/src/Application.php(1189): Laravel\Lumen\Application->Laravel\Lumen\{closure}(2, 'Invalid argumen...', '/var/www/contac...', 1189, Array)
#1 /var/www/core/vendor/laravel/lumen-framework/src/Application.php(1171): Laravel\Lumen\Application->callActionOnArrayBasedRoute(Array)
#2 /var/www/core/vendor/laravel/lumen-framework/src/Application.php(1146): Laravel\Lumen\Application->handleFoundRoute(Array)
#3 /var/www/core/vendor/laravel/lumen-framework/src/Application.php(1098): Laravel\Lumen\Application->handleDispatcherResponse(Array)
#4 /var/www/core/vendor/laravel/lumen-framework/src/Application.php(1320): Laravel\Lumen\Application->Laravel\Lumen\{closure}()
#5 /var/www/core/vendor/laravel/lumen-framework/src/Application.php(1099): Laravel\Lumen\Application->sendThroughPipeline(Array, Object(Closure))
#6 /var/www/core/vendor/laravel/lumen-framework/src/Application.php(1037): Laravel\Lumen\Application->dispatch(NULL)
#7 /var/www/core/public/index.php(28): Laravel\Lumen\Application->run()
#8 {main}

So I think I'm gonna stick with the extended class, as you said is a shame we don't have a public addRoute mehtod :S

Thanks,

zot24's avatar
zot24
OP
Best Answer
Level 2

Just to keep this updated I submit a PR to change the privacy of the addRoute method from protected to public and have been approved so for now on it'll be as easy as from our route.php file do something like:

$app->addRoute('PROPFIND', '/principals', 'WebDavController@principals');

Thanks,

1 like

Please or to participate in this conversation.