Mal ganz anders - Zugriffsrechte nur für Nodeautor und Autor eines referenzierten Nodes
Auf dieser Seite geht es darum, dem Autor eines referenzierten Nodes Leserechte zu gewähren
Es gibt auch etwas speziellere Fälle für Zugriffsbeschränkungen.
So kann es manchmal auch vorkommen, dass User nur ihre eigenen Beiträge eines Inhaltstyps sehen dürfen und zusätzlich noch der Autor eines referenzierten Nodes den Node lesen darf.
Also, als Beispiel: User A erstellt Node A und referenziert darin Node B. Nun können nur User A und User B (Autor von Node B) den Inhalt sehen.
Auch das lässt sich machen und zwar so:
Die Module
ACL benötigen wir, um die Berechtigungen mit Content Access auf User-Basis zu speichern. Rules setzt die Berechtigungen. Für die Node Reference benötigt man natürlich noch CCK, aber ich habe nur die Module aufgelistet, welche sich mit den Zugriffsrechten befassen.
Zum Zeitpunkt des Verfassens dieser Buchseiten werden folgende Versionen benutzt:
Drupal --> 6.17 (deutsche Version von DC)
Content Access --> 6.x-1.2
Rules --> 6.x-1.2
Vorbereitung und Installation
Zu diesem Punkt muss man eigentlich nichts mehr sagen, aber der Vollständigkeit wegen:
--> Module herunterladen, entpacken, nach sites/all/modules hochladen und aktivieren
Einstellungen von Content Access
Näheres dazu, wie und wo man die Einstellungen von Content Access ändert, findet man unter dem Punkt "Einstieg - Grundlegende rollenbasierte Zugriffe".
Die Rechte setzen wir für die entsprechenden Rollen so, dass sie nur eigene Inhalte sehen (und evtl. bearbeiten / löschen) dürfen.
Wenn dann also User A einen Node dieses Typs erstellt, kann auch nur User A den Node sehen.
Außerdem müssen wir bei den Einstellungen von Content Access unten einen Haken bei "Erlaube Zugriffskontrolle für einzelne Nodes" setzen, damit wir die Rechte später für die einzelnen Nodes automatisch anpassen lassen können.
Das war es zu den Einstellungen von Content Access, nun kommt Rules ins Spiel und hier könnte es ein wenig kompliziert werden. Wir müssen zwei Fälle unterscheiden:
- Es kann pro Node nur ein anderer Node referenziert werden
- Es können pro Node mehrere andere Nodes referenziert werden
Diese zwei Fälle zu unterscheiden ist wichtig. Man sollte sich vorher darüber im Klaren sein, wie Nodes referenziert werden können. Wenn man immer nur einen Node referenzieren kann (z.B. weil das Node-Reference-Feld nur einen Wert zulässt), sollte man die erste Variante nehmen, da diese einfacher ist. Sie funktioniert aber ausschließlich für eine einzelne Node-Referenz! Sobald die Möglichkeit besteht, dass man in einem Node mit einem Node-Reference-Feld mehrere andere Nodes referenzieren kann, muss man die zweite Variante verwenden. Diese funktioniert für eine beliebige Anzahl von Nodereferenzen, ist aber etwas komplizierter umzusetzen.
Erste Variante
Diese Variante funktioniert wie gesagt nur für Nodes mit einer einzelnen Node-Reference.
Dazu ruft man admin/rules/trigger auf und klickt auf "Neue Regel hinzufügen". Als Ereignis wählen wir "Nach dem Speichern von neuem Inhalt". Wie man die Regel benennt, bleibt einem selbst überlassen.
Auf der nächsten Seite kann man die Regel an bestimmte Bedingungen knüpfen, zum Beispiel, dass sie nur für bestimmte Inhaltstypen gilt. Ich stelle hier einfach mal als Bedingung, dass der Inhaltstyp des neuen Nodes "Test-Typ" lauten muss.
Nun kommen drei Aktionen in dieser Reihenfolge:
(vor dem Titel der Aktion steht hier immer der Gliederungspunkt, zu dem die Aktion gehört).
- CCK - Referenzierten Beitrag laden
- User - Benutzerkonto laden
- Content Access - Gewähre Zugriffsrechte für einen Nutzer
Also, zuerst müssen wir den referenzierten Node laden, dazu nehmen wir die Aktion "Referenzierten Beitrag laden" und gehen zur nächsten Seite.
Unter "Der Inhalt der das Beitragsreferenzfeld enthält:" sollte "Inhalt erstellt" stehen, darunter wählt man das entsprechende Node-Reference-Feld aus. Ganz unten kann man die Bezeichnung und den Namen des geladenen Objekts bearbeiten. Standardmäßig steht hier als Bezeichnung "referenzierter Inhalt" und als Name "referenced_node". Diese Werte kann man lassen, wie sie sind. Aber man kann sie auch umbenennen, ganz, wie es einem beliebt.
Als Reihenfolge nehmen wir für diese Aktion -10
Nun müssen wir den Autor dieses Nodes laden, also erstellen wir eine neue Aktion "Benutzerkonto laden" und gehen weiter zur nächsten Seite.
Nun können wir den User anhand des Namens oder der ID laden. Wir haben im Node-Objekt nur die User-ID gegeben, also laden wir den User anhand dieser ID. Die ID (bzw. die Variable, aus der sich Drupal dann die ID holt), kommt also in das Feld bei "Benutzer-ID: "
Nun gibt es zwei Möglichkeiten:
- sollten wir das Modul Token installiert haben (was meistens eine gute Idee ist, wenn man Rules verwenden will), dann trägt man in das Feld einfach "[referenced_node:author-uid]" ein (ohne die Anführungszeichen)
- sollte das Token-Modul nicht installiert sein und auch nicht installiert werden, kann man das Feld auch einfach durch PHP-Code füllen. Dazu trägt man in das Feld folgendes ein: (inkl. der PHP-Begrenzer; für PHP-Verwendung muss evtl. das Core-Modul PHP-Filter aktiviert sein)
<?php
echo $referenced_node->uid;
?>
(diese Variablen-Bezeichnungen ändern sich natürlich, wenn man zuvor beim Laden des Refernz-Nodes den Namen geändert hat)
Auch hier kann man die Bezeichnung des geladenen Objekts ändern, ich bleibe wieder beim Standard "geladener Benutzer" und "user_loaded".
Diese Aktion bekommt als Reihenfolge -9
Nachdem der Autor des Nodes geladen ist, müssen wir ihm nur noch die gewünschten Rechte geben. Dazu erstellen wir eine Aktion "Gewähre Zugriffsrechte für einen Nutzer".
Auf der nächsten Seite müssen wir die "Argument-Konfiguration" anpassen.
Bei "Inhalt" sollte der neu erstellte Inhalt angegeben werden, bei "Benutzer" der gerade geladene User. Also müssen dort "Inhalt erstellt" und "Geladener Benutzer" stehen. Jetzt gibt man darunter noch die gewünschten Rechte an ("view", "edit" und "delete") und ist fertig.
Diese Aktion bekommt als Reihenfolge -8
Damit wäre Variante 1 abgeschlossen.
Variante 2
Diese Variante funktioniert für eine beliebige Anzahl von Node-Referenzen.
Dafür gehen wir nach rules/rule_sets und klicken auf "Neues Regel-Set hinzufügen". Auf der nächsten Seite können und müssen wir ein paar Anpassungen vornehmen.
"Bezeichnung" und "Maschinenlesbarer Name:" sind euch überlassen. Beachtet, dass dem Namen immer ein "rules" vorangestellt wird. Wenn ihr bei "Maschinenlesbarer Name:" also "reference_autor_acces" eintragt, heißt das Regelset dann "rules_reference_autor_acces".
Nun müsst ihr unten folgende zwei Argumente erstellen
(Datentyp - Bezeichnung - Name)
Benutzer - Referenz-Autor - reference_autor
Inhalt - Neuer Inhalt - node_added
(Bezeichnung und Name kann man wie immer frei wählen).
Nun speichern wir und gehen zur Konfigurationsseite des Regelsets (nach dem Speichern kommt man zur Übersicht der Rulesets, dort einfach auf den Namen des Regelsets klicken) und klicken dort (auf der Konfigurationsseite des Regelsets) auf "Neue Regel hinzufügen".
Diese Regel kann eine beliebige Bezeichnung erhalten. Wichtig ist, dass bei "Regel-Set:" das gewünschte Regelset ausgewählt ist.
Auf der nächsten Seite kann man der Regel wie immer Bedingungen hinzufügen. Allerdings benötigen wir an dieser Stelle nicht zwingend Bedingungen. Wem welche für seinen Anwendungsfall einfallen, der kann sie natürlich einfügen.
Als Aktion nehmen wir nun "Gewähre Zugriffsrechte für einen Nutzer". Auf der nächsten Seite muss man eigentlich nur die zu gewährenden Rechte anpassen, unter "Argument-Konfiguration" dürften "Neuer Inhalt" und "Referenz-Autor" stehen, da nur diese beiden Argumente angegeben wurden.
Also passen wir die Rechte an (ich gewähre nur View-Rechte) und speichern das ganze. Damit ist das Regelset fertig.
Nun gehen wir zu admin/rules/trigger und klicken auf "Neue Regel hinzufügen". Dieser kann man wieder mal eine beliebige Bezeichnung geben, als Ereignis nehmen wir wieder "Nach dem Speichern von neuem Inhalt".
Auf der nächsten Seite können wir z.B. als Bedingung stellen, dass die Regel nur ausgeführt wird, wenn der neue Inhalt einen bestimmten Typ hat.
Als Aktion wählen wir "Benutzerdefinierten PHP-Code ausführen" bzw "Custom PHP" aus (dafür muss evtl. das Core-Modul PHP-Filter aktiviert werden).
Auf der nächsten Seite haben wir ein Fenster "PHP-Code:", dort tragen wir folgenden Code (allerdings ohne die PHP-Begrenzer) ein:
<?php
//Durchläuft die Node-Referenzen und ruft für jede Node-Referenz das zuvor erstellte Ruleset auf
foreach ($node->field_nodereference_feld as $r) {
$id = $r['nid'];
$n = node_load($id);
$u = user_load($n->uid);
//ruft das Regelset auf und gibt ihm die nötigen Objekte als Argumente
rules_invoke_rule_set('rules_reference_autor_acces', array('reference_autor' => $u, 'node_added' => $node));
}
?>
Das ganze speichert man und ist fertig.
Man könnte aus Performancegründen die Zeile "$n = node_load($id);" durch ein db_result ersetzen, mit dem man gezielt die User-ID des gewünschten Nodes abfragt, das könnte dann so aussehen:
<?php
//Durchläuft die Node-Referenzen und ruft für jede Node-Referenz das zuvor erstellte Ruleset auf
foreach ($node->field_nodereference_feld as $r) {
$id = $r['nid'];
$sql = "SELECT n.uid FROM {node} n WHERE n.nid = %d;";
$uid = db_result(db_query($sql, $id));
$u = user_load($id);
//ruft das Regelset auf und gibt ihm die nötigen Objekte als Argumente
rules_invoke_rule_set('rules_reference_autor_acces', array('reference_autor' => $u, 'node_added' => $node));
}
?>
Das lohnt sich evtl. wenn abzusehen ist, dass man es mit vielen Node-Referenzen in einem Node zu tun bekommt, dann muss man nicht immer das ganze Node-Objekt laden, wenn man nur die User-ID benötigt. Aber der Vollständigkeit wegen gibt es hier beide Varianten.
Damit ist diese Variante fertig.
Wenn man nun einen Node erstellt und darin einen anderen Node referenziert, bekommt der Autor des Referenz-Nodes automatisch die entsprechenden Rechte zugewiesen.
Neue Kommentare
vor 2 Tagen 20 Stunden
vor 2 Tagen 22 Stunden
vor 2 Tagen 22 Stunden
vor 2 Tagen 22 Stunden
vor 3 Tagen 20 Stunden
vor 3 Tagen 22 Stunden
vor 4 Tagen 18 Stunden
vor 5 Tagen 12 Stunden
vor 5 Tagen 12 Stunden
vor 5 Tagen 16 Stunden