Zend Framework: как отобразить на одной странице несколько действий, каждое из которых требует разных уровней авторизации - PullRequest
0 голосов
/ 23 января 2009

Представьте, что у меня есть 4 таблицы базы данных и интерфейс, который представляет формы для управления данными в каждой из этих таблиц на одной веб-странице (используя шаблон дизайна гармошки, чтобы показывать только одну форму за один раз). Каждая форма отображается со списком строк в таблице, что позволяет пользователю вставить новую строку или выбрать строку для редактирования или удаления. Затем AJAX используется для отправки запроса на сервер.

Для разных пользователей должен отображаться другой набор форм в зависимости от ACL приложения.

Мой вопрос: с точки зрения контроллеров, действий, представлений и макетов, какая архитектура лучше всего подходит для этого интерфейса?

Например, пока у меня есть контроллер с действиями добавления, редактирования и удаления для каждой таблицы. Для каждого есть indexAction, но это пустая функция. Я также расширил Zend_Form для каждой таблицы. Чтобы отобразить формы, я затем в IndexController передаю формы в их представление и отображаю каждую форму. Затем Javascript позаботится о заполнении формы и отправке запросов на соответствующие действия добавления / редактирования / удаления соответствующего контроллера. Это, однако, не позволяет ACL управлять отображением или отсутствием форм для разных пользователей.

Было бы лучше, чтобы indexAction инстанцировал форму, а затем использовал что-то вроде $ this-> render (); сделать каждый вид в представлении indexAction IndexController? Может ли ACL предотвратить отображение определенных представлений?

Приветствие.

Ответы [ 3 ]

1 голос
/ 24 января 2009

Есть несколько мест, где вы можете выполнить свои проверки по вашему ACL:

  1. Где у вас есть ваш цикл (или жестко закодированный блок) для загрузки каждой формы.
  2. В конструкторе каждого из объектов формы, возможно, выдается пользовательское исключение, которое может быть перехвачено и соответствующим образом обработано.
  3. Из конструктора расширения Zend_Form, из которого расширены все ваши пользовательские объекты Form (вероятно, лучший метод, поскольку он помогает уменьшить дублирование кода).

Имейте в виду, что если вы используете ZF для выполнения решения AJAXy для своего обновления, ваш контроллер должен также выполнить проверку ACL в своем методе init(), предотвращая несанкционированные изменения в вашей БД.

Надеюсь, это поможет.

0 голосов
/ 30 мая 2010

Вы уже решили это?

Я создаю большое приложение базы данных с множеством вложенных субконтроллеров в виде панелей на панели мониторинга, показанной на родительском контроллере. Упрощенный исходный код приведен ниже: исходит от моего parentController-> indexAction ()

    $dashboardControllers = $this->_helper->model( 'User' )->getVisibleControllers();
    foreach (array_reverse($dashboardControllers) as $controllerName) // lifo stack so put them on last first
    {
        if ($controllerName == 'header') continue; // always added last
        // if you are wondering why a panel doesn't appear here even though the indexAction is called: it is probably because the panel is redirecting (eg if access denied). The view doesn't render on a redirect / forward
        $this->_helper->actionStack( 'index', $this->parentControllerName . '_' . $controllerName ); 
    }
    $this->_helper->actionStack( 'index', $this->parentControllerName . '_header' ); 

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

0 голосов
/ 30 января 2009

Я использую измененную версию того, что находится в книге «Zend Framework in Action» от Manning Press (доступно для скачивания в формате PDF, если вам это нужно сейчас). Я думаю, что вы можете просто скачать сопроводительный код с сайта книги. Вы хотите взглянуть на код главы 7.

Обзор:

Контроллер - это ресурс, а действие - это привилегия. Поместите ваши разрешения и запреты в метод init контроллера. Я также использую настроенную версию их Controller_Action_Helper_Acl.

Каждый контроллер имеет открытый статический метод getAcls:

public static function getAcls($actionName)
{
    $acls = array();
    $acls['roles']      = array('guest');
    $acls['privileges'] = array('index','list','view');

    return $acls;
}

Это позволяет другим контроллерам запрашивать разрешения этого контроллера. Каждый метод init контроллера вызывает $ this -> _ initAcls (), который определен в моем собственном базовом контроллере:

public function init()
{
    parent::init(); // sets up ACLs
}

Родитель выглядит так:

public function init()
{
    $this->_initAcls(); // init access control lists.
}

protected function _initAcls()
{
    $to_call = array(get_class($this), 'getAcls');
    $acls = call_user_func($to_call, $this->getRequest()->getActionName());
    // i.e. PageController::getAcls($this->getRequest()->getActionName());

    if(isset($acls['roles']) && is_array($acls['roles']))
    {
        if(count($acls['roles'])==0)     { $acls['roles'] = null; }
        if(count($acls['privileges'])==0){ $acls['privileges'] = null; }
        $this->_helper->acl->allow($acls['roles'], $acls['privileges']);
    }
}

Тогда у меня просто есть функция с именем:

aclink($link_text, $link_url, $module, $resource, $privilege);

Он вызывает {$ resource} Controller :: getAcls () и проверяет разрешения для них. Если у них есть разрешение, он возвращает ссылку, в противном случае он возвращает ''.

function aclink($link_text, $link_url, $module, $resource, $privilege)
{
    $auth = Zend_Auth::getInstance();

    $acl = new Acl(); //wrapper for Zend_Acl
    if(!$acl->has($resource))
    {
       $acl->add(new Zend_Acl_Resource($resource));
    }

    require_once ROOT.'/application/'.$module.'/controllers/'.ucwords($resource).'Controller.php';

    $to_call = array(ucwords($resource).'Controller', 'getAcls');
    $acls = call_user_func($to_call, $privilege);

    if(isset($acls['roles']) && is_array($acls['roles']))
    {
        if(count($acls['roles'])==0)     { $acls['roles'] = null; }
        if(count($acls['privileges'])==0){ $acls['privileges'] = null; }
        $acl->allow($acls['roles'], $resource, $acls['privileges']);
    }

    $result = $acl->isAllowed($auth, $resource, $privilege);

    if($result)
    {
       return '<a href="'.$link_url.'" class="aclink">'.$link_text.'</a>';
    }
    else
    {
       return '';
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...