2010-12-02 3 views
0

Je suis très nouveau à cakePHP.Comment faire une action pour des actions manquantes?

Je travaille sur un contrôleur comme ceci:

class DesignersController extends AppController 
{ 
    var $name = 'Designers'; 

    function index() 
    { 
     $data = $this->Designer->find('all'); 
     $this->set('designers', $data); 
    } 

    function belle_etoile() 
    { 
     $this->show_designer("belle etoile"); 
    } 

    function ritani() 
    { 
     $this->show_designer("ritani"); 
    } 

    function swarovski() 
    { 
     $this->show_designer("swarovski"); 
    } 

    function verragio() 
    { 
     $this->show_designer("verragio"); 
    } 


    private function show_designer($designer) 
    { 
     $this->layout = 'first'; 
     $data = $this->Designer->find('first', array('conditions' => array('Designer.name' => $designer))); 
     $this->set('data', $data); 
     $this->render('show_designer'); 
    } 

} 

Comme vous pouvez le voir bon nombre des « actions » sont des raccourcis pour l'action show_designer/paramparam est le nom de l'action de raccourci.

Chacune de ces actions est un "concepteur" dans la base de données. Je ne veux pas avoir à faire l'url designers/show_designer/ritani, je préfère être designers/ritani.

Cela fonctionne, mais le problème est:

Je dois créer un tas de fonctions redondantes pour chaque concepteur, et si un nouveau concepteur est ajouté, il ne fonctionnera pas jusqu'à ce que j'ajouter une fonction pour il.

Je préférerais avoir une fonction/action qui fonctionne si l'action demandée est manquante, et a l'action qui a été demandé en tant que paramètre

donc si je demande url designers/stardust, puisque stardust n'est pas défini comme une action qu'il appellerait l'action catch_all avec stardust comme paramètre.

Ainsi, au lieu d'un tas de fonctions redondantes je pouvais avoir ceci:

function catch_all($action) 
{ 
    $this->show_designer($action) 
} 

Y at-il de toute façon de faire quelque chose comme ça?

Répondre

4

utiliser le routage au lieu

// add this to app/config/routes.php 
Router::connect('/designer/*', array('controller' => 'designers', 'action' => 'designer')); 

Dans votre contrôleur

// and remove all actions 'belle_etoile', 'swarovski' etc 
// change `show_designer` to `public designer` 
class DesignersController extends AppController { 
    var $name = 'Designers'; 

    function designer($name) 
    { 
     $this->layout = 'first'; 
     $data = $this->Designer->find('first', array('conditions' => array('Designer.name' => $name))); 
     if(!empty($data)) { 
      $this->set('data', $data); 
      $this->render('show_designer'); 
     } else { 
      $this->redirect('index'); 
     } 
    } 
} 
+1

Ne pas oublier de vérifier "existe" d'abord ... – mark

+0

comme tu dis @mark – Ish

0

Avez-vous essayé d'ajouter une méthode d'appel:

function __call($action,$params = array()) 
{ 
    $this->show_designer($action) 
} 

Im pas shore 100% comment le gâteau appelle ses méthodes, mais cela devrait fonctionner:

Exemple de l'utilisation:

finale class Test 
{ 
    function __call($action,$params = array()) 
    { 
     echo $action . " called:<br />"; 
     foreach($params as $param) 
     { 
      echo "Param: "$param . "<br />"; 
     } 
    } 
} 
$test = new Test(); 
$test->SomeNonExistantmethod("param 1","param 2"); 

Cette génèrerait:

SomeNonExistantmethod called: 
param: param 1 
param: param 2 

votre classe serait comme si:

class DesignersController extends AppController 
{ 
    var $name = 'Designers'; 
    var $allowed = array(
     "belle_etoile", 
     "ritani", 
     "swarovski", 
     "verragio" 
    ); 

    function index() 
    { 
     $data = $this->Designer->find('all'); 
     $this->set('designers', $data); 
    } 

    function __call($action,$params = array()) 
    { 
     if(in_array($action,$this->allowed)) 
     { 
      $this->show_designer($action); 
     } 
    } 

    private function show_designer($designer) 
    { 
     $this->layout = 'first'; 
     $data = $this->Designer->find('first', array('conditions' => array('Designer.name' => $designer))); 
     $this->set('data', $data); 
     $this->render('show_designer'); 
    } 
} 
Questions connexes