<sect1 id="zend.acl.advanced">

    <title>Продвинутое использование</title>

    <sect2 id="zend.acl.advanced.storing">

        <title>Постоянное хранение данных ACL</title>

        <para>
            Zend_Acl спроектирован таким образом, что не требует для хранения
            данных ACL использования строго определенных технологий хранения -
            таких, как база данных или сервер кеша. Его реализация на чистом PHP
            позволяет создавать административные инструменты под управлением
            Zend_Acl с относительной простотой и гибкостью.
            Многие ситуации требуют некоторой интерактивной поддержки от ACL, и
            Zend_Acl предоставляет методы для настройки, произведения запросов,
            контроля доступа приложением.
       </para>

        <para>
            Тем не менее, хранение данных ACL остается задачей разработчика,
            т.к. случаи использования могут сильно варьироваться в различных
            ситуациях. Поскольку Zend_Acl доступен для сериализации, то можно
            сериализовать объекты ACL через PHP-функцию
            <ulink url="http://php.net/serialize"><code>serialize()</code></ulink>,
            и результаты можно хранить там, где пожелает разработчик - например,
            в файле, базе данных или с помощью механизма кэширования.
     </para>

    </sect2>

    <sect2 id="zend.acl.advanced.assertions">

        <title>Написание условных правил ACL с утверждениями</title>

        <para>
            Иногда правило разрешения или запрета доступа роли к ресурсу должно
            быть не безусловным, а зависеть от различных критериев. Например,
            определенный доступ должен быть разрешен, но только с 8:00 до 17:00.
            Другой пример - доступ должен быть запрещен, если запрос поступил
            с IP-адреса, находящегося в "черном списке". Zend_Acl имеет
            встроеную поддержку для применения правил, основанных на любых
            нужных разработчику условиях.
        </para>

        <para>
            Zend_Acl предоставляет поддержку условных правил с помощью
            интерфейса <code>Zend_Acl_Assert_Interface</code>.
            Чтобы использовать интерфейс утверждений, разработчик должен
            написать класс, который реализует метод <code>assert()</code>
            интерфейса:
         </para>

        <programlisting role="php"><![CDATA[
class CleanIPAssertion implements Zend_Acl_Assert_Interface
{
    public function assert(Zend_Acl $acl,
                           Zend_Acl_Role_Interface $role = null,
                           Zend_Acl_Resource_Interface $resource = null,
                           $privilege = null)
    {
        return $this->_isCleanIP($_SERVER['REMOTE_ADDR']);
    }

    protected function _isCleanIP($ip)
    {
        // ...
    }
}
]]>
        </programlisting>

        <para>
            После объявления класса утверждения разработчик должен передавать
            экземпляр этого класса при определении условных правил. Правило,
            которое создается с утверждением, применяется
            только тогда, когда метод утверждения возвращает true.
        </para>

        <programlisting role="php"><![CDATA[
$acl = new Zend_Acl();
$acl->allow(null, null, null, new CleanIPAssertion());
]]>
        </programlisting>

        <para>
            Код выше создает условное правило, разрешающее
            всем доступ ко всем привилегиям всех ресурсов, за исключением
            случаев, когда IP-адрес запрашивающего занесен в "черный список".
            Если запрос приходит с IP-адреса, который не определяется как
            "белый", то правило не применяется.
            Поскольку правило применяется ко всем ролям, всем ресурсам и всем
            привилегиям, то "черный" IP приведет к запрещению доступа.
            Тем не менее, это особый случай, и следует понимать, что во всех
            других случаях (например, когда для правила были указаны роль,
            ресурс, или привилегия), невыполнение утверждения приводит к тому,
            что правило не применяется, и для определения того, реазрешить ли
            доступ или запретить, могут использоваться другие правила.
        </para>

        <para>
            Методу <code>assert()</code> объекта утверждения передаются ACL,
            роль, ресурс и привилегия, к которым применяется запрос на
            авторизацию (например, <code>isAllowed()</code>). Это нужно для
            предоставления контекста классу утверждения и определения его
            условий там, где это нужно.
        </para>

    </sect2>

</sect1>
<!--
vim:se ts=4 sw=4 et:
-->
