[RESOLU] [Silex] SecurityProvider Fakeroute

Zef
Petit nouveau ! | 5 Messages

18 mars 2013, 23:59

Bonjour !

J'ai un petit soucis avec Silex et le composant Security de symfony. Il me renvoie l'erreur suivante:

"LogicException: The controller must return a response (null given). Did you forget to add a return statement somewhere in your controller?"

Après plusieurs heures de recherche j'ai compris que c'est parce que le controller qui est appeler est en faite une fonction vide :

Dans le SecurityServiceProvider, je passe par la fonction anonyme function() {} qui ne renvoie rien (j'ai vérifier à coup de breakpoints).
<?php
public function boot(Application $app)
    {
        // FIXME: in Symfony 2.2, this is a proper subscriber
        //$app['dispatcher']->addSubscriber($app['security.firewall']);
        $app['dispatcher']->addListener('kernel.request', array($app['security.firewall'], 'onKernelRequest'), 8);
 
        foreach ($this->fakeRoutes as $route) {
            list($method, $pattern, $name) = $route;
 
            $app->$method($pattern, function() {})->bind($name);
        }
    }
?>
Je ne comprend pas comment résoudre ce problème...

Pour information voici ma config:
<?php
 
define('ROOT_DIR', realpath(__DIR__.'/../../..'));
 
require_once ROOT_DIR.'/vendor/autoload.php';
 
$app = new \Silex\Application();
 
require_once __DIR__.'/config/load.php';
 
use \Symfony\Component\HttpFoundation\Request;
use \Symfony\Component\HttpFoundation\Response;
 
$app->register(new \Propel\Silex\PropelServiceProvider(), array(
    'propel.path'        => ROOT_DIR.'/vendor/propel/propel1/runtime/lib/Propel.php',
    'propel.config_file' => ROOT_DIR.'/resources/propel/build/conf/Higgs-conf.php',
    'propel.model_path'  => ROOT_DIR.'/resources/propel/build/classes',
));
$app->register(new \Silex\Provider\ValidatorServiceProvider());
$app->register(new \Silex\Provider\FormServiceProvider());
$app->register(new \Silex\Provider\SessionServiceProvider());
$app->register(new \Silex\Provider\SecurityServiceProvider(), array(
    'providers' => [
        'main' => [
            'entity' => [
                'class' => '\Higgs\Model\User',
                'property'  =>   'username'
            ]
        ]
    ]
    // TODO : http://symfony.com/doc/current/book/security.html
));
 
$app['security.firewalls'] = array(
    'main' => array(
        'pattern' => '^/User',
        'form' => array(
            'check_path'                     => '/User/login2',
            'login_path'                     => '/login',
            'default_target_path'            => '/logged',
        ),
        'anonymous' => '~',
    ),
);
 
$app->before(function (Request $request) {
    if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
        $data = json_decode($request->getContent(), true);
        $request->request->replace(is_array($data) ? $data : array());
    }
});
 
// include API
call_user_func(function () use($app) {
    chdir(__DIR__.'/Route');
    foreach (glob('*.php') as $file) {
        $api = substr($file,0,-4);
        $controller = '\\Higgs\\API\\Route\\'.$api;
        $app->mount('/'.$api, new $controller);
    }
});
 
$app->error(function(\Exception $e, $code) use($app) {
    if ($app['debug']) return;
    switch ($code) {
        case 400:   $message = 'Bad request';   break;
        case 403:   $message = 'Forbidden'; break;
        case 404:   $message = 'API not found'; break;
        default:    $message = 'Internal Error';
    }
    return new Response($message, $code);  
});
 
$app->after(function(Request $request, Response $response) use ($app) {
    if ($app['debug'] && $response->getStatusCode() != 200)
        return;
    $response->headers->set('Content-type', 'text/json');
});
 
$app->run();
 
?>
Pour tomber sur l'erreur en question j'appel le script avec l'url: localhost/Higgs/User/login2 sachant que Higgs un link vers le dossier "web" de mon projet.
Merci de votre aide !

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

19 mars 2013, 00:08

Le controller par lequel que tu passes ne retourne pas une instance de \Symfony\HttpFoundation\Response.
Montre le code de tes controlleurs, et je vais te montrer ce qui pose soucis
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Zef
Petit nouveau ! | 5 Messages

19 mars 2013, 00:13

Comme je l'ai précisé mais peux être pas assez explicitement du coup, c'est la fonction anonyme de la fakeroute qui joue le rolle de controller. Ce n’est pas moi qui implémente le controller pour le login avec le composant security de symfony, c'est lui même. Le User/login2 vient de la config: 'check_path' => '/User/login2',

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

19 mars 2013, 00:21

Le composant Security fait le matching entre les routes et les controlleurs, mais il faut bien que tu les codes à un endroit, tout de même ;)

D'ailleurs, pourquoi faire le choix de Silex si c'est pour réintégrer des choses tels que le composant Security ?
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Zef
Petit nouveau ! | 5 Messages

19 mars 2013, 00:32

http://symfony.com/doc/current/book/security.html
You will not need to implement a controller for the /login_check URL as the firewall will automatically catch and process any form submitted to this URL.
Et j'ai retrouvé cette information à plusieurs endroits. Donc je confirme, je ne pense pas devoir implémenter le login. Mais je serais très heureux de trouver un exemple d'implémentation basique sans avoir à pomper sur le controller inclus dans le module security :)

Je préfère Silex car il est léger et moins contraignant pour ce que je veux faire. Je préfère avoir à rajouter des modules plutôt qu'à les enlever :)

Merci pour tes réponses en tout cas !

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

19 mars 2013, 12:06

Oula, après une nuit de sommeil, je me rend compte de la bétise que je t'ai dit hier ^^
Alors oui, le composant Security s'occupe lui même des contrôleurs.

Maintenant, j'avoue que je ne comprend pas pourquoi, dans ton cas, ça ne marche pas.
J'aurais initialement dit que tu n'appellais pas la méthode boot (comme décrit ici), mais tu dis que ton debuggage point à point t'as mené dans cette fonction.

Du coup, je ne sais trop que te répondre.
Tu pourrais essayer de passer par le google groups Silex ?
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Zef
Petit nouveau ! | 5 Messages

19 mars 2013, 12:22

Là tu pointes du doigt le problème j'ai peur.
Le débugger (xdebug avec netbeans) m'amène bien dans cette fonction c'est comme ça que j'ai compris que le controller n'était pas appeler.

Par contre je n'ai pas fait le boot c'est surement ce qui cause problème. Dès que je rentre du boulot je test ça et je te tiens au courant !

Si ce n’est pas ça j'essaierai le google groups Silex merci pour le conseil !

Encore merci !

Edit:

Bon en faite c'est pas ça car $app->run() fait le boot() (j'ai quand même essayer de rajouter un $app->boot() avant le run)

Zef
Petit nouveau ! | 5 Messages

21 mars 2013, 11:37

Bon j'ai trouvé fallait faire un POST plutôt qu'un GET :/