Зенд комментарий загрузочный код


Я работаю над внедрением нового приложения от Зенд. В моей админке, я хочу сча ссылки, чтобы показывать только если пользователь имеет права, чтобы просмотреть страницу. Поэтому я создал несколько списков ACL. Но это не похоже на правильный способ сделать вещи. Какой "правильный" способ сделать это?

Bootstrap.php

<?php

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap {
    protected $_aclAdapter;


    protected function _initDoctype() {
        $this->bootstrap('view');
        $view = $this->getResource('view');
        $view->doctype('XHTML1_STRICT');
    }

    protected function _initPlugins() {
        // First, set up the Cache
        $frontendOptions = array(
                'automatic_serialization' => true
                );

        if (! is_dir("/tmp/cache")) mkdir("/tmp/cache");
        $backendOptions  = array(
                'cache_dir'                => '/tmp/cache'
                );

        $cache = Zend_Cache::factory('Core',
                'File',
                $frontendOptions,
                $backendOptions);

        Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);


        $this->_aclAdapter = new My_Plugin_Acl();
    }

    protected function _initRoute() {

        /*
        $this->bootstrap('FrontController');
        $front = $this->getResource('FrontController');
        $router = $front->getRouter();

        $restRoute = new Zend_Rest_Route($front, array(), array('rest'));
        $router->addRoute('rest', $restRoute);

        return $router;
        */
    }

    protected function _initAutoloadModuleAdmin() {
        $autoloader = new Zend_Application_Module_Autoloader(
            array(
                'namespace' => 'Admin',
                'basePath' => APPLICATION_PATH . '/modules',
            )
        );
        return $autoloader;
    }

    protected function _initDatabase() {
        $database = Zend_Db_Table::getDefaultAdapter();
        return $database;
    }

    protected function _initAuthChecker() {
        $this->bootstrap('view');
        $view = $this->getResource('view');

        /**
         *  @todo Determine how to pass Acl information to the view
         *  so that links can be determined properly
         */


        $auth = Zend_Auth::getInstance();
        if ($auth->hasIdentity()) {
            $view->isLoggedIn = true;

            $aclAdapter = $this->_aclAdapter;

            $container = new Zend_Navigation();

            $pages = array(
                new Zend_Navigation_Page_Mvc(array('module' => 'admin', 'action' => 'index', 'controller' => 'make', 'label' => 'Makes')),
                new Zend_Navigation_Page_Mvc(array('module' => 'admin', 'action' => 'index', 'controller' => 'model', 'label' => 'Models')),
                new Zend_Navigation_Page_Mvc(array('module' => 'admin', 'action' => 'index', 'controller' => 'year', 'label' => 'Years')),
                new Zend_Navigation_Page_Mvc(array('module' => 'admin', 'action' => 'index', 'controller' => 'user', 'label' => 'Users')),
            );

            foreach ($pages as $page) {
                $resources = $aclAdapter->getCurrentResources($page);


                $allowedToViewResource = true;
                foreach ($resources as $resource) {
                    // access to the module
                    if(!$aclAdapter->isAllowed($aclAdapter->getRolesForIdentity($auth->getIdentity()->nickname), $resource, 'view')) {
                        $allowedToViewResource = false;
                    }
                }

                if ($allowedToViewResource) {
                    $container->addPage($page);
                }
                $view->navigation = $container;
            }

        } else {
            $view->isLoggedIn = false;
        }
    }
}

My/Plugin/Acl.php

<?php

/**
 * Acl functionality
 *
 * @category My
 * @package  My_Plugin
 * @author   Glen Solsberry <glens@dp.cx>
 */


class My_Plugin_Acl extends Zend_Controller_Plugin_Abstract {
    /**
     * @var Zend_Acl
     */
    protected $_acl = null;

    public function __construct() {

        $args = func_get_args();
        if (count($args) > 0) {
            $this->_acl = $args[0];
        } else {
            $this->_acl = new Zend_Acl();
        }

        $this->_acl = $this->setupRoles($this->_acl);
        $this->_acl = $this->setupResources($this->_acl);
        $this->_acl = $this->setupAllowances($this->_acl);
    }

    public function isAllowed($role, $resource, $function) {
        return $this->_acl->isAllowed($role, $resource, $function);
    }


    /**
     * preDispatch
     *
     * @param Zend_Controller_Request_Abstract $request
     * @return none
     */
    public function preDispatch(Zend_Controller_Request_Abstract $request) {

        if (Zend_Auth::getInstance()->hasIdentity()) {
                $identity = Zend_Auth::getInstance()->getIdentity();
            $role = $this->getRolesForIdentity($identity->nickname);
        } else {
            $role = 'guest';
        }

        $resources = $this->getCurrentResources($request);

        $allowedToViewResource = true;
        foreach ($resources as $resource) {
            // access to the module
            if(!$this->_acl->isAllowed($role, $resource, 'view')) {
                $allowedToViewResource = false;
            }
        }
        if ($allowedToViewResource === false) {
            //If the user has no access we send him elsewhere by changing the request
            // print sprintf("I'm sorry, but your role '%s' doesn't have access to the resource named '%s'<br>", $role, $resource);
            $request->setModuleName('')->setControllerName('auth')->setActionName('login');
            return false;
        }
        return true;
    }

    public function getCurrentResources($request) {

        if ($request instanceOf Zend_Controller_Request_Http) {
            $resources = array(
                $request->getModuleName(),
                implode("-", array($request->getModuleName(), $request->getControllerName())),
                implode("-", array($request->getModuleName(), $request->getControllerName(), $request->getActionName())),
            );
        } else if ($request instanceOf Zend_Navigation_Page_Mvc) {
            $resources = array(
                $request->getModule(),
                implode("-", array($request->getModule(), $request->getController())),
                implode("-", array($request->getModule(), $request->getController(), $request->getAction())),
            );
        } else {
            throw new Zend_Exception('Unsupported request type');
        }

        return $resources;
    }

    /**
     * Gets available roles for an identity, by nickname
     * @param string $nickname
     */
    public function getRolesForIdentity($nickname)  {
        if ($nickname === "") {
            return 'guest';
        }
        return 'admin';
    }

    private function setupRoles(Zend_Acl $acl) {
        $acl->addRole(new Zend_Acl_Role('guest'));

        // make-admin has all rights that guest has
        $acl->addRole(new Zend_Acl_Role('make-admin'), 'guest');
        $acl->addRole(new Zend_Acl_Role('model-admin'), 'guest');
        $acl->addRole(new Zend_Acl_Role('year-admin'), 'guest');
        $acl->addRole(new Zend_Acl_Role('user-admin'), 'guest');

        // admin has all rights that year-admin, make-admin, user-admin and model-admin have
        $acl->addRole(new Zend_Acl_Role('admin'), array('year-admin', 'make-admin', 'model-admin', 'user-admin'));

        return $acl;
    }

    private function setupResources(Zend_Acl $acl) {

        // setup admin resources
        $this->setupResourcesFromArrays(
            $acl,
            array('admin'),
            array('index','make','year','model','user'),
            array('index','update','delete')
        );

        $this->setupResourcesFromArrays(
            $acl,
            array('default'),
            array('auth','index','error'),
            array('index')

        );

        $this->setupResourcesFromArrays(
            $acl,
            array('default'),
            array('auth'),
            array('logout')
        );

        $this->setupResourcesFromArrays(
            $acl,
            array('default'),
            array('favicon.ico'),
            null
        );

        return $acl;
    }

    private function setupResourcesFromArrays($acl, $modules, $controllers, $actions) {
        foreach ($modules as $module) {
            $resource_name = $module;
            $this->addResource($acl, $resource_name);

            foreach ($controllers as $controller) {
                $resource_name = sprintf('%s-%s', $module, $controller);
                $this->addResource($acl, $resource_name);

                if (is_array($actions)) {
                    foreach ($actions as $action) {
                        $resource_name = sprintf('%s-%s-%s', $module, $controller, $action);
                        $this->addResource($acl, $resource_name);
                    }
                }
            }
        }
    }

    private function addResource($acl, $resource_name) {
        if (! $acl->has($resource_name)) {
            $acl->addResource(new Zend_Acl_Resource($resource_name));
        }
    }

    private function setupAllowances(Zend_Acl $acl) {
        // role, resource, privilege
        $acl->allow('admin', 'admin', 'view');
        $acl->allow('admin', 'admin-index', 'view');
        $acl->allow('admin', 'admin-index-index', 'view');
        /**
          SNIP
        */

        $acl->allow('guest', 'default', 'view');
        $acl->allow('guest', 'default-index', 'view');
        $acl->allow('guest', 'default-index-index', 'view');
        $acl->allow('guest', 'default-auth', 'view');
        $acl->allow('guest', 'default-auth-index', 'view');

        return $acl;
    }
}


1120
3
задан 3 июня 2011 в 08:06 Источник Поделиться
Комментарии
1 ответ

Вы должны использовать имеющийся загрузочный ресурсы , где можно:

protected function _initPlugins() {
// First, set up the Cache
$frontendOptions = array(
'automatic_serialization' => true
);

if (! is_dir("/tmp/cache")) mkdir("/tmp/cache");
$backendOptions = array(
'cache_dir' => '/tmp/cache'
);

$cache = Zend_Cache::factory('Core',
'File',
$frontendOptions,
$backendOptions);

могут быть заменены без каких-либо функций в ушко:

resources.cachemanager.yourcachename.frontend.name = Core
resources.cachemanager.yourcachename.options.automatic_serialization = true
resources.cachemanager.yourcachename.backend.name = File
resources.cachemanager.yourcachename.backend.options.cache_dir = "/tmp/cache"

Наконец, вы активируете metadatacache для вашей базы данных:

resources.db.defaultMetadataCache = "yourcachename"

Тоже самое можно проделать с вашей точки зрения:

protected function _initDoctype() {
$this->bootstrap('view');
$view = $this->getResource('view');
$view->doctype('XHTML1_STRICT');
}

// can be replaced with:
resources.view.doctype = "XHTML1_STRICT"

Предполагая, что вы настраиваете базу данных в вашей конфигурации, вы, вероятно, не нужна эта строка:

protected function _initDatabase() {
$database = Zend_Db_Table::getDefaultAdapter();
return $database;
}

Вы можете сделать то же самое для автозагрузчика и маршруты, а также.
Это, вероятно, должно быть плагин на свой собственный:

protected function _initAuthChecker() 
{
/* .... */
}

До сих пор на ушко. Я вижу, что вы принять ваши модули/контроллеры в качестве ресурсов. Обычно я не согласны с этим: контроллер обрабатывает набор моделей, которые являются ресурсы. Я знаю, что это не облегчает навигацию ;) вы должны взглянуть на модуль-бутстрап тоже. Они принимают модуля bootstraping от основной-загрузчик.

1
ответ дан 4 июня 2011 в 09:06 Источник Поделиться