web-dev-qa-db-fra.com

Rediriger vers la page précédente dans zend framework

Je souhaite ajouter une URL de redirection à mon action de formulaire de connexion (sous forme de requête) dans la page de connexion. Ainsi, après la connexion, vous pouvez visiter la page précédente sur laquelle il surfait.

J'ai d'abord pensé à utiliser Zend Session et à enregistrer l'URL de chaque page dans une variable. mais j'ai lu dans la documentation qu'il y a des frais généraux. Alors, y a-t-il une meilleure façon de le faire? ou existe-t-il un autre moyen d'utiliser zend session sans surcharge?

28
Morteza Milani

Tout d’abord, vous devez récupérer l’URL d’origine pour la redirection . Vous pouvez le faire par la classe Zend_Controller_Request via:

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

ou simplement par:

$url = $_SERVER['REQUEST_URI'];

Ensuite, la difficulté consiste à le transmettre à la demande de l'utilisateur. Je recommande d'utiliser la bibliothèque Zend_Session, bien que l'utilisation d'un paramètre POST soit également légitime:

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

Veuillez noter que l'adresse que nous avons conservée inclut le chemin de base . Pour rediriger le client dans la classe du contrôleur, désactivez l'option 'prependBase' pour perdre l'insertion du chemin de base:

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

Ce que j’ai trouvé comme méthode simple pour y parvenir est simplement d’avoir un champ caché dans votre formulaire de connexion. 

Maintenant, je ne sais pas si votre formulaire de connexion est un élément HTML générique ou est en fait une instance de Zend_Form, mais si c'est une instance de Zend_Form, vous pouvez simplement ajouter ce qui suit:

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

Ensuite, dans mon script d'authentification, comme le commentaire ci-dessus, j'ai une redirection simple qui utilise la valeur transmise pour les renvoyer sur la même page. 

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

Évidemment, dans ces deux exemples, ils sont simplement écrits pour compacter le code et ne représentent probablement pas le meilleur moyen de le réaliser. Les deux méthodes utilisant la getRequest() dans mon code ne sont en réalité pas intégrées à la redirect ou à la addElement, mais à titre d'exemple, je les ai simplement glissées ici. 

La réponse ci-dessus fonctionnera évidemment aussi, sauf si une redirection massive de pages est en cours. La raison principale pour laquelle j’exécute le mien de cette façon actuellement, c’est que tous mes formulaires ne fonctionnent pas dans Zend_Form et qu’il est également agréable de pouvoir modifier la valeur de la zone de texte masquée return à des fins de test. 

8
Jesta

La même chose que Jesta fait dans sa réponse, mais j’ai ajouté les fonctions suivantes à ma classe "MW_Form" - qui est une super-classe de tous mes formulaires - assez facile à nommer $form->trackReferrer($this->getRequest()); depuis le contrôleur quel que soit le formulaire. La fonction getReferrer () prend un argument "default" (qui, si l'utilisateur a les en-têtes REFERER désactivés, ou s'il n'y a pas de référent - vous allez vouloir un emplacement par défaut où être redirigé)

  /**
   * 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;
  }

Le décorateur utilisé - vous offre l'avantage supplémentaire de ne pas utiliser les lignes du <dl> créé par 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;
  }
}

Exemple d'utilisation (d'un contrôleur):

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

J'ai un hook prédispatch en plugin pour autorisation. Dans celui-ci si (et seulement si) l'utilisateur doit être connecté, j'enregistre l'URI de la demande en session et, une fois connecté, je le redirige. Il n'y a pas de surcharge, sauf lors de la redirection vers le formulaire de connexion. Mais c'est un cas où les frais généraux ne posent aucun problème. :)

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

Je vois que cela a déjà une réponse, mais je voudrais aussi ajouter la mienne, juste comme une façon différente de traiter le problème avec des chats, en utilisant des méthodes statiques.

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;
     }
}

Cela ne fonctionne pas tout le temps, seulement sur un besoin de base.

C'est tout le code, une partie de mon billet de blog ici ( http://hewmc.blogspot.com/2010/08/simple-way-to-store-last-visited-url-in.html )

2
Edward Hew

Ce plugin Zend Framework vous permet de sauvegarder les URL actuelles et dernières qualifiées et de filtrer les URL indésirables. n'hésitez pas à utiliser et commenter:

<?php

class Plugins_PageLog extends Zend_Controller_Plugin_Abstract
{
    public function preDispatch(Zend_Controller_Request_Abstract $request){
        $module = $request->getModuleName();
        $controller = $request->getControllerName();
        $action = $request->getActionName();
        $params=$request->getParams();

        // to grap urls that are in default module, not in auth controller, and not an error url 
        $controller2= Zend_Controller_Front::getInstance();
        if ($controller2->getDispatcher()->isDispatchable($request) 
            && ( $module == 'default' || $module == NULL )
            && $controller != 'auth'
            && ( !isset($params['error_handler']))
        ) {

            // init 2 session variables: the current and last qualified url
            if (!isset($_SESSION['redirect'])) $_SESSION['redirect'] = '';
            if (!isset($_SESSION['last_visited_url'])) $_SESSION['last_visited_url'] = '';

            // tempurl is to save current qualified url temporarily to ensure current and last qualified url will not be same
            if (!isset($tempUrl)) $tempUrl = '';
            if ($_SESSION['last_visited_url'] != $_SESSION['redirect']) {
                $tempUrl = $_SESSION['redirect'];
                $tempParams = $_SESSION['redirect_params'];
            }

            // save current qualified url
            $_SESSION['redirect']=$request->getRequestUri();
            $_SESSION['redirect_params'] = $params;

            // to ensure there are no duplicated urls due to browser refresh 
            if ($tempUrl != $_SESSION['redirect']){
                $_SESSION['last_visited_url'] = $tempUrl;
                $_SESSION['last_visited_url_params'] = $tempParams;
            }
        }

        //echo '<pre>';var_dump($_SESSION['last_visited_url']);echo '</pre>';
        //echo '<pre>';var_dump($_SESSION['redirect']);echo '</pre>';
    }
}
1
Capitaine

En plus de gnarfs answer, je l’ai modifié pour le rendre valide - pour ceux qui en aiment le coup.

$this->addDecorator(array('WrapClose' => 'HtmlTag'), array('tag' => 'div', 'placement' => 'PREPEND', 'closeOnly' => true));
$this->addDecorator('Referrer'); 
$this->addDecorator(array('WrapOpen' => 'HtmlTag'), array('tag' => 'div', 'placement' => 'PREPEND', 'openOnly' => true));
0
Phliplip

Si vous n'êtes pas fan des variables via une session, vous pouvez essayer d'obtenir la variable $ _SERVER ['HTTP_REFERER'] de manière sécurisée. Fondamentalement, il vérifie si votre URL de référence et correspond au nom local de votre serveur et au schéma (http/https). 

class My_Tools
{   
    public static function doesUrlMatchServerHttpHost($url)
    {       
        $scheme = Zend_Controller_Front::getInstance()->getRequest()->getScheme();
        $httpHost = Zend_Controller_Front::getInstance()->getRequest()->getHttpHost();
        $needleUrl = $scheme.'://'.$httpHost.'/';
        if (strpos($url, $needleUrl) !== 0)
        {
            return false;
        }
        return true;
    }

    public static function safelyGetReferrerUrl($default)
    {
        if ( isset($_SERVER['HTTP_REFERER']) == false){
            return $default;
        }
        if (self::doesUrlMatchServerHttpHost($_SERVER['HTTP_REFERER']) == false){
            return $default;
        }
        return $_SERVER['HTTP_REFERER'];
    }
}

Et puis juste 

$referrerUrl = My_Tools::safelyGetReferrerUrl('/');

Par défaut, vous pouvez définir un URI local ('/')

0
chmurson

$ this -> _ redirect ($ this-> getRequest () -> getServer ('HTTP_REFERER'));

0
Webdesign7 London

Vous pouvez essayer d'utiliser l'en-tête HTTP_REFERRER comme ceci:

// str_replace is the easiest way to get rid of domain - u can also preg_replace it   
return str_replace("http://".Zend_Controller_Front::getInstance()->getRequest()->getServer("HTTP_Host"),"",Zend_Controller_Front::getInstance()->getRequest()->getServer("HTTP_REFERER"));  
0
Marcin Hubert