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');
}
}
精彩评论