2010-12-02 2 views
0

Я очень новичок в cakePHP.Как сделать действие для отсутствующих действий?

Я работаю на контроллере так:

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'); 
    } 

} 

Как вы можете видеть, многие из «действий» являются ярлыками для show_designer/param действия, где param это имя контекстного действия.

Каждое из этих действий является «конструктором» в базе данных. Я просто не хочу писать url designers/show_designer/ritani, я бы предпочёл, чтобы это было просто designers/ritani.

Это работает, но проблема:

Я должен создать кучу избыточных функций для каждого дизайнера, и если новый дизайнер будет добавлен, он не будет работать, пока я не добавить функцию Это.

Я предпочел бы иметь функцию/действие, которое будет выполняться, если запрошенное действие отсутствует, и имеет действие, которое было запрошено в качестве параметра

поэтому, если я URL запроса designers/stardust, поскольку StarDust не определен как действие, которое оно назвало бы действием catch_all с stardust как параметр.

Так вместо того, чтобы куча избыточных функций я мог просто так:

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

Есть в любом случае, чтобы сделать что-то вроде этого?

ответ

4

Использование маршрутизации вместо

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

В контроллере

// 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

не забудьте проверить на "существует" первая ... – mark 2010-12-03 02:05:51

0

вы пробовали добавить метод вызова:

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

Im не 100% берег, как пирожное называет свои методы, но он должен работать:

Пример использования:

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"); 

Это выведет:

SomeNonExistantmethod called: 
param: param 1 
param: param 2 

ваш класс будет выглядеть примерно так:

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'); 
    } 
}