2015-12-22 11 views
5

Ho viste da varie azioni del controller che devono essere eseguite esclusivamente da un iframe inserito in un'altra vista.

Attualmente, quando l'iframe viene caricato e si accede alla pagina di accesso per accedere, in caso di successo il controller di accesso (utilizzando il modulo utente yii2) chiama $this->goBack(), reindirizzandomi all'URL dell'origine iframe (poiché è l'ultima pagina visitato), piuttosto che la pagina originale contenente l'iframe.

Fondamentalmente, vorrei escludere azioni del controllore specifiche da impostare come URL di ritorno quando viene chiamato $this->goBack(). Punti bonus se tutte le azioni caricate negli iframe vengono automaticamente escluse da $this->goBack().

+0

Tutti gli iframe occupano la stessa pagina di visualizzazione? –

+0

No, gli iframe si trovano su varie viste. – Dean

risposta

1

Ok, ci provo! Questo codice è assolutamente non testato! Il tuo problema è che l'azione non ha modo di sapere se è stata chiamata da un iframe o meno, a meno che tu non la dica. Quindi, la base del mio tentativo di risposta è che tutti gli URL per iframe dovrebbero avere un parametro get aggiuntivo. Chiamiamo questo caller. Così ogni iframe dovrebbe essere simile

<iframe url="index.php?r=controller/action&caller=this-controller/action</iframe> 

Ora si può sempre provare la richiesta URL per vedere se è stato chiamato da un iframe. Inoltre, ogni link all'interno dell'iframe dovrebbe avere questo parametro aggiunto al suo URL.

Quindi, ora abbiamo almeno due problemi. In primo luogo, come aggiungere automaticamente caller come parametro get, senza dover riscrivere ogni URL, e in secondo luogo, come riconfigurare il metodo goBack() in modo che conosca la differenza tra i due tipi di richiesta.

Il primo problema può essere risolto in modo relativamente semplice aggiungendo un altro livello di visualizzazione tra il controller e la vista desiderata. Lo chiamerò iframe. Quindi, nell'azione del tuo controller, aggiungi questo;

$view = 'The name of the view you want to render'; 
$this->render('iframe', 'view' => $view);//Add in any other parameters you want to pass 

Il file di visualizzazione iframe deve contenere qualcosa come questo;

<iframe src="<?php Url::to(['however you generate the url for your iframe', 'caller' => Url::to($this->context->route)]); ?>"> 
    <?php $this->render($view); ?>//Pass additional parameters to the view if needed 
</iframe> 

Ora abbiamo un modo di testare una chiamata controller/action per vedere se è stata richiesta dal mattino iframe. Il parametro caller è importante perché consente di estrarre una stringa da utilizzare come valore per goBack() e altri metodi.

Quindi, occorre estendere UrlManager, come tutti request, response, Url:to() e goBack() metodi e classi infine usa il UrlManager per completare i metodi per la generazione di URL.

Quindi, creare un nuovo UrlManager. Copiremo la maggior parte del codice dall'UrlManager esistente, aggiungendo solo un po 'piccante del nostro. Ho archiviato il mio in commands, ma metto dove vuoi e cambia lo spazio dei nomi di conseguenza.

<?php 

namespace app\commands; 

use Yii; 
use yii\web\UrlManager; 

class CustomUrlManager extends UrlManager { 

    public function createUrl($params){ 
     $request = Yii::$app()->request; 
     $caller = $request->get('caller'); 
     if ($caller && !$params['caller']){ 
      $params['caller'] = $caller; 
     } 
     return parent::createUrl($params); 
    } 

} 

Così ora, l'iframe genera un parametro caller, ed ogni link nel iframe avrà anche caller aggiunto come un parametro, il più a lungo il culo che hai usato sia Url::to() (o varianti su questo metodo) o Yii::$app->UrlManager per generare i tuoi collegamenti.

Ora tutto ciò che dobbiamo fare è personalizzare il metodo goBack() del controller per inviare qualsiasi richiesta goBack() all'iframe di origine originale.

public function goBack($defaultUrl = null) 
    { 
     $caller = Yii::$app->request->get('caller'); 
     if ($caller){ 
      return Yii::$app->getResponse()->redirect($caller); 
     } 
     return Yii::$app->getResponse()->redirect(Yii::$app->getUser()->getReturnUrl($defaultUrl)); 
    } 

Infine è necessario configurare Yii per utilizzare il nuovo UrlManager, nel proprio file di configurazione;

'components' => [ 
    'urlManager' => [ 
     'class' => 'app/commands/CustomUrlManager' 
    ] 
] 

Mi piacerebbe sapere se questo funziona, è stata una sfida interessante!

+0

Wow, questo è molto intelligente e perspicace! Proverò questo metodo esatto e tornerò con i risultati. Buon lavoro! – Dean

Problemi correlati