I have a legacy application built in CakePHP 2.2.3
One part of the application has controller file which has been named SymposiumsController.php. This resulted in URL's such as:
domain.com/symposiums
domain.com/symposiums/view/23
The problem is that 'symposiums' isn't a real (English language) word; it should be 'symposia'.
I want to rename my URL's so they are like this:
domain.com/symposia
domain.com/symposia/view/23
I tried to do this by editing app/Config/Routes.php to use this:
Router::connect('symposia/:action', array('controller' => 'symposiums'));
However all this does is redirects domain.com/symposia to domain.com/symposiums which therefore makes no difference to what the user sees in the URL.
To put it simply I don't want 'symposiums' exposed anywhere in my URLs. I want them all to use 'symposia' in it's place.
I read http://book.cakephp.org/2.0/en/development/routing.html but can't see how to do this. Does anyone have a solution? Surely I don't have to rename controllers/models and DB tables to do this?
I don't know if this makes a difference but I also have admin routing switched on so my SymposiumsController.php also has functions such as:
admin_add()
admin_delete()
admin_edit($id)
Any help is appreciated.
Here is the code for this specific redirection:
Router::connect('/:controller/:action/:id',
array('controller' => 'symposiums', 'action' => 'view', 1)
);
:controller => Give the name new name of controller e.g. symposia
:action => Give the name new name of action e.g. view
:id => Give the name new name of controller e.g. 23
But if you need to redirect more than one action then I suggest you to rename the controller.
Note: If you rename the controller or create new Routers then you would need to make sure in the all application modify the link to new controller name.
Source: Cakephp Router
Related
I'm trying to set up a routing prefix in cakephp 3 so any URLs starting with /json/ get the prefix key set and I can change the layout accordingly in the app controller. Other than that, they should use the usual controller and action. I have added the following to routes.php
$routes->prefix('json', function($routes) {
$routes->connect(
'/:controller/:action/*',
[],
['routeClass' => 'InflectedRoute']
);
});
I want to direct all requests with json as first url segment to controller specified in second url segment. e.g. /json/users/add_account_type/ goes to users controller. However when accessing this URL I get the message:
Error: Create the class UsersController below in file:
src/Controller/Json/UsersController.php
whereas I want it to be using
src/Controller/UsersController.php
I think this should be possible but I can't quite see what I'm doing wrong when consulting the book. Have partly based my code on: CakePHP3.x controller name in url when using prefix routing
Thanks a lot in advance
That's simply how prefix routing now works in 3.x, as explained in the docs, prefixes are being mapped to subnamespaces, and thus to separate controllers in subfolders.
http://book.cakephp.org/3.0/en/development/routing.html#prefix-routing
If you'd wanted to change that behavior (I don't really see why), one way would be to implement a custom ControllerFactory dispatcher filter.
http://book.cakephp.org/3.0/en/development/dispatch-filters.html
On a side note, the RequestHandler component supports layout/template switching out of the box, so maybe you should give that a try.
http://book.cakephp.org/3.0/en/controllers/components/request-handling.html
http://book.cakephp.org/3.0/en/views/json-and-xml-views.html
Prefix routing is a way of namespacing parts of your routes to a dedicated controller. It seem that what you want is a scope and not a prefix, for what you describe:
Router::scope('/json', function($routes) {
$routes->fallbacks('InfledtedRoute')
});
In Laravel the default controller is the Home_Controller. However I have a controller called frontend. I want to use this instead of the home controller.
When I register a route like this:
Route::controller(Controller::detect());
then a request to /offer will be handled from within the home controller like home#offer. I want to use frontend#offer and access it from the site's root - not like /frontend/offer.
What should I do?
Thanks in advance.
Home_Controller is one of the hard-coded convention which exist in Laravel 3, however there are still ways to define routing to point the Frontend_Controller methods, my preference would be.
Route::any('/(index|offer|something)', function ($action)
{
return Controller::call("frontend#{$action}");
});
Limitation with this is that you need to define all supported "actions" method in Frontend_Controller.
My guess is that the only reason you think the Home_Controller is some sort of default is because you are using Controller::detect(); I really haven't seen anything in the documentation to make me think that the Home_Controller is anything special at all. In fact, it doesn't even look like it is routed to in the example documentation. Given that, my first suggestion would be to get rid of Controller::detect() and see if that fixes your problem.
Barring that, have you tried registering frontend as route named home? It appears that all URL::home() does is search for the 'Home' route, and then redirect to it. When using controller routing this can be done with something to the effect of.
Route::get('/',
array(
'as' => 'home',
'uses' => 'frontend#index'
)
);
Or is that not your desired effect? Do you want all routes which aren't otherwise found to be redirected to your frontend controller?
If you are concerned about your urls looking pretty, you can probably use some rewrite rules in your .htaccess file to make the whole process of routing to /frontend/index transparent you your users.
Add this to your routes.php :
Route::get('/', array('as' => 'any.route.name', 'uses' => 'frontend#offer'));
If you have any other / route, just remove it.
Being new to Cake on PHP, I am trying to work out if I have a URL, what would be the easiest way to find the controller code for it?
The URL on my local machine is something like:
http://foofoofoo.local/protected/admin/org/edit/1
I have worked out that the location of the view for this file is at this location on my machine:
/var/www/MyApp/protected/app/views/org/admin_edit.ctp
I thought what I'd do is do a search throughout the entire codebase for anything referencing admin_edit.ctp. I found two entries, and changed them to see if I had found the point where the view is called, but despite changing the file name on these entries - the app still works when I visit the URL: http://foofoofoo.local/protected/admin/org/edit/1
I just want to see where the admin_edit.ctp file is being called within the site.
URL: http://foofoofoo.local/protected/admin/org/edit/1
This means I can assume you have a added a route in your /app/Config/routes.php. Where this is pointing can not be said since we don't have access to this file.
Why can I assume you have added this to your routes? Because the posted URL is not matching the CakePHP Conventions which clearly states that controllers should be defined in plural. Since the URL will be accessing the Controller directly through the Controller, unless a route has been specified, I know that the OrgController does not exist. Why?
Try Inflector::pluralize('Org'). It will return 'Orgs' to you. And thus meaning the controller should be called OrgsController and you should be accessing this Controller via the following URL.
http://foofoofoo.local/protected/admin/orgs/edit/1
In this OrgsController there should be an action (function) called admin_edit(), because you have prepended the org with Admin, which is a prefix.
It can be possible that the /protected part, is part of the URL as well, but do not know where your main /App is located and what part of the URL is pointing to the /app/webroot/index.php file.
The Views can be found at /app/View/Orgs/*.ctp.
If you are still having trouble finding your files. Please start with the Blog tutorial written by the Cake Community. This tutorial describes all the neat built-in tricks and will get your first app running in no-time. Please read that first!
If you are still having trouble, feel free to update your question and add the /app/Config/routes.php file.
Under Cake 1.3, if your application has an AppController (check if the file app/app_controller.php exists), you can put this code in the beforeFilter method:
debug($this->params);
It will print an array on your app pages when you are in debug mode, with the name of the controller and the action used.
Array
(
...
[controller] => controller_name
[action] => action_name
...
)
If the AppController does not contain any beforeFilter method, you can just create it:
function beforeFilter()
{
debug($this->params);
}
I am using Zend Framework 1.12.
I wanted to add some routers. There are users and administrators in my system, and I have added a router for administrator viewing user's page.
I added
// meant to create the usage "xxx.com/userview/someusername"
$route = new Zend_Controller_Router_Route(
'userview/:username',
array('controller' => 'user',
'action' => 'viewone',
'username' => 'someusernamedefault')
);
$router = $frontController->getRouter();
$router->addRoute('userview', $route);
to my Bootstrap.php file.
I had some links in my sidebar, which contains links to actions (of another controller). I had added their link in a .phtml file as
echo $this->url(array('controller'=>'somecontroller', 'action'=>'someaction' ), null, true);
This sidebar contains lots of this links, which are from multiple controllers.
These worked fine till I added the route. After I added new route to Bootstrap (and added new action (viewall) to that controller (user) which is pointed from rooter, that works fine (I can use as "xxx.com/userview/someusername ). But my other links in the sidebar all becomes "xxx.com/userview". They all lose their values of controller and action...
What am I doing wrong?? Should I define my url's better, or my router better?
Thanks in advance.
The second param to the URL helper should be the name of the route you want to use. By passing null you're telling it to use the current route, which is why the links are coming out wrong. Change your sidebar link calls to:
$this->url(array('controller'=>'somecontroller', 'action'=>'someaction'), 'default');
and then it should work fine.
I'm using Zend framework 1.12, trying to come up with custom routes.
I'm trying to create something that looks like facebook's profile URL (http://facebook.com/username). So, at first I tried something like that:
$router->addRoute(
'eventName',
new Zend_Controller_Router_Route(
'/:eventName',
array(
'module' => 'default',
'controller' => 'event',
'action' => 'detail'
)
)
);
I kept getting the following error anytime I tried running mydomain.com/something:
Fatal error: Uncaught exception 'Zend_Controller_Router_Exception'
with message 'eventName is not specified' in
/var/desenvolvimento/padroes/zf/ZendFramework-1.12.0/library/Zend/Controller/Plugin/Broker.php
on line 336
Not only I was unable to make that piece of code work, all my default routes were (obviously) overwritten. So I have, for example, stuff like "mydomain.com/admin" that should send me to the "admin" module, on the Index controller, but was now returning the same error (as it fell in the same pattern as /:eventName).
What I need to do is to create this custom route, without overwriting the default ones and actually working (dûh).
I have already checked the online docs and a lot (A LOT) of stuff on google, but I didn't find anything related to the error I'm getting or how to not overwrite the default routes. I'd appreciate anything that could point me the right direction.
Thanks.
EDIT¹:
I managed to get it working, but I didn't use any routing at all. I just made a plugin with the following:
public function preDispatch(\Zend_Controller_Request_Abstract $request) {
if (!\Zend_Controller_Front::getInstance()->getDispatcher()->isDispatchable($request)) {
$request->setModuleName($this->_eventRouter["module"]);
$request->setControllerName($this->_eventRouter["controller"]);
$request->setActionName($this->_eventRouter["action"]);
}
}
It feels like an ugly workaround, though... As Tim Fountain pointed out, my events are dynamic (I load them from a database), so I can't hardcode it. Also, my current implementation prevents me from having to hardcode every module/controller/action combination.
I'd just like to know if there's a way to avoid using a plugin.
EDIT²: I'm not doing that crappy plugin thing anymore. I figured out what was causing the router error. My routing definition did not have a valid default value for variable 'eventName'. My fix was:
$router->addRoute(
'eventName',
new Zend_Controller_Router_Route(
'/:eventName',
array(
'module' => 'default',
'controller' => 'event',
'action' => 'detail',
'eventName' => ''
)
)
);
I am still unable to create routes with "conflicting" patterns, such as /admin and /:eventName. If only there was a way to make /admin override /:eventName...
Routes are applied/matched on a LIFO basis. As the routing docs note:
Note: Reverse Matching
Routes are matched in reverse order so make sure your most generic routes are defined first.
So, in order to have your "static" routes (static, in the sense that they do not pull from the db, /admin and the like) apply over your dynamic ones (/:eventName), make sure you define the static ones later in the execution flow.
In practical terms, this means that you cannot define your static routes during bootstrap, so you'll have to do it in a plugin with a routeStartup hook. Perhaps, two plugins: one for your dynamic routes, then another for the static ones, just make sure that the priority on the plugins is set so that the static ones are added later.
The error you are getting is probably coming from a URL helper call you have in your template. You need to specify the eventName param to this since you've made it required, e.g.:
Something
The answer to your other question depends a bit on whether you have a static, unchanging list of events or non-event URLs. You need to give the router a way to determine whether /foo is an event, or a controller. You do this by either hardcoding the possible events in to your event route, hardcoding routes for your other non-event URLs, or (if your events are dynamic and based on some database content) writing a custom route class for your event route which can do a lookup to see whether a given string is an event.
Since you are using Zend Framework 1.x
Here is the solution which I have added here : How to redirect Error Page and perform Routes in Zend Framework 1.x
Also, to make life easier... here it is:
I am still unable to create routes with "conflicting" patterns, such as /admin and /:eventName. If only there was a way to make /admin override /:eventName...
Once you are on the action which calls your eventName, you can put a check if that == admin, later you can define a re-route by specifying which action needs to be loaded, in that condition itself.
Simple? :)
define the eventName, and even if it's not required, just leave it blank.