Yii2:从'$ this-> goBack()'中排除特定的控制器操作

时间:2015-12-22 17:59:16

标签: yii2 yii2-user

我有来自各种控制器操作的视图,这些操作只能从放置在另一个视图中的iframe运行。

目前,当iframe加载,我进入登录页面登录时,登录控制器(使用yii2用户模块)成功调用$this->goBack(),将我重定向到iframe源URL(因为它是访问的最后一页),而不是包含iframe的原始页面。

基本上,我想在调用$this->goBack()时将特定控制器操作排除在设置为返回URL之外。如果iframe中加载的所有操作都自动从$this->goBack()中排除,则会获得积分。

1 个答案:

答案 0 :(得分:1)

好的,我会去看看!此代码完全未经测试!你的问题是,除非你给它一个,否则动作无法知道它是否是从iframe调用的。因此,我尝试回答的基础是iframe的所有网址都应该有一个额外的get参数。让我们称之为caller。所以每个iframe应该看起来像

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

现在,您始终可以测试请求网址以查看是否从iframe调用了该网址。此外,iframe中的每个链接都应该将此参数添加到其中

所以,现在我们至少有两个问题。首先,如何自动添加caller作为get参数,而不必重写每个网址,其次,如何重新配置​​goBack()方法,以便它知道两者之间的区别请求的类型。

通过在控制器和您想要的视图之间添加另一个视图层,可以相对轻松地解决第一个问题,我将其称为iframe。所以在你的控制器动作中,添加它;

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

您的iframe视图文件应包含以下内容;

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

现在我们有一种方法可以测试controller/action调用,看看是否是iframe请求的。 caller参数很重要,因为它允许我们提取字符串以用作goBack()和其他方法的值。

接下来,我们需要扩展UrlManager,因为所有requestresponseUrl:to()goBack()方法和类最终都使用UrlManager完成生成网址的方法。

因此,创建一个新的UrlManager。我们将从现有的UrlManager中复制大部分代码,只是添加了我们自己的一些辛辣。我已将其存储在commands中,但请将您的位置放在您喜欢的位置并相应更改名称空间。

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

}

现在,iframe会生成一个caller参数,iframe中的每个链接也会附加caller作为参数,只要您使用Url::to() (或该方法的变体)或Yii::$app->UrlManager生成链接。

现在我们需要做的就是自定义控制器的goBack()方法,将任何goBack()请求发送到原始源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));
    }

最后,您需要在配置文件中配置Yii以使用新的UrlManager;

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

我很想知道这是否有效,这是一个有趣的挑战!