Question

I'm looking to send the user to another page via a controller method. The other page expects POST data.

Normally, the page is accessed with a postLink(). Is there a way to use this in the controller, perhaps with redirect()?

Was it helpful?

Solution

A little bit old but still no answer accepted so... The answer is no, and yes.

  • No, there is no direct method since you cannot pass POSTed data using redirect() function.
    You could use requestAction(), since you can pass data as posted (see requestAction() here for version cakePHP>=2.0).
    In that case you pass an url and then an array having the key data with the posted data, something like

    $this->requestAction($url, array('data' =>$this->data));

    or if you prefer

    $this->requestAction($url, array('data' =>$this->request->data));

    The problem with requestAction() is that the result is environmentally as if you were generating the page of the requested action in the current controller, not in the target, resulting in not very satisfactory effects (at least not usually for me with components behaving not very nicely), so still, no.

  • ...but Yes, you can do something very similar using the Session component.
    This is how I usually do it. The flow would be something like this:

    View A=>through postLink() to Action in A controller=>
    =>A controller request->data to Session variable=>
    =>action in B controller through redirect()=>
    =>set B controller request->data from Session variable=>
    =>process data in B controller action=> View B

So, in your A controller, let's say in the sentToNewPage() action you would have something like

//Action in A controller
public function sentToNewPage()
{
 $this->Session->write('previousPageInfo', $this->request->data);
 $url = array('plugin' => 'your_plugin', 'controller'=>'B',
              'action'=>'processFromPreviousPage');
 $this->redirect($url);
}

and in B controller:

//Action in B controller
public function beforeFilter()
{//not completelly necessary but handy. You can recover directly the data
 //from session in the action 
 if($this->Session->check('previousPageInfo'))
   {$this->data = $this->Session->read('previousPageInfo')};
 parent::beforeFilter();
}
public function processFromPreviousPage()
{
 //do what ever you want to do. Data will be in $this->data or
 // if you like it better in $this->request->data
 $this->processUserData($this->request->data);
  //...
}

OTHER TIPS

Best solution would be use javascript to redirect.

But if you want more cake I give you some tools CakeAPI: requestAction - it allow to execute controller method of desire with parameters, if you pass 'return', it will return full view output for that action.

//very useful in views
$result =  $this->requestAction('Controller/method', 
       array('return','user_id'=>$userId)
); 

parameter will be accessible in controller via request param

$this->request->params['user_id']

Long and short is that it's not easy to emulate an HTML form with POST data and a redirect, you kind of need to set a bunch of hidden variables containing the data and automatically post the form to your destination via Javascript.

What I would do is take the processing functionality out of the function that requires POST variables, and make it generic so that you can call it from both of your functions.

Consider this rough example:

public function myPostDataAction() {
    $name = $_POST['name'];
    $age = $_POST['age'];
    // do stuff
    echo $name . ', ' . $age;
}

Let's say that is the action you are trying to post data to in this scenario, but you can't because you can't emulate those $_POST variables over a redirect without the scenario mentioned at the top here. You can do this:

public function myPostDataAction() {
    $name = $_POST['name'];
    $age = $_POST['age'];
    // call common function
    echo $this->getMyResults($name, $age);
}

// accessible from inside the controller only
private function getMyResults($name, $age) {
    return $name . ', ' . $age;
}

Now you can also use that getMyResults() functionality by passing regular old variables into it:

public function myProblemFunction() {
    $name = 'John';
    $age = 15;
    echo $this->getMyResults($name, $age);
}

Now, obviously you won't be outputting anything like that straight from the controller action, you'll be setting it to your views etc, but that's an example of how you can centralize functionality to be used in multiple locations.

For the disclaimer, this kind of thing is exactly what models are for, and you should definitely consider putting this kind of function into a model instead of a controller - it depends on your specific application.

With cakephp 2.x Use this:

$this->autoRender = false;
$request = new CakeRequest(Router::url(array('controller' => 'mycontroller','action' => 'my_action')));
$request->data('dataIndex','value');
$response = new CakeResponse();
$d = new Dispatcher();
$d->dispatch(
    $request,
    $response
);

but it will not redirect but dispatch to a different controller/action so if you went on /controller/oldaction it will stays the current url (no HTTP redirection is done).

You could still change the url with javascript see: Change the URL in the browser without loading the new page using JavaScript

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top