2015-12-22 6 views
5

Mam widoki z różnych działań kontrolera, które są uruchamiane wyłącznie z elementu iframe umieszczonego w innym widoku.

Obecnie, gdy ładuje się element iframe i przechodzę do strony logowania, aby się zalogować, po pomyślnym zalogowaniu się kontroler logowania (przy użyciu modułu użytkownika yii2) wywołuje $this->goBack(), przekierowując mnie do źródłowego adresu URL elementu iframe (ponieważ jest to ostatnia strona odwiedzane), a nie oryginalna strona zawierająca element iframe.

Zasadniczo, chciałbym wykluczyć określone akcje kontrolerów z ustawionych jako zwrotny adres URL, gdy zostanie wywołana $this->goBack(). Dodatkowe punkty, jeśli wszystkie działania załadowane w elementach iframe są automatycznie wykluczane z $this->goBack().

+0

Czy wszystkie twoje ramki iframe zajmują tę samą stronę widoku? –

+0

Nie, elementy iframe znajdują się w różnych widokach. – Dean

Odpowiedz

1

OK, będę musiał się z tym pogodzić! Ten kod jest całkowicie nieprzetestowany! Twój problem polega na tym, że akcja nie ma możliwości sprawdzenia, czy została wywołana z elementu iframe, chyba że ją podasz. Tak więc podstawą mojej próby odpowiedzi jest to, że wszystkie adresy URL dla elementów iframe powinny mieć dodatkowy parametr get. Nazwijmy to caller. Więc każdy iframe powinna wyglądać

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

Teraz zawsze można przetestować URL żądania, aby sprawdzić, czy został wywołany z iframe. Ponadto każdy link w elemencie iframe powinien mieć ten parametr dodany do adresu URL.

Mamy teraz co najmniej dwa problemy. Po pierwsze, jak automatycznie dodać caller jako parametr get, bez konieczności ponownego napisania każdego adresu URL, a po drugie, jak zmienić konfigurację metody goBack(), aby wiedzieć, jaka jest różnica między tymi dwoma typami żądań.

Pierwszy problem można stosunkowo łatwo rozwiązać, dodając kolejną warstwę widoku pomiędzy kontrolerem a żądanym widokiem. Nazywam to iframe. A więc w akcji kontrolera dodaj to;

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

Twój plik widoku iframe powinien zawierać coś takiego;

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

Teraz mamy sposób testowania controller/action wezwanie, aby zobaczyć, czy to jest wymagane przez am iframe. Parametr caller jest ważny, ponieważ pozwala nam wyodrębnić ciąg znaków do użycia jako wartość dla goBack() i innych metod.

Następnie musimy rozszerzyć UrlManager, ponieważ wszystkie request, response, Url:to() i goBack() metody i klasy ostatecznie użyć UrlManager wypełnić metody generowania adresów URL.

Stwórz więc nowy UrlManager. Skopiujemy większość kodu z istniejącego UrlManager, dodając tylko odrobinę pikanterii. Przechowałem kopalnię w commands, ale umieść ją tam, gdzie chcesz i odpowiednio zmień przestrzeń nazw.

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

} 

Więc teraz, iframe generuje parametr caller, a każde ogniwo w iframe będzie również caller dołączana jako parametr, jak długo ass użyłeś albo Url::to() (lub wariantów tego sposobu) lub Yii::$app->UrlManager generować twoje linki.

Teraz wystarczy, że dostosujemy metodę goBack() kontrolera, aby wysłać wszystkie żądania goBack() do oryginalnego źródła iframe.

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

Na koniec musisz skonfigurować Yii, aby używać nowego UrlManager w pliku konfiguracyjnym;

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

Chciałbym wiedzieć, czy to działa, to było ciekawe wyzwanie!

+0

Wow, to jest bardzo sprytne i wnikliwe! Wypróbuję tę dokładną metodę i wrócę z wynikami. Dobra robota! – Dean