Класс Zend Framework Inspect Controller для тегов docblock - PullRequest
0 голосов
/ 11 сентября 2011

Я хотел реализовать плагин FrontController для авторизации, основанный на аннотациях, как ASP.NET Mvc.Я подумал, что смогу написать плагин для фронт-контроллера и добавить проверку авторизации в один из хуков, предоставляемых Zend Framework.Пример:

class My_Controller_Plugin_Authorize extends Zend_Controller_Plugin_Abstract {
    public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request){
        ...
        if($user_is_not_loggedin){
             goSomeWhereElse();
        }
    }
}

class MyFancyController extends Zend_Controller_Action{

   /**
    * @Authorize
    */
    public function secretAction(){
        ...
    }
}

Теперь мне нужно проверить docblocks в фактическом запрашиваемом контроллере, чтобы выяснить, требует ли действие, на которое направляет пользователь, авторизация или нет.И оказалось, что это не так просто: объект запроса является единственным ресурсом, который передается в хуки.

Я думал, что мог бы создать имя класса контроллера, выполнив controllerName + "Controller", но класс нене загружается, и поэтому он не найден, и код разрушается.

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 16 сентября 2011

Это моё решение.Аннотация @Authorize работает либо в верхней части класса, либо в верхней части отдельных методов.Очевидно, может быть расширен для проверки с ACL.

<?php
class Ant_Controller_Plugin_Authorize extends Zend_Controller_Plugin_Abstract {

    public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request){
        $frontController = Zend_Controller_Front::getInstance();
        $dispatcher = $frontController->getDispatcher();
        $controllerClass = $dispatcher->getControllerClass($request);
        $dispatcher->loadClass($controllerClass);
        $reflectionClass = new Zend_Reflection_Class($controllerClass);
        $reflectionMethod = $reflectionClass->getMethod($dispatcher->getActionMethod($request));
        try {
            $authClass = $reflectionClass->getDocblock()->hasTag("Authorize");
        } catch (Exception $e) {
            $authClass = false;
        }
        try{
            $authMethod = $reflectionMethod->getDocblock()->hasTag("Authorize");
        }catch (Exception $e){
            $authMethod = false;
        }

        if($authClass || $authMethod){
            if(!Zend_Auth::getInstance()->hasIdentity()){
                $request->setActionName("login")->setControllerName("Accounts");
                $request->setDispatched(false);
            }
        }
    }
}

, а затем в application.ini

resources.frontController.plugins.Authorize = "Ant_Controller_Plugin_Authorize"
0 голосов
/ 12 сентября 2011

Как вы отметили в своем комментарии к вашему вопросу, диспетчер имеет доступ к фактическому контроллеру экземпляр - в отличие от просто контроллера name .

Другое место, где есть доступ к экземпляру контроллера, - это action helper , который имеет доступ к экземпляру контроллера. Так, может быть, хелпер действий с хуком preDispatch(), который выполняет интроспекцию докблока на основе отражений? Возможно некоторое снижение производительности, так как отражение считается медленным.

Но, в общем, это звучит так, как будто вам нужен контроль доступа, который обычно обрабатывается с использованием Zend_Acl, а затем пишется подключаемый модуль контроллера, использующий этот объект ACL. Если вы действительно не должны выполнять основанную на отражении проверку аннотаций докблока для своего ACL, я бы использовал подход ACL / плагин.

...