I am trying to do some custom routing on my site, but have been stuck for 2 days at a very silly issue. I have the following route configuration:
Router::connect('/your-solution/add-comment/*', array('controller' => 'comments', 'action' => 'add'));
Router::connect('/admin/your-solution/add-comment/*', array('controller' => 'comments', 'action' => 'add', 'admin' => true));
The problem is that when I try to load a URL formatted using the second route, it gives me a 404 not found.
The first rule works fine.
For both rules I have a separate element containing a form and pointing to a URL formatted after the respective rule. The only parameter for both actions is the solution id, which is "contained" in the wildcard.
What could possibly be the issue? Thank you very much for your help!
EDIT:
I found out another weird behaviour. When I access /admin/your-solution/add-comment/3, it goes to that action. But if I submit a form to that link, it displays a blank page, with Firebug informing me that the page was not found. Very strange...
Also, I have a similar route for editing comments. Both loading the edit form and saving the form work...
how are you?
In order to see exactly why isn't it working, go to your /app/config/core.php and seek for this line:
Configure::write('debug', 2);
And make sure the value is set to "2". This way, it'll no longer give you a 404 error, but the actual issue, since in production mode (debug set to 0), all errors are masked with a 404 error.
Let me know!
Cheers!
In your core.php be sure
Configure::write('Routing.prefixes', array('admin'));
In your comments controller, be sure you have
function admin_add() {...}
Also try other ways of formatting Routing statement.
Router::connect('/admin/your-solution/add-comment', array('controller' => 'comments', 'action' => 'add', 'admin' => true));
The order of your route is also important. You may want to check that.
For debugging which route you are using when loading the URL, try adding this code to your app_controller.php file.
function __construct() {
$route = Router::currentRoute();
pr($route);
}
These are just some tips to hopefully help you move forward.
Apparently, the problem has been lying in a disabled input. After I've deleted this element, the form submits correctly and the target page is shown.
Just for my knowledge, why didn't the form submit if it had a disabled input in it?
Related
Using CakePHP 2.3. I turned on the security component, and I noticed an odd behavior with postLinks, where for some reason they are no longer seem to be transmitting data by POST, but instead they are using GET. In the action I'm trying to call, the first thing I do is to ensure that the data was made by POST:
if (!$this->request->is('post'))
{
throw new MethodNotAllowedException();
}
When the security component is on, this if statement is false. When it is off, the if statement is true. No other changes have been made.
The postLink:
<?php echo $this->Form->postLink($this->Html->image('icons/resend-icon.png'), array('action' => 'resend', $invoice['Invoice']['number']), array('escape' => false, 'class' => 'hastip', 'title' => 'Resend'), __('Are you sure you want to resend this invoice?')); ?>
As far as I've been able to look, I've found no explanation for this. I would prefer if I could make sure the data is actually being sent by POST, though everything else works if I remove the check for the request is a POST.
Edit:
I've discovered that if I set $this->Security->csrfCheck = false; and $this->Security->validatePost = false; in the before filter for that particular action, it does not have this problem. I would still like to know why precisely this is though.
Edit 2:
After more investigation, I discovered the view of the page in question has another form on it, echo $this->Form->create('Invoice', array('type' => 'get')); which should not be affecting the post links in any way (post links are not inside the form, etc.), but if I remove the array('type' => 'get'), the postLinks start working. I need the other form to be of type get though, as it's a search form, and I need to have the search query string in the URL.
Edit 3:
I've discovered that moving the search form below the post links also fixes the problem. I tried running the markup through a html validator to make sure nothing was malformed, but it did not report anything.
Edit 4:
I discovered that the markup being generated for the PostLinks is incorrect -- the hidden inputs used for detecting CSRF are named incorrectly, resulting in it failing CSRF tests. Thus, the request is getting blackholed. I have set up a blackhole callback to redirect http:// to https://, so the page gets redirected, resulting in a new get request for the same page, which then gets rejected by the MethodNotAllowedException. Trying to investigate now why the PostLinks aren't being generated correctly.
I determined the solution is after finishing with the first form, I needed to reset the Form helper's request type.
<?php echo $this->Form->create('Invoice', array('type' => 'get')); ?>
<?php echo $this->Form->end(); ?>
<?php $this->Form->requestType = null; ?>
$this->Form->requestType starts as null, and gets set by calling $this->Form->create. So if I set the earlier Form to be post, or if I had created the Form after using postLinks, the Form helper's request type is set to a value that will work with PostLinks when I attempted to create the postLinks, but it appears manually resetting requestType also works.
Edit: This is actually a bug with the CakePHP framework. I have reported it, and it has been fixed, so this is no longer necessary in the newest version of CakePHP.
My codebase is built in Cakephp.
I have an update button which processes a "notes" field. I have a working controller update/write that redirects back to the page, so the "hard" bit is done...
However: from a usability point of view, this redirects to the raw URL, and hence to the top of the page every time.
The <input> field has an id, so I simply want to link back to it using an anchor tag.
Here's what works [controller]:
$this->redirect('/review/index/'.item->getEmployeeId());
I tried to add in the following:
$this->redirect('/review/index/'.$item->getEmployeeId().'#'.$item->getEmployeeId());
However - this seems to be stripped out... The write still works, but the anchor is stripped out.
For debugging/quick gotchas: I have tested the raw URL out and it redirects to the <input>.
Is there another way to do this? I'm assuming this is some cakephp "magic" and I simply don't know how to apend an anchor. Some google searches and poking in the API don't seem to clear things up though.
Many thanks.
Following: http://book.cakephp.org/2.0/en/controllers.html#Controller::redirect
Use this:
$url = array(
'controller' => 'review',
'action' => 'index',
$item->getEmployeeId(),
'#' => $item->getEmployeeId()
);
$this->redirect($url);
I have the following problem in Cakephp:
I maded a CMS to edit the content of a website with CakePhp. Now when I change the content in my form and I click Save then he shows again the data from before the form was changed.
In the database everything saved well and if I refresh the page also he shows the right data.
I know I can render a new page or redirect to another page, but I liked to just show a message with setFlash and that's it. Someone can help me out?
Thanks in advance
AƤron
Update : check the Justin T. solution below.
You can just redirect to the same page:
to set your flash message:
$this->setFlash('blablablabla');
and
return $this->redirect($this->here); //cake 1.3
or
return $this->redirect($this->request->here); // cake 2.x
or
return $this->redirect(['controller' => 'MyController', 'action' => 'methodOfController']); // cake3.X
to redirect.
With the new method flash() you set a message and redirect in the same method.
This is the most elegant way I know of, and it goes something like this :
<?php
public function post() {
// process content here...
// redirects the user immediately with a nice message
$this->flash('Your post has been updated, thanks', 'index');
}
Hope this helps !
I've a new question :)
I'll briefly explain what I'm trying to achieve. Right now I have an url that looks like this.
/products/index/brand:figleaves
I want this to look like this
/brand/figleaves
By writing the following route rule I get what I want.
Router::connect('/brand/:brand/*', array('controller' => 'products', 'action' => 'index'));
Everything goes fine, but then I discovered the pagination logic has been destructed.
If I click on 'next page' I get redirected to the url /products/index/page:2.
it doesn't pass the brand parameter
it redirects back to the products_controller and not to the url I defined in the route rule.
In fact I'd need this as url /brand/figleaves/page:2.
Strange thing is if I browse to /products/index/brand:figleaves and click on Next, then I get redirected to /brand/figleaves/page:2. How can this be explained?
I'd appreciate some help with this :)
Kind Regards,
Laurent
For those interested in how I solved this.
I just defined some options in the paginator in my view and passed the value explicitly, like this.
$this->Paginator->options(array
('url'=> array(
'controller' => 'products',
'action' => 'index',
'brand'=>$this->params['brand']
)));
That does the job :)
in my application am calling this line in case a particular case (if condition) from ajax call
$this->redirect('/login/login/');
But this was updating the particular div. I want to redirect the whole page.
How to do it?
Thanks,
you may need to do it the old way :)
window.opener.location.href = "new page";
I believe that you can supply a parameter to redirect which will change the controller.
In an application I have written I use:
$this->redirect(array('controller' => 'users', 'action' => 'login');
when I want to prompt the user for a login.
You can find the full documentation for redirect here
http://book.cakephp.org/view/425/redirect