开发者

How to make an action for missing actions?

I am very new to cakePHP.

I am working on a controller like so:

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.nam开发者_开发知识库e' => $designer)));
        $this->set('data', $data);  
        $this->render('show_designer');
    }
    
}

As you can see many of the "actions" are shortcuts for show_designer/param action where param is the name of the shortcut action.

Every one of these actions is a "designer" in the database. I just don't want to have to make the url designers/show_designer/ritani, I would rather it just be designers/ritani.

This works, but the problem is:

I have to create a bunch of redundant functions for every designer, and if a new designer gets added, it won't work until I add a function for it.

I would rather have a function/action that runs if the action requested is missing, and has the action that was requested as a parameter

so if I request url designers/stardust, since stardust is not defined as an action it would call the catch_all action with stardust as the parameter.

So instead of a bunch of redundant functions I could just have this:

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

Is there anyway to do something like this?


Use routing instead

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

In your controller

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


have you tried adding a call method:

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

Im not 100% shore how cake calls its methods but it should work:

Example of the usage:

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

This would output:

SomeNonExistantmethod called:
param: param 1
param: param 2

your class would be like so:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜