Настройка управления доступом Точное управление доступом Базовый ACL, как было описано в предыдущем разделе, демонстрирует, как различные привилегии могут быть разрешены в ACL (ко всем ресурсам). Но на практике средства управления доступом имеют тенденцию к тому, чтобы иметь исключения из правил и различную степень сложности. Zend_Acl позволяет производить детализацию просто и гибко. Для CMS из нашего примера было установлено, что хотя группа 'сотрудник' подходит большинству пользователей, возникла необходимость в новой группе 'маркетинг', которая имела бы доступ к подписке и последним новостям в CMS. Группа в некоторой степени самодостаточна и будет иметь возможность публиковать и удалять как подписки, так и последние новости. Кроме этого, необходимо, чтобы группе 'сотрудник' было разрешено просматривать новости, но запрещено редактировать их. И наконец, должно быть запрещено всем (в том числе и администраторам) помещать в архив любые 'объявления', если с момента добавления прошло только 1-2 дня. В первую очередь мы модифицируем реестр ролей для отражения этих изменений. Мы определили, что группа 'маркетинг' имеет те же базовые права, что и 'сотрудник', поэтому мы определим 'маркетинг' таким образом, чтобы она наследовала права группы 'сотрудник': addRole(new Zend_Acl_Role('marketing'), 'staff'); ]]> Далее обратите внимание, что указанные выше права доступа имеют отношение к особым ресурсам (например, "подписка", "последние новости"). Теперь добавим эти ресурсы: add(new Zend_Acl_Resource('newsletter')); // новости $acl->add(new Zend_Acl_Resource('news')); // последние новости $acl->add(new Zend_Acl_Resource('latest'), 'news'); // объявления $acl->add(new Zend_Acl_Resource('announcement'), 'news'); ]]> Затем определяются более точные правила для целевых областей ACL. allow('marketing', array('newsletter', 'latest'), array('publish', 'archive')); // Пользователю (и маркетингу через наследование), запрещено редактировать // последние новости $acl->deny('staff', 'latest', 'revise'); // Всем, включая администраторов, не разрешается удалять объявления $acl->deny(null, 'announcement', 'archive'); ]]> Теперь мы можем производить запросы к ACL с учетом последних изменений: isAllowed('staff', 'newsletter', 'publish') ? "разрешен" : "запрещен"; // запрещен echo $acl->isAllowed('marketing', 'newsletter', 'publish') ? "разрешен" : "запрещен"; // разрешен echo $acl->isAllowed('staff', 'latest', 'publish') ? "разрешен" : "запрещен"; // запрещен echo $acl->isAllowed('marketing', 'latest', 'publish') ? "разрешен" : "запрещен"; // разрешен echo $acl->isAllowed('marketing', 'latest', 'archive') ? "разрешен" : "запрещен"; // разрешен echo $acl->isAllowed('marketing', 'latest', 'revise') ? "разрешен" : "запрещен"; // запрещен echo $acl->isAllowed('editor', 'announcement', 'archive') ? "разрешен" : "запрещен"; // запрещен echo $acl->isAllowed('administrator', 'announcement', 'archive') ? "разрешен" : "запрещен"; // запрещен ]]> Удаление правил доступа Для того, чтобы удалить одно или несколько правил из ACL, используйте методы removeAllow() или removeDeny(). Как и в случае с allow() и deny(), вы можете передавать NULL в качестве параметра, чтобы применить метод ко всем ролям, ресурсам, и/или привилегиям: removeDeny('staff', 'latest', 'revise'); echo $acl->isAllowed('marketing', 'latest', 'revise') ? "разрешен" : "запрещен"; // разрешен // Убираем разрешение на публикацию и удаление подписки для маркетинга $acl->removeAllow('marketing', 'newsletter', array('publish', 'archive')); echo $acl->isAllowed('marketing', 'newsletter', 'publish') ? "разрешен" : "запрещен"; // запрещен echo $acl->isAllowed('marketing', 'newsletter', 'archive') ? "разрешен" : "запрещен"; // запрещен ]]> Привилегии могут модифицироваться в порядке возрастания, как показано выше, но параметр NULL для привилегий переопределяет такой порядок изменений: allow('marketing', 'latest'); echo $acl->isAllowed('marketing', 'latest', 'publish') ? "разрешен" : "запрещен"; // разрешен echo $acl->isAllowed('marketing', 'latest', 'archive') ? "разрешен" : "запрещен"; // разрешен echo $acl->isAllowed('marketing', 'latest', 'anything') ? "разрешен" : "запрещен"; // разрешен ]]>