Respect/Rest

By Routine (before)

Closed this issue · 8 comments

Hi everyone,
I need some help. I 'm doing something wrong.

When use "By Routine (before)" I have this error: "Catchable fatal error: Argument 1 passed to Respect\Rest\Routines\When::when() must be an instance of Respect\Rest\Request, "...

This is my code:

$router = new Router;

$myLogger = new Auth;

$router->get('/bookmarks', 'MyBookmarks')->by(function() use ($myLogger) {
        return $myLogger; //return true or false if isset session
});

I need pass $router in use()?

Thaks.

Sorry my english is not verry good.

The by Routine is expecting a boolean returned, may this be the problem?

Please provide the whole stack trace and use the develop branch which will be the latest source and what we would use to solve your problem with.

You do not need to pass router but the problem could be related to your MyBookmarks class and not the by function perse. Which I would only be able to tell if you provide more information please.

I'm pass by Routine a boolean parameter $myLogger return true or fouse.

My MyBookmarks class is simples, following this reference http://respect.li/docs/Rest/#feature-guide/class-controllers. See

use Respect\Rest\Routable;

class MyBookmarks implements Routable
{
    public function get()
    {
        return 'do something';
    }
} // END class MyBookmarks

thanks for support...

@williamespindola Let me see if I can help also :)

In the example you gave in your first comment, the $myLogger is an instance fo Auth. As @nickl- pointed out, you can return basically 3 things from the function passed as argument to by():

  • A boolean value:
    • TRUE so the route gets executed
    • FALSE to NOT execute the given route
  • Another instance that implements the Respect\Rest\Routable interface

The Exception described by you in the first comment, could be possibly caused by the $myLogger being identified as an object by Respect\Rest (and not a boolean value) that does not implement the required interface.

PS: In what language are you more confortable writing? Or talking?

Português @augustohp

by() esta esperando um valor boleano certo? Se eu passar isto para ele, tenho o mesmo erro. E pelo que vi na classe by() ele espera mesmo uma instancia de de Respect\Rest\Request. Não é por isto que estou tendo este erro?

.../Respect/Rest/Routines/By.php

    public function by(Request $request, $params)
    {
        return call_user_func_array($this->callback, $params);
    }

@williamspindola Some mistakes on our part, sorry for that 😢 By does not affect route matching at all, it only gets executed before the route (at least that we got right 😊). Contrary to when, that if something that can be evaluated as false is returned a 400 Bad Request header is set.

Also, I already missed passing objects that are callable to routines, thanks to you I did a quick increment to make that happen. This is still not merged neither published on anywhere, but you can use the code on the issue-85 branch.

Note: If you are using composer you can test that code by specifying dev-issue-85 as version as noted on the documentation. Let me know if that works for you.

Hi @augustohp thanks for your help. But still we have problem :( the Catchable fatal error persist!
I did a test I put the Request object as first paramater of by method and got the following error:
Warning: call_user_func_array() expects parameter 1 to be a valid callback, no array or string given in /Users/rodrigodasilvarodrigues/Sites/celmar/vendor/Respect/Rest/library/Respect/Rest/Routines/AbstractSyncedRoutine.php on line 51

I saw your commit and realized that you changed call_user_func_array() by $this->execute in some class, and error above is this method $this->execute.

I have a question! In this function the variable $callback should return a function or a class right? Because this returning null.

Sorry by my bad english, but continue write in english. I have that take shame in my face and learning this shit!

Considering that Auth is a Routinable (a class routine that you've coded and implements the Respect\Rest\Routines\Routinable interface), you should do it by using:

<?php
$router->get('/bookmarks', 'MyBookmarks')->appendRoutine($myRoutinable);

Considering that Auth is not a Respect instance, This is not supported:

<?php
$router = new Router;

$myLogger = new Auth;

$router->get('/bookmarks', 'MyBookmarks')->by(function() use ($myLogger) {
        return $myLogger; //return true or false if isset session
});

The by occours before the route was run, and it's not intended to pass arguments to the route. by can accept two kinds of return methods:

  • true, which will continue
  • false, which will stop that route
  • An instance of AbstractRoute, which will do an internal forward to that route

Returning a logger won't do nothing. This is not expected.

Some possible uses for the logger could be:

Record on by:

<?php
$router = new Router;

$myLogger = new Auth;

$router->get('/bookmarks', 'MyBookmarks')->by(function() use ($myLogger) {
        $myLogger->log('Bookmarks accessed');
});

Record on through:

<?php
$router = new Router;

$myLogger = new Auth;

$router->get('/bookmarks', 'MyBookmarks')->through(function() use ($myLogger) {
        return function($data) use ($myLogger) { //return inner closure to handle data
            $myLogger->log('Bookmarks accessed by '.$data->user);
        }
});

You can also use always to apply the logger to all routes at once if you need. http://respect.li/docs/Rest/#feature-guide/controller-splitting

@williamespindola I didn't quite understand what you said by "passed the Resquest instance". Passin the class name of you routine (or an instance of it) should just work 😢 Also, as noted by @alganet I was really wrong on my last comment when I said by() does not affect routing.

I also tested that code against PHP 5.3.2 (OSX 10.8) and it works, so we must have run on a communication problem =P Feel free to talk in portuguese and ask anything that is not clear to you, If you don't mind, I do rather answer in english so other people can follow this discussion (it may be helpful in the future).

Summing things up, the following code should work using the issue-85 branch:

<?php
$router = new Respect\Rest\Router();
// Made this work in the latest commit of the branch
$router->get('/', 'Hello world!')->by('MyNamespace\Routines\Authentication');
// This also works (as I said on the latest comment)
$router->get('/', 'Hello world!')->by(new MyNamespace\Routines\Authentication);