Laravel 4 nous fournit les contrôleurs de ressource RESTful. Mais généralement j’ai rarement des ressources définies de façon linéaires, elles sont généralement imbriquées.
Pour un blog, on a : catégories (0->n) posts (0->n) commentaires
pour un site marchand, ce sera : categories (0->n) produits
Puisque qu’un « commentaire » est obligatoirement attaché à un « post », et que ce post est nécessairement dans une « catégorie » nous pouvons très bien imbriquer ces contrôleurs REST.
ce qui donnerait par exemple : GET /categorie/machines/produit/44
Merci Laravel :), il nous permet d’imbriquer très simplement des controleurs REST; voici la solution de route pour Laravel :
// route.php Route::resource('categorie', 'CategorieController'); Route::resource('categorie.produit', 'CategorieProduitController');
Le reste est classique: utiliser php artisan en ligne de commande pour créer ces contrôleurs :
php artisan controller:make CategorieController php artisan controller:make CategorieProduitController
Pour test, je ne vais remplir que quelques méthodes :
<?php // app/controllers/CategorieController.php class CategorieController extends \BaseController { /** * Display a listing of the resource. * GEt /categorie/ * @return Response */ public function index() { echo Route::currentRouteName().'<br>'; echo "Categorie::index toutes categories "; } /** * Display the specified resource. * GET /categorie/{$id} * @param int $id * @return Response */ public function show($id) { // meme chose que GET /categorie/{$listId}/produit echo Route::currentRouteName().'<br>'; echo "Categorie::show la categorie : \"$id\", tous produits "; }
Ce contrôleur(parent) est des plus classique, il n’y a aucune distinction avec un contrôleur REST autonome.
Le contrôleur imbriqué (Produit), lui est particulier, en fait, toutes ces méthodes prennent un paramètre supplémentaire. Ce paramètre est le paramètre passé au controleur parent. Attention, ce paramètre n’est pas généré par la commande php artisan 🙁
<?php // app/controllers/CategorieProduitController.php class CategorieProduitController extends \BaseController { /** * Display a listing of the resource. * GET /categorie/{$listId}/produit * @return Response */ public function index($listId) { // tous les produits de la categorie // meme que GET /categorie/{$listId} echo Route::currentRouteName().'<br>'; echo "index:: categorie : $listId, tous produits "; } /** * Display the specified resource. * @param int listId categorie * @param int $id id du produit * @return Response */ public function show($listId, $id) { echo Route::currentRouteName().'<br>'; echo "show:: categorie : $listId, produit id: $id"; } /** * Show the form for editing the specified resource. * @param int listId categorie * @param int $id * @return Response */ public function edit($listId, $id) { echo Route::currentRouteName().'<br>'; echo "edit:: categorie : $listId, produit id: $id"; }
Nous pouvons utiliser ces 2 contrôleurs comme :
/categorie/44/ /categorie/44/produit/22 /categorie/44/produit/22/edit
Bien sur « $listId » n’est pas obligatoirement un id, on peut désirer une route de la forme :
/categorie/nouveautés/produit/22, le slug est nettement recommandé pour le référencement.