Redirect to previous page in zend framework

50,682

Solution 1

First, you need to grab the original url for the redirection. You can do that by the Zend_Controller_Request class via:

$url = Zend_Controller_Front::getInstance()->getRequest()->getRequestUri();

or simply by:

$url = $_SERVER['REQUEST_URI'];

Then, the tricky part is to pass it through the user request. I recommend to use the library Zend_Session, despite using a POST parameter is also legitimate:

$session = new Zend_Session_Namespace('Your-Namespace');
$session->redirect = $_SERVER['REQUEST_URI'];

Please note that the address we kept includes the base path. To redirect the client in the controller class, disable the option 'prependBase' to lose the base path insertion:

$this->_redirect($url, array('prependBase' => false));

Solution 2

What I have found as a simple method to accomplish this is just to have a hidden field in your login form.

Now, im not sure if your login form is a generic HTML element or is actually an instance of Zend_Form, but if its an instance of Zend_Form, you could simple add the following:

$this->addElement('hidden', 'return', array(
        'value' => Zend_Controller_Front::getInstance()->getRequest()->getRequestUri(),             
            ));

Then in my authentication script, like the comment above, I have a simple redirect that uses the value passed in to return them to the same page.

$this->_redirect($this->_request->getPost('return'));

Obviously in these two examples, they are just written to compact the code and probably do not represent the best way to accomplish it. The two methods using the getRequest() in my code are actually not embedded in the redirect or the addElement, but for example purposes I just slid them in there.

The answer above will obviously work as well, unless you have some massive page redirection going on. The main reason I am running mine this way right now is because not all of my forms are running in Zend_Form and its also nice being able to change the value of the hidden return input text box for testing purposes.

Solution 3

Basically the same thing that Jesta is doing in his answer, but I added the following functions to my "MW_Form" class - which is a superclass of all my forms - easy enough to $form->trackReferrer($this->getRequest()); from the controller with any form. The getReferrer() function takes a "default" argument (which if the user has REFERER headers disabled, or there is no referrer - your going to want a default place to redirect back to)

  /**
   * Adds a form element named "referrer" and sets its default value to either
   * the 'referrer' param from the request, or the HTTP_REFERER header.
   *
   * @param Zend_Controller_Request_Abstract $request 
   * @return MW_Form
   * @author Corey Frang
   */
  public function trackReferrer(Zend_Controller_Request_Abstract $request)
  {
    $this->addElement('hidden', 'referrer');
    $this->setDefault('referrer', 
      $request->getParam('referrer', 
        $request->getServer('HTTP_REFERER')));
        // HTTP_REFERER not HTTP_REFERRER - grrr HTTP spec misspellings

    // use no decorator for the actual form element
    $this->referrer->setDecorators(array()); 

    // use our custom "referrer" decorator to stick the hidden before the <dl>
    $decorators = $this->getDecorators();
    $this->clearDecorators();
    foreach ($decorators as $class=>$decorator)
    {
      if (substr($class,-5) == '_Form') {
        $this->addDecorator('Referrer');
        $added = true;
      }
      $this->addDecorator($decorator);
    }
    if (!$added) $this->addDecorator('Referrer');

    return $this;
  }

  /**
   * Returns the referrer field if it exists.
   *
   * @return string | false
   * @param mixed $default The value to return if referrer isn't set
   * @author Corey Frang
   **/
  public function getReferrer($default = false)
  {
    if (!isset($this->referrer)) return $default;
    $val = $this->referrer->getValue();
    if ($val) return $val;
    return $default;
  }

The Decorator Used - gives you the added benifit of not using up any rows in the <dl> created by zend_form:

class MW_Form_Decorator_Referrer extends Zend_Form_Decorator_Abstract  {
  /**
   * Attaches the standard "ViewHelper" decorator for the 'referrer' element
   * prepended on the content
   *
   * @return void
   * @author Corey Frang
   **/
  public function render($content)
  {
    $form = $this->getElement();
    if ($form instanceOf MW_Form)
    {
      $referrer = $form->referrer;
      if ($referrer)
      {
        $decorator = new Zend_Form_Decorator_ViewHelper(array('placement'=>self::PREPEND));
        $decorator->setElement($referrer);
        return $decorator->render($content);
      }
    }
    return "Error - No Referrer Found".$content;
  }
}

Example Usage (from a controller):

$form = $description->getEditForm();
$form->trackReferrer($this->_request);
if ($this->_request->isPost())
{
  if ($form->process($this->_request->getPost()))
  {
    return $this->_redirect($form->getReferrer('/page'));
  }
}

Solution 4

I have a predispatch hook in plugin for authorization. In it if (and only if) user needs to be logged I save the request URI to session and after logging in I redirect there. There is no overhead except when redirecting to login form. But that's a case where overhead is no problem. :)

if(!$auth->hasIdentity()){
  $this->_insertLastUrlToSession();
  $this->redirect('/index/login');
} else {
  //no overhead
}

Solution 5

I see this already has an answer, but i'd like to throw mine in too, just as a different way to skin the cat sort of deal, using static methods.

class App_Helpers_LastVisited {
    /**
     * Example use:
     * App_Helpers_LastVisited::saveThis($this->_request->getRequestUri());
     */
    public static function saveThis($url) {
        $lastPg = new Zend_Session_Namespace('history');
        $lastPg->last = $url;
        //echo $lastPg->last;// results in /controller/action/param/foo
    }

    /**
     * I typically use redirect:
     * $this->_redirect(App_Helpers_LastVisited::getLastVisited());
     */
    public static function getLastVisited() {
        $lastPg = new Zend_Session_Namespace('history');
        if(!empty($lastPg->last)) {
            $path = $lastPg->last;
            $lastPg->unsetAll();
            return $path;
        }

        return ''; // Go back to index/index by default;
     }
}

This doesn't run all the time, only on a need to basis.

That's the whole code, part of my blog post here (http://hewmc.blogspot.com/2010/08/simple-way-to-store-last-visited-url-in.html)

Share:
50,682
Morteza Milani
Author by

Morteza Milani

Updated on March 28, 2020

Comments

  • Morteza Milani
    Morteza Milani about 4 years

    I want to add a redirection URL to my login forms action (as a query) in login page, so after loging-in, one can visit the previous page he or she was surfing.

    First I thought about using Zend Session and save the url of each page in a variable. but I read in the documentation that it has overhead. So, is there a better way to do so? or is there an other way to use zend session with no overhead?