Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating my first filter extension #5

Open
drodata opened this issue Jul 6, 2015 · 0 comments
Open

Creating my first filter extension #5

drodata opened this issue Jul 6, 2015 · 0 comments

Comments

@drodata
Copy link
Owner

drodata commented Jul 6, 2015

1. What is Filter?

a piece of code that is configured to be executed before and / or after a controller action executes.

https://trello.com/c/IGUwxO73

2. Creating a Filter Extension

Filter extension 必须继承自 CFilter 或其子类。实现过程主要涉及两个方法:CFilter::preFilter()CFilter::postFilter().

class MyFilter extends CFilter
{
    protected function preFilter($filterChain)
    {
        // logic being applied before the action is executed
        return true; // false if the action should not be executed
    }

    protected function postFilter($filterChain)
    {
        // logic being applied after the action is executed
    }
}

上面两个方法都携带一个类型为 CFilterChain Class 的参数 $filterChain.

我们可以向 Controller Extension 那样,将 Filter Extension 也放在 extensions/ 目录下,

Given a filter class XyzClass belonging to the xyz extension, we can use it by overriding the CController::filters method in our controller class:

class TestController extends CController
{
    public function filters()
    {
        return array(
            array(
                'ext.xyz.XyzClass',
                'property1'=>'value1',
                'property2'=>'value2',
            ),
            // other filters
        );
    }
}

Practise

读完后立刻想到 commit :在想要进行访问控制的 Controller 中都添加了内置的 accessControl filter, 此 filter 需要在 accessRules() 内配置。这个 filter 功能很强大。为了实践本节学的理论知识,我们创建一个名为 LoginFilter 的 filter extension, 简单实现用户是否登录的 filter.

// in extensions/filter/login/
class LoginFilter extends CFilter
{
    protected function preFilter($filterChain)
    {
        if (Yii::app()->user->id)
            $filterChain->run();
        else
        {
            Yii::app()->request->redirect(Yii::app()->baseUrl.'/site/login');
            return false;
        }
    }
}

我们在 BackController 中不再使用 AccessControl Filter, 改用 LoginFilter 来达到禁止未登录用户访问的目的:

class BackController extends Controller
{
    public function filters()
    {
        return array(
            array('ext.filter.login.LoginFilter'),
        );
    }
}

LoginFilter 适用于 BackController 内所有 actions, 有时我们需要 filter 仅针对部分 actions, 这时我们可以在 filter path alias 后面使用 +, -, 后面跟着 action name, 来实现指定 actions. 例如 #15 中的一个实例:

array('ext.filter.precheck.PostRequestCheckFilter + delete')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant