CakePHP 3 - Rename controller in routes.php - url-routing

What would be the correct way to reroute all actions from fakeController to controller1 using Cake's routing engine?
I'd like to reroute actions index and any other actions and also parameters.
app/fake/ => app/controller1/
app/fake/action1 => app/controller1/action1
app/fake/action2/any/params => app/controller1/action2/any/params
Is it possible with just one line of code?
Why I am doing this? - because in CakePHP 3 the routes are case-sensitive. I'd like to keep my controllers names UpperCase, but it results in paths like app/Users/login, if I write users it says usersController not found. If there is a way around this, I wouldn't need all this rerouting.

The default route is case-sensitive, yes, however by default there should be fallbacks defined using the InflectedRoute class, which behave as known from 2.x, ie it will inflect users to Users (as of 3.1.0 the default is DashedRoute, which inflects too).
https://github.com/cakephp/app/blob/3.0.4/config/routes.php#L73
If you want this to be the default behavior (note that this is relatively slow) for all routes, then simply set this to be the default via Router::defaultRouteClass()
Router::defaultRouteClass('InflectedRoute');
https://github.com/cakephp/app/blob/3.0.4/config/routes.php#L42
or in order to restrict it to a specific scope, use the fallbacks() method.
$routes->fallbacks('InflectedRoute');
https://github.com/cakephp/app/blob/3.0.4/config/routes.php#L73
Alternatively you could create appropriate routes for all your controllers, similar to as shown in your apps routes.php file:
Router::scope('/', function (\Cake\Routing\RouteBuilder $routes) {
// ...
$routes->connect('/users', ['controller' => 'Users', 'action' => 'index']);
$routes->connect('/users/:action/*', ['controller' => 'Users']);
$routes->connect('/foos', ['controller' => 'Foos', 'action' => 'index']);
$routes->connect('/foos/:action/*', ['controller' => 'Users']);
// and so on...
});
https://github.com/cakephp/app/blob/3.0.4/config/routes.php#L60-L62
See Cookbook > Routing for more information about routing.

Related

How to have different dashboards based on roles with cakedc plugins / users & acl

I am using CakeDC Users & ACL plugins in my CakePhp app. I have different roles for my users in my app and I would like to have different dashboards based on roles after login.
I extend the plugin with my own table and controller based on the documentation here, so I have MyUsersController and MyUsersTable which override the initial files of the plugin, UsersController and UsersTable. Everything works fine. I create an event in my events.php file which contains:
use CakeDC\Users\Controller\Component\UsersAuthComponent;
use Cake\Event\Event;
use Cake\Event\EventManager;
EventManager::instance()->on(
UsersAuthComponent::EVENT_AFTER_LOGIN,
['priority' => 99],
function (Event $event) {
if ($event->data['user']['role_id'] === 'bbcb3031-ebed-445e-8507-f9effb2de026') //the id of my client role{
return ['plugin' => 'CakeDC/Users', 'controller' => 'MyUsers', 'action' => 'index', '_full' => true, 'prefix' => false];
}
}
);
But it seems like the override is not working because I have an error:
Error: CakeDC/Users.MyUsersController could not be found.
In my URL I have /users/my-users instead of /my-users and I don't know why. I have test with a template file which is include in the plugin and the Users controller like this:
function (Event $event) {
if ($event->data['user']['role_id'] === 'bbcb3031-ebed-445e-8507-
f9effb2de026') //the id of role{
return ['plugin' => 'CakeDC/Users', 'controller' => 'Users', 'action' => 'profile';
}
And it works. My URL redirect after login as a client is /profile.
Could someone help me to understand? Please tell me if it's not clear enough and if it's missing parts of codes that might be important to understand my problem.
I specify that I am beginner with Cake.
Your custom controller doesn't live in the CakeDC/Users plugin, hence you must disable the plugin key accordingly, so that the correct URL is being generated (assuming your routes are set up correctly) that connects to your controller, like this:
[
'plugin' => null,
'controller' => 'MyUsers',
'action' => 'index',
'_full' => true,
'prefix' => false
]
That would for example match the default fallback routes, generating a URL like /my-users.
See also:
Cookbook > Routing > Creating Links to Plugin Routes

CakePHP 3 : link to any action in PagesController opens same action

I have to link to different actions in PagesController.
I have created many static pages and for that I have defined an action like
public function contact(){
}
now when I access www.mysite.com/pages/contact instead of opening contact.ctp it opens the default display action.
The routes.php file contains
Router::defaultRouteClass('DashedRoute');
Router::scope('/', function (RouteBuilder $routes) {
$routes->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);
$routes->connect('/pages/*', ['controller' => 'Pages', 'action' => 'display']);
$routes->fallbacks('DashedRoute');
});
Plugin::routes();
How can I access the static pages or other actions of PagesController?
$routes->connect('/pages/:action/*', ['controller' => 'Pages']);
Now you can call to diferent actions. e.g.
www.mysite.com/pages/contact
www.mysite.com/pages/about
www.mysite.com/pages/someaction
The default routing for the PagesController is to direct everything to the display action.
In order to add additional actions, you would need to route these specifically.
$routes->connect('/pages/contact', ['controller' => 'Pages', 'action' => 'contact']);
Or, alternatively, if you do not want everything to go through the display action, remove the specific line in routes.php that directs everything there. CakePHP would auto-route anything beginning with /pages/ to the PagesController, and anything after the slash to it's appropriate action.
If you make the view file src/Template/Pages/contact.ctp you can access it using the URL http://example.com/pages/contact
No need to change anythin in routes.php they are fine. No need to create a method in your PagesController, this is a simple and optional controller for serving up static content.

Kohana 3.2 routing issue

I have set up my routes so that most classes are called in the standard controller/action style. However for my front end I don't want users to see the action being called, so all front end pages have their own controller and use the index action. These are my routers in bootstrap:
Route::set('normal', '<controller>(/<action>(/<arguments>))',
array(
'arguments' => '.*'
))
->defaults(array(
'controller' => 'admin',
'action' => 'index',
));
Route::set('default', '(<controller>(/<arguments>))',
array(
'arguments' => '.*',
))
->defaults(array(
'controller' => 'home',
'action' => 'index',
));
I currently have three front end pages, home, about_us and services. They all work great if I don't pass any arguments in through the URL, but the problem occurs if I try to pass an argument in through the URL into arguments. In services there is only action_index() to display the page and it checks for any arguments, and displays results based on the argument. However if I try to browse to /services/1 to pass in 1 as an argument I get this 404 error:
Kohana_HTTP_Exception [ 404 ]: The requested URL services/1 was not found on this server.
It just uses the first route, normal. Once it can't find the action it doesn't even try to use the second route, which would work. If I swap the order of the routes then it works, but all my other classes that use the first controller stop working as all my actions get passed to action_index() as arguments.
How can I get this working? Why when the first route doesn't work does Kohana not go on to the second route?
You do not need to create controller per route. You can create custom routes (route names) and specify controller and action name. Read the documentation for further explanation. Routing
For arguments try this:
Route::set('default', '(<controller>(/<arguments>))',
->defaults(array(
'controller' => 'home',
'action' => 'index',
));

Cakephp route matches everything

I have following route added to routes.php in the end.
Router::connect('/:sellername/:itemtitle',
array('controller' => 'items', 'action' => 'view_item_detail'),
array(
'pass' => array('sellername','itemtitle'),
'sellername' => '[a-zA-Z0-9_-]+',
'itemtitle' => '[a-zA-Z0-9_-]+',
)
);
So this matches the dynamic urls like http://example.com/john/title-of-an-item
Problem is this also matches every other url like http://example.com/members/signin even though there's a MembersController controller and signin action in it.
I can fix it using following route entry.
Router::connect(
'/members/:action',
array('controller' => 'members')
);
But it's very tedious to add every route like above.
Doesn't existing matching controller names are prioritized while making a match?
Do order of routes in routes.php matter?
Custom Route classes is to help you
Custom route classes allow you to extend and change how individual routes parse requests and handle reverse routing. A route class should extend CakeRoute and implement one or both of match() and/or parse(). parse() is used to parse requests and match() is used to handle reverse routing.
You can use a custom route class when making a route by using the routeClass option, and loading the file containing your route before trying to use it:
Router::connect(
'/:slug',
array('controller' => 'posts', 'action' => 'view'),
array('routeClass' => 'SlugRoute')
);
This route would create an instance of SlugRoute and allow you to implement custom parameter handling.
custome routing class let you impliment anything
But personal opinion is to user a static and meaning full text in the url that diffrenciate it from the rest.

Cakephp route and prefix

I have a problem with Routes in CakePHP. Let me explain.
I'm using authentication through the Auth component. I have a routing prefix called account.
When I want to edit a user, I'm calling the users controller which gives me a URL like:
/account/users/edit/5
What I want is to have a URL like:
/account/edit/5
So I changed my router like this:
Router::connect('/:prefix/edit/:id',
array('controller' => 'users', 'action' => 'edit'),
array('pass' => array('id'), 'id' => '[0-9]+')
);
which worked when I try to access /account/edit/5
My problem is located in my view. How can I access this route using the Html->link helper?
So far, I'm just doing it like this:
'/'.$this->Session->read('Auth.User.role').'/edit/'.$this->Session->read('Auth.User.id')
But it's not really clean in my opinion. I want to use the helper.
Thanks a lot for your help
Using a prefix "account" would mean needing an action like "account_edit" in your controller. That's probably not what you want. Also why put the "id" in url when it's already there in the session? Why not just use url "/account" for all users and get the id (and role if required) from session in the action?
Router::connect('/account',
array('controller' => 'users', 'action' => 'edit')
);
This would be the clean way to generate required url:
$this->Html->link('Account', array(
'controller' => 'users',
'action' => 'edit'
));
// Will return url "/account"
In general always use array form to specify url to benefit from reverse routing.
everything is just fine except router. it should be
Router::connect('/account/*',
array('controller' => 'users', 'action' => 'edit')
);
and creating anchor link in various way using Helper you can CHECK HERE

Resources