CakePHP Custom Route Classes - How to Pass Arguments? - cakephp

I've created a custom route class and I want to be able to pass in settings/options to the constructor so that it's configurable. Can this be done?
Documentation for Custom Route Classes:
http://book.cakephp.org/2.0/en/development/routing.html#custom-route-classes
My custom route class:
https://github.com/Signified/CakePHP-Model-Route-Class

You can probably just pass any settings/options you might have in the options of your Router::connect function.
App::import('Lib', 'ModelRoute');
Router::connect('/', array('controller' => 'pages', 'action' => 'display'),
Array('routeClass' => 'ModelRoute',
'someMoreOptions' => 'OptionValue' ));
Then you can retrieve the key someMoreOptions in your constructor
public function __construct($settings = array())
{
$this->settings = Set::merge($this->settings, $settings);
// Now you can do something with the option passed.
if(isset($this->settings['someMoreOptions'])
DoSomethingWith($this->settings['someMoreOptions']);
}

Related

CakePHP3 routing: pass static variable to controller action

I trying to pass "language" param from CakePHP3 route, to the action, so I can set the language for those pages.
$routes->connect('/es/hola', ['controller' => 'StaticPages', 'action' => 'welcome']);
$routes->connect('/en/hello', ['controller' => 'StaticPages', 'action' => 'welcome']);
The only way I can make it work is using a dynamic parameter like this:
$routes->connect('/:lang/hola', ['controller' => 'StaticPages', 'action' => 'welcome'], ['pass' => ['lang']]);
But the problem is this route will be match:
/en/hola
/es/hello
...
/fr/hello
I think it should be another best way to do this in CakePHP3, but I can't find this.
Thanks!
If you don't want it to be dynamic, then you need to pass it in the defaults, ie alongside the controller and action:
$routes->connect(
'/es/hola',
[
'controller' => 'StaticPages',
'action' => 'welcome',
'lang' => 'es'
]
);
In the controller the parameter will be available via the request object:
$lang = $this->request->getParam('lang'); // param('lang') before CakePHP 3.4
If you want it to be passed as an argument to the controller action, you can still define it to be passed via the pass option.
See also
Cookbook > Routing > Connecting Routes
API > \Cake\Routing\RouteBuilder::connect()

How to dynamically load a component with settings in CakePHP 2?

I understand that we can pass settings for a component when we define the component at the start of a controller. Example from the CakePHP 2.0 Cookbook
public $components = array(
'Auth' => array(
'authorize' => array('controller'),
'loginAction' => array(
'controller' => 'users',
'action' => 'login'
)
),
'Cookie' => array('name' => 'CookieMonster')
);
But I usually load components on the fly like so (also from the Cookbook)
$this->OneTimer = $this->Components->load('OneTimer');
While using the second method (loading a component on the fly), how can I pass settings to it so that I can use them in the constructor to correctly setup the component based on the settings?
Any help would be greatly appreciated.
2 minutes after asking the question I looked at the load function in the library and found that settings is the second argument for the function.
public function load($component, $settings = array())
So I just need to supply the settings as the second parameter when I load components on the fly.

Cakephp Routing to generate URL parameter

Simple question for Cakephp 2.0.
I want to set a routing rule such that:
www.abc.com/z/abc123
will resolve to the full URL of (including the URL parameter)
www.abc.com/bookings/bookingref/?ref=abc123
Where bookings is the Controller, and bookingref is the action.
Can someone teach me what I need to write in the routes.php?
Kevin
In routes.php:
Router::connect('/bookingref/', array('controller' => 'bookings', 'action' => 'bookingref'));
In controller:
public function bookingref(){
}
So you should have a view name after your function. i.e. bookingref.ctp
This is how I would implement your solution:
In Config/routes.php add:
Router::connect('/z/:reference',
['controller' => 'bookings', 'action' => 'bookingref'],
[
'pass' => ['reference'],// Passed to corresponding function argument (order matters if 2 or more)
'reference' => '[a-z0-9]+'// RegExp validation if you need it
]
);
In your BookingsController use:
public function bookingref($reference = null)
{
...
}
Unfortunately, Router::redirect() cannot redirect to string based URLs that include variables. The controller based approach Progredi mentioned is your best bet.

add helpers to static pages and layouts

Can I add a helper to my static page (for example my homepage) and layouts?
How? (Because no actions are available. In PagesContoller.php, we've display action. I add a home action, but it is overridden by display action)
To use a Helper in every controller and layout you can load in AppController.php:
<?php
class AppController extends Controller {
public $helpers = array('Form', 'Html', 'Js', 'Time', 'MyCustomHelper');
}
?>
Your home action will not work because of the default settings in Config/routes.php:
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
Any passed argument to /pages/ is sent to the display action. Either create a new route for functions in PagesController or create a new controller.
Example route to get PagesController functions to work:
Router::connect('/pages/show/:action/*', array('controller' => 'pages'));
(Place this route before your /pages/* route!)

Adding a controller function for the "home" view in CakePHP

When visiting a default CakePHP site, it takes you to "home.ctp" page.
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
I want to add a few elements there (like blog posts), so I thought I could just add this to the PagesController() class:
public function home() {
$this->set('blogposts', $this->Blogpost->find('all'));
}
But that does not work.
So: what is the correct way to add something like this on the home page (or any other page for that matter)
The preferred option is to create a custom route for the home page but you can also override the PagesController's display function
Option 1: (Preferred Method)
Router::connect('/', array('controller' => 'mycontroller', 'action' => 'myaction'));
Option 2
Router::connect('/', array('controller' => 'pages', 'action' => 'home'));
Option 3:
class PagesController {
function display()
{
// default controller code here
// your custom code here
}
}
The final option is using requestAction in your view, but it isn't recommended as it has a huge performance drawback
Option 4: (Not recommended)
$newsitems = $this->requestAction(array('controller' => 'newsitems', 'action' => 'getlatestnews', 'limit' => 10));
In fact, the action is display, home is a parameter. So your main method in the Controller Pages must call display, not home. After that, create display.ctp view.
Reference:
Routing
To actually answer the original question:
$this->loadModel('Blogpost');
Ideally the model should be called
$this->loadModel('BlogPost');

Resources