Как сделать действие за пропущенные действия? - PullRequest
0 голосов
/ 03 декабря 2010

Я очень новичок в 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/paramaction, где param - это имя ярлыка.

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

Это работает, но проблема в следующем:

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

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

, поэтому, если я запрашиваю url designers/stardust, так как stardust не определяется как действие, оно будетвызовите действие catch_all с stardust в качестве параметра.

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

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

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

Ответы [ 2 ]

4 голосов
/ 03 декабря 2010

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

// 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');
        }
    }
}
0 голосов
/ 03 декабря 2010

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

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

Я не на 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');
    }
}
...