#php #zend-framework #zend-navigation #zend-acl
#php #zend-framework #zend-навигация #zend-acl
Вопрос:
Я работаю над плагином аутентификации с использованием плагина контроллера. Я определяю свою конфигурацию навигации в файле application.ini, а затем использую это и пользовательские записи базы данных для динамической загрузки списка управления доступом и применения его к Zend_Navigation. Этот бит работает, поскольку он успешно загружает меню и отображает только те страницы, которые разрешено просматривать пользователю.
Однако это не останавливает пользователя от прямого перехода на страницу. Что я хочу сделать, так это определить, когда пользователь переходит на страницу, к которой у него нет доступа в плагине контроллера, чтобы я мог перенаправить их запрос на страницу аутентификации.
Я думал, что должна быть функция для получения текущей страницы из Zend_Navigation, но я не могу ее найти … так что, возможно, она не существует.
В любом случае, это мой полноценный плагин для контроллера. Кто-нибудь видит решение?
<?php
class Pog_Model_AuthPlugin extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $oRequest)
{
/**
* Load user
*/
$oAuth = Zend_Auth::getInstance();
$oDbUsers = new Pog_Model_DbTable_Users();
if (!$oAuth->hasIdentity())
{
$oUser = $oDbUsers->createRow();
$oUser->name = "guest";
$oUser->setReadOnly(true);
}
else
{
$oUser = $oAuth->getIdentity();
$oUser->setTable($oDbUsers);
}
/**
* Load ACL
*/
$oAcl = new Zend_Acl();
$oAcl->addRole($oUser->name);
/**
* Add current user privileges
*/
$oPrivileges = $oUser->getPrivileges();
foreach ($oPrivileges as $oPrivilege)
{
if (!$oAcl->has($oPrivilege->resource))
$oAcl->addResource($oPrivilege->resource);
$oAcl->allow($oUser->name, $oPrivilege->resource, $oPrivilege->privilege);
}
/**
* Load Navigation view helper
*/
$oViewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
$oNavigation = $oViewRenderer->view->navigation();
/**
* Add remaining Navigation resources
*/
foreach ($oNavigation->getPages() as $oPage)
{
if (!is_null($oPage->getResource()) amp;amp; !$oAcl->has($oPage->getResource()))
$oAcl->addResource($oPage->getResource());
}
/**
* Set ACL and Role
*/
$oNavigation->setAcl($oAcl)->setRole($oUser->name);
/**
* Check if use is allowed to be here
*/
...MAGIC GOES HERE...
}
}
Ответ №1:
Я думаю, что вы должны иметь возможность получить текущую страницу навигации следующим образом:
/**
* Load Navigation view helper
*/
$oViewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
$oNavigation = $oViewRenderer->view->navigation();
/*@var $active array */
$active = $oNavigation->findActive($oNavigation->getContainer());
/*@var $activePage Zend_Navigation_Page_Mvc */
$activePage = $active['page'];
// example of getting page info
var_dump($activePage->getLabel(), $activePage->getController(), $activePage->getAction());
Надеюсь, это поможет.
Комментарии:
1. Это похоже на то, что мне нужно, но в ответ я получаю пустой массив. Может ли это иметь какое-то отношение к тому, что я запускаю ее в плагине контроллера?
2. Я просто поместил некоторый тестовый код в скрипт просмотра, и вышеприведенный работает нормально. Похоже, что навигационный помощник не полностью настроен, когда я добираюсь до него в плагине контроллера, но после этого все в порядке… Теперь, чтобы узнать, когда она будет настроена, и посмотреть, смогу ли я ее запустить.
3. @Valorin. Я протестировал код в preDispatch моего плагина acl controller, и все в порядке. Как вы настраиваете свою навигацию? Я настраиваю навигацию в bootstrap.php ? Может быть, в моем случае это способ инициализации?
4. @Marcin, я настраиваю свою навигацию в файле application.ini, используя ресурс навигации, так что это может быть так. Хотя, если это так, то это немного странно. Похоже, что код для Nav запрашивает активный контроллер и действие через внешний контроллер — поэтому я предположил, что это еще не настроено.
5. @Valorin. Вот как я инициализирую свою навигацию в bootstrap.php: pastebin.com/TrCf0Bm5 . Возможно, это будет полезно.
Ответ №2:
Это решение, которое я использовал, поскольку по какой-то причине я не могу заставить решение Marcin работать в моей настройке.
Я еще немного подумал и придумал хорошее простое решение проблемы. Вместо того, чтобы использовать модуль навигации для поиска активной страницы, я нахожу ее сам. Поскольку я уже перебираю страницы, сравнить контроллер и действие проще простого — если они оба совпадают, у меня есть моя активная страница!
Новый цикл getPages() для каждого из них выглядит следующим образом:
$oCurrentPage = null;
foreach ($oNavigation->getPages() as $oPage)
{
/**
* Check for Current Page
*/
if ($oPage->getController() == $oRequest->getControllerName()
amp;amp; $oPage->getAction() == $oRequest->getActionName())
$oCurrentPage = $oPage;
/**
* Add Resource, if missing
*/
if (!is_null($oPage->getResource()) amp;amp; !$oAcl->has($oPage->getResource()))
$oAcl->addResource($oPage->getResource());
}