I have a CakePHP 2.3 setup with the following route:
Router::connect('/contact', array('controller' => 'old_layout', 'action' => 'contact'));
In my AppController, I define
public $components = array(
'Security'...
);
In OldLayoutController, in the beforeFilter() function I define:
$this->Security->allowedControllers = array('OldLayout');
In the view for old_layout/contact, I generate the form using the Form->create() and end() functions and regular Form::input()... commands.
When I submit the form at /contact, I get the following message:
The request has been black-holed
Error: The requested address '/[domain].com/contact' was not found on this server.
Thing is, I do the exact same thing for another form in a different controller which works perfectly.
After much debugging, I figured it out. It was all due to an errant 'reset' button that was being generated incorrectly.
Related
I have some code in my routes file:
Router::scope('/v1', function (RouteBuilder $routes) {
$routes->resources( 'Files');
});
And then a FilesController with a delete function like:
public function delete($id){
echo "here"; exit();
}
When I do:
DELETE http://192.168.1.197/v1/files/1
The response is here, however, if I do:
DELETE http://192.168.1.197/v1/files
The response is that it is missing the V1Controller.
What I would expect instead is for CakePHP to turn around and say "oops, you have passed the wrong number of required parameters".
Something very weird seems to be going on here and I am not quite sure what. How can I make the two do the same thing and point to the controller?
CakePHP operates very differently on exceptions when debug mode is enabled. When debug is true all exceptions are rendered with debug information, stack tracing and developer friendly messages.
When debug mode is false the exception is rendered as a standard HTTP response type. With handles for 400 and 500 error codes.
When the router can't find a match for a route there is no controller involved. The HTTP request never gets past the dispatching phase. It's the dispatcher that throws a 400 type exception.
In your given example the framework is throwing a MissingControllerException with the HTTP code of 404.
400 error codes are rendered via the ErrorController. CakePHP comes a with a default error controller, but if you generate a new application using the composer template, then you should have a default ErrorController in your app's controller holder.
In your templates there should be a src/Template/Error/error400.ctp file which displays the response for 400 codes. Keep in mind, that this template is not used when debug mode is enabled.
You can modify this template to find "closely" matching routes and offer them as recommendations to the user as feedback in the error message.
You can iterate all configured Routes easily like this:
foreach (Router::routes() as $route) {
$name = isset($route->options['_name']) ? $route->options['_name'] : $route->getName();
$output[] = [$name, $route->template, json_encode($route->defaults)];
}
Above taken from cakephp/src/Shell/RoutesShell.php:
Since this is technically a 404 error. There is no matching route and what you can do is try to find routes that are "close" to a match. The problem here is that you are subject to the same route matching challenges as the Router class.
The Router class uses dynamic routing techniques that take parts of the URL parameters and fills them in as names of controllers, names of actions and user defined parameters.
This can change significantly depending upon what kind of default router class you are using.
For example, you might be using the DashedRoute routing class which does the following:
/**
* This route class will transparently inflect the controller, action and plugin
* routing parameters, so that requesting `/my-plugin/my-controller/my-action`
* is parsed as `['plugin' => 'MyPlugin', 'controller' => 'MyController', 'action' => 'myAction']`
*/
class DashedRoute extends Route
You might instead be using the InflectedRoute routing class which does the following:
/**
* This route class will transparently inflect the controller and plugin routing
* parameters, so that requesting `/my_controller` is parsed as `['controller' => 'MyController']`
*/
class InflectedRoute extends Route
Since there are cases where routing could be using dynamic routing. It's not possible to know if a URL segment is a controller, action or named parameters.
Add to the complexity that you're also using a scoped segment named /v1 it becomes even more challenging to predict what the intended route is.
You can either create custom routes to catch these edge cases and render an informative error message, or you can try to add logic to the error400.ctp to display a more informative error message.
There is also a final option. Where CakePHP allows you to write your own custom Route classes, and/or modify the middleware with your own dispatcher.
I solved this another way entirely, just stop using the resource routes in CakePHP; I changed my code to:
$routes->get('/files/*', ['controller' => 'Files', 'action' => 'view'], 'files:get');
$routes->post('/files', ['controller' => 'Files', 'action' => 'add'], 'files:post');
$routes->put('/files/*', ['controller' => 'Files', 'action' => 'edit'], 'files:put');
$routes->patch('/files/*', ['controller' => 'Files', 'action' => 'view'], 'files:patch');
$routes->delete('/files/*', ['controller' => 'Files', 'action' => 'delete'], 'files:delete');
And it works exactly as how I wanted in the question...
I have had installed and configured a new CakePHP 2.4 instance. Now I wanted to implement the AuthComponent. I have had implemented the component exactly as in recent projects, too. Now I have the problem that I get the error message Missing Controller: SteadinessController. But Steadiness is the project name. I'm confused haha.
The URL I want to open is http://localhost/steadiness/users/view/2 and I will be redirected to http://localhost/steadiness/steadiness/users/login. The controller and action invoked is correct but the second steadiness is false.
Thanks a lot for help.
Alex
Can you post the code where you try to direct the user to this url?
I'm guessing it's a redirect to do with the Auth component.
In your AppController when you set up Auth there should be something similar yo:
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => '/',
'logoutRedirect' => '/',
'authorize' => 'controller',
'unauthorizedRedirect' => '/'
)
);
The loginRedirect tells Cake where to send users after login who went directly to the login page (they didn't try to access a restricted link whilst not logged in).
The logoutRedirect tells Cake where to send users after logout.
The unauthorizedRedirect tells Cake where to send logged in users that try to access a link that they do not have the priveleges for (e.g. a non-admin tries to delete an account - only admins should be able to do that).
If one of these is not set then when Cake tries to use it you get redirected to '/{app-directory}' which is NOT the same as '/'.
This is most likely why your url has the domain appear twice - so Cake thinks it is looking for a controller with the same name as your domain.
This question has been asked many times but for some reason the proposed solution isn't working for me.
I wan't to use names like "deleteDefaultUser" for my action. To achieve this I have done following.
Added a route
$route = new Zend_Controller_Router_Route_Static(
'user/delete-default-user',
array(
'action' => 'deleteDefaultUser',
'controller' => 'user',
'module' => 'root'
)
);
$router->addRoute('delete-default-user', $route);
Defined my action as below
public function deleteDefaultUserAction(){
//some code
}
And generated a URL like this
echo $this->url(array(), 'delete-default-user');
( This generates the URL /user/delete-default-user)
But for some reason I am still getting the error shown below:
Zend_Controller_Action_Exception: Action "deletedefaultuser" does not exist and was not trapped in __call() in C:\Users\Jay\Projects\EOP\library\Zend\Controller\Action.php on line 485
I have checked the controller and action names are correct. But from the error message it seems that Zend Framework is not applying camel case to action names.
The version of Zend Framework that I am using is 1.12.
Can any one please help with this?
Edit: If I change my action name to 'deletedefaultuser' it works correctly.
Change the action part of the route to:
'action' => 'delete-default-user',
and then it should work.
How do you add in the yii form the action for PHP_SELF, I am currently using this:
'action' => '/site/contact',
but I want to replace the action to call itself again. How do I do that?
UPDATE:
tried removing the action in the array, now it does not go into validating the form.
Use Yii controller method createUrl - calling it without params will point to current controller and action.
In views you can just call $this->createUrl():
'action' => $this->createUrl(),
Important: do not hardcode actions like in your question. Always call createUrl, this will ensure proper urls if you change url rules:
'action' => $this->createUrl('otherController/someAction'),
or same controller different action
'action' => $this->createUrl('otherAction'),
etc.
Do mean perhaps a page refresh?
Just do $this->refresh() inside your controller action.
Im developing a simple application with CakePHP v1.3.7 Stable. I want to generate a simple user profile page, accessible by the url: my.domain/u/id, where id is the id of the user in database.
So i wrote this (and only this) in app/config/routes.php:
Router::connect('/u/:id',
array('controller' => 'Users', 'action' => 'profile')
,array('pass'=>array('id'),'id'=>'[0-9]+')
);
The above code works fine, when i put my.domain/u/120 in the browser, it shows the profile of user 120.
But, when i try to create a link to this page using the Html helper:
// some code in a view
$this->html->link('Test', array('controller'=>'Users', 'action'=>'profile', 120))
The html helper (doing inverse routing, i think) generates the url in the defaut cakephp form: Test
Based on the configuration in routes.php, it should be: Test, right?
I'm missing something?
Thanks.
Try with this:
$this->html->link('Test', array('controller'=>'Users', 'action'=>'profile', 'id'=>120))
I hope the missed 'id' will fix it.
Finally, thanks to dogmatic69, I deleted the id related code of the route.
I end with this in routes.php:
Router::connect('/u/*',
array('controller' => 'users', 'action' => 'profile')
);
Now, the html helper works just as expected:
echo $this->html->link('Test',array(
'controller'=>'users',
'action'=>'profile',
100
))
// renders: Test
The drawback is that I can't take advantage of the regexp filter of the router, as in the initial route code.