<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: 20763 -->
<sect1 id="zend.acl.refining">
    <title>Verfeinern der Zugriffskontrolle</title>

    <sect2 id="zend.acl.refining.precise">
        <title>Präzise Zugangsbeschränkung</title>

        <para>
            Die grundlegende <acronym>ACL</acronym>, wie sie im <link
                linkend="zend.acl.introduction">vorherigen Kapitel</link> definiert ist, zeigt wie
            verschiedene Rechte für die gesamte <acronym>ACL</acronym> (alle Ressourcen) vergeben
            werden können. In der Praxis tendieren Zugangsbeschränkungen jedoch eher dahin,
            Ausnahmen und verschiedene Stufen von Komplexität zu haben.
            <classname>Zend_Acl</classname> erlaubt einem, diese Verfeinerungen auf einfache und
            flexible Weise zu bewerkstelligen.
        </para>

        <para>
            Für das Beispiel <acronym>CMS</acronym> wurde ermittelt, dass während die Gruppe
            'staff' die Bedürfnisse der überwiegenden Mehrheit der Benutzer abdeckt, es den Bedarf
            für eine neue Gruppe 'marketing' gibt, die Zugriff auf den Newsletter und die neuesten
            Nachrichten im <acronym>CMS</acronym> benötigen. Die Gruppe ist ziemlich unabhängig und
            wird die Möglichkeit haben, sowohl Newsletter als auch die neuesten Nachrichten zu
            veröffentlichen und zu archivieren.
        </para>

        <para>
            Zusätzlich wurde angefordert, dass es der Gruppe 'staff' erlaubt sein soll, die
            Nachrichten ansehen, aber nicht die neuesten Nachrichten überarbeiten zu können.
            Letztendlich soll es für jeden (Administratoren eingeschlossen) unmöglich sein, irgend
            eine Bekanntmachung zu archivieren, da diese sowieso nur eine Lebensdauer von 1 bis 2
            Tagen haben.
        </para>

        <para>
            Zuerst überarbeiten wir die Rollenregistrierung, um die Änderungen wider zu spiegeln.
            Wir haben ermittelt, dass die Gruppe 'marketing' dieselben grundlegenden Rechte wie
            'staff' hat, also definieren wir 'marketing' so, dass die Genehmigungen von 'staff'
            geerbt werden:
        </para>

        <programlisting language="php"><![CDATA[
// Die neue Gruppe Marketing erbt Genehmigungen der Mitarbeiter
$acl->addRole(new Zend_Acl_Role('marketing'), 'staff');
]]></programlisting>

        <para>
            Als nächstes ist zu beachten, dass sich die obige Zugangsbeschränkung auf bestimmte
            Ressourcen bezieht (z.B. "newsletter", "lastest news", "announcement news"). Nun fügen
            wir die Ressourcen hinzu:
        </para>

        <programlisting language="php"><![CDATA[
// Ressourcen für die Regeln erstellen

// Newsletter
$acl->addResource(new Zend_Acl_Resource('newsletter'));

// Nachrichten
$acl->addResource(new Zend_Acl_Resource('news'));

// Neueste Nachrichten
$acl->addResource(new Zend_Acl_Resource('latest'), 'news');

// Bekanntmachungen
$acl->addResource(new Zend_Acl_Resource('announcement'), 'news');
]]></programlisting>

        <para>
            Nun ist es nur eine Frage der Definition für diese spezifischeren Regeln auf die
            Zielbereiche der <acronym>ACL</acronym>:
        </para>

        <programlisting language="php"><![CDATA[
// Marketing muss Newsletter und die neuesten Nachrichten veröffentlichen
// und archivieren können
$acl->allow('marketing',
            array('newsletter', 'latest'),
            array('publish', 'archive'));

// Staff (und Marketing durch die Vererbung), wird die Erlaubnis verweigert,
// die neuesten Nachrichten überarbeiten zu können
$acl->deny('staff', 'latest', 'revise');

// Jedem (inklusive der Administratoren) wird die Erlaubnis verweigert,
// Bekanntmachungsnachricht zu archivieren
$acl->deny(null, 'announcement', 'archive');
]]></programlisting>

        <para>
            Wir können nun die <acronym>ACL</acronym> hinsichtlich der letzten Änderungen abfragen:
        </para>

        <programlisting language="php"><![CDATA[
echo $acl->isAllowed('staff', 'newsletter', 'publish') ?
     "allowed" : "denied";
// verweigert

echo $acl->isAllowed('marketing', 'newsletter', 'publish') ?
     "allowed" : "denied";
// erlaubt

echo $acl->isAllowed('staff', 'latest', 'publish') ?
     "allowed" : "denied";
// verweigert

echo $acl->isAllowed('marketing', 'latest', 'publish') ?
     "allowed" : "denied";
// erlaubt

echo $acl->isAllowed('marketing', 'latest', 'archive') ?
     "allowed" : "denied";
// erlaubt

echo $acl->isAllowed('marketing', 'latest', 'revise') ?
     "allowed" : "denied";
// verweigert

echo $acl->isAllowed('editor', 'announcement', 'archive') ?
     "allowed" : "denied";
// verweigert

echo $acl->isAllowed('administrator', 'announcement', 'archive') ?
     "allowed" : "denied";
// verweigert
]]></programlisting>
    </sect2>

    <sect2 id="zend.acl.refining.removing">
        <title>Zugangsbeschränkungen entfernen</title>

        <para>
            Um eine oder mehrere Zugangsregel von der <acronym>ACL</acronym> zu entfernen,
            verwendet man einfach die vorhandenen Methoden <methodname>removeAllow()</methodname>
            oder <methodname>removeDeny()</methodname>. Wie bei
            <methodname>allow()</methodname> und <methodname>deny()</methodname> kann man den
            <constant>NULL</constant> Wert übergeben, um die Anwendung auf alle Rollen, Ressourcen
            und / oder Rechte anzuzeigen:
        </para>

        <programlisting language="php"><![CDATA[
// Entferne die Verweigerung, die letzten Nachrichten zu überarbeiten für
// die Mitarbeiter (und Marketing durch die Vererbung)
$acl->removeDeny('staff', 'latest', 'revise');

echo $acl->isAllowed('marketing', 'latest', 'revise') ?
     "allowed" : "denied";
// erlaubt

// Entferne die Erlaubnis für das Marketing, Newsletter veröffentlichen und
// archivieren zu können
$acl->removeAllow('marketing',
                  'newsletter',
                  array('publish', 'archive'));

echo $acl->isAllowed('marketing', 'newsletter', 'publish') ?
     "allowed" : "denied";
// verweigert

echo $acl->isAllowed('marketing', 'newsletter', 'archive') ?
     "allowed" : "denied";
// verweigert
]]></programlisting>

        <para>
            Rechte können schrittweise wie oben angezeigt verändert werden, aber ein
            <constant>NULL</constant>-Wert für die Rechte überschreibt solche schrittweisen
            Änderungen:
        </para>

        <programlisting language="php"><![CDATA[
// Erlaube dem Marketing alle Rechte für die neuesten Nachrichten
$acl->allow('marketing', 'latest');

echo $acl->isAllowed('marketing', 'latest', 'publish') ?
     "allowed" : "denied";
// erlaubt

echo $acl->isAllowed('marketing', 'latest', 'archive') ?
     "allowed" : "denied";
// erlaubt

echo $acl->isAllowed('marketing', 'latest', 'anything') ?
     "allowed" : "denied";
// erlaubt
]]></programlisting>
    </sect2>
</sect1>
