Hallo Andreas,
Wenn es Dir auf Performance ankommt - IMHO kann PEAR::DB ne ganz schöne Bremse darstellen.
Du könntest Recht haben. Das Problem ist, das Ding ist auch ohne die Abstraktionsfähigkeiten ganz nett...
Aber was mache ich mit der Oberfläche? Vielleicht eine extra-Tabelle dafür?
Also ich habe das bei mir so gelöst: (ich vereinfache hier ziemlich stark, um möglichst nahe an das ranzukommen, was Du willst) Ich habe eine Tabelle global_acl, die sieht so aus:
CREATE TABLE global_acl (
id_type INT(1) UNSIGNED NOT NULL,
id INT(6) UNSIGNED NOT NULL,
right_name VARCHAR(255) NOT NULL,
PRIMARY KEY (id_type, id, right_name)
);
id_type ist entweder 1 für Gruppe oder 0 für Benutzer. ID ist dann die entsprechende Benutzer/Gruppen-ID. Bei Dir bräuchtest Du nur ein Feld: userlevel. right_name ist dann der Name des Rechts.
Ich habe dann zum einen folgende Backend-Funktionen:
has_right ($right_name)
=> hat der aktuelle Benutzer das Recht (geprüft über JOIN mit der Benutzer/Gruppen-Tabelle)
list_rights ()
=> listet alle Rechte in der Form:
array (
0 => array (
'id_type' => 1,
'id' => 1,
'rights' => array (
'rechta',
'rechtb',
'rechtc'
)
),
1 => array (
'id_type' => 1,
'id' => 2,
'rights' => array (
'rechta',
'rechtc',
'rechtd',
'rechte',
'rechtf'
)
)
);
Das ist praktisch für die Anzeigefunktionien (s.u.) Den Teilsourcecode, um so eine Baumdarstellung zu bekommen, hänge ich ans Ende des Postings.
has_rights ()
=> Listet alle Recht des aktuellen Benutzers auf und gibt sie als normales Array zurück: array ('rechta', 'rechtb', 'rechtc') => über JOIN mit der Benutzer/Gruppendatenbank
set_right ($id_type, $id, $right_name)
=> setzt ein Recht
unset_right ($id_type, $id, $right_name)
=> löscht ein Recht
Dann habe ich noch vier weitere Funktionen zur Verwaltung:
display_acl_form ($addurl, $changeurl, $rights_array)
=> zeigt das Rechte-Formular an:
+-----------+----------+------------+------------+-----------+---------+
| | Recht A | Recht B | Recht C | Recht D | Recht E |
+-----------+----------+------------+------------+-----------+---------+
| Gruppe 1 | [ ] | [ ] | [ ] | [X] | [X] |
| Gruppe 2 | [X] | [ ] | [X] | [ ] | [X] |
| Benutzer1 | [ ] | [X] | [ ] | [ ] | [ ] |
+-----------+----------+------------+------------+-----------+---------+
- $addurl ist die URL des Scripts, das display_acl_add_form aufrufen wird. (su.)
- $changeurl ist die URL des Scripts, das bei einem POST-Request process_acl_form aufrufen wird (su.)
- $rights_array sind alle _verfügbaren_ Rechte (array ('rechta', 'rechtb', 'rechtc'))
process_acl_form ($rights_array)
=> Verarbeitet das Rechte-Formular
display_acl_add_form ($addurl, $backurl, $rights_array)
=> Zeit ein Rechte-Hinzufüge-Formular an:
+------------+--------------------------------+
| Typ | [Gruppe_________] |
+------------+--------------------------------+
| Gruppe | [Gruppe 1_______] |
+------------+--------------------------------+
| Benutzer | [Benutzer1______] |
+------------+--------------------------------+
| Rechte | [ ] Recht A |
| | [ ] Recht B |
| | [ ] Recht C |
| | [ ] Recht D |
| | [ ] Recht E |
| | [ ] Recht F |
| | [ ] Recht G |
+------------+--------------------------------+
- $addurl ist die URL des Scripts, das bei einem POST-Request process_acl_add_form aufrufen wird (su.)
- $backurl ist die URL des Scripts, das wieder display_acl_form aufrufen wird
- $rights_array sind wieder alle Rechte
process_acl_add_form ($rights_array)
=> verarbeitet das Hinzufügen-Formular
Bei den Formularen sind jeweils immer noch Links zum Springen zum anderen Formular gegeben, daher die einen URL-Parameter, die anderen URL-Parameter sind für den Wert des action-Attributs des Formulars zuständig.
Wie oben erwähnt kommt hier noch ein Teilsourcecodeauszug aus list_rights; diese Struktur ist enorm hilfreich, wenn man dieses Tabellenformular anzeigen will: Man geht erst alle Zeilen durch; geht dann die Liste mit allen Rechten durch und prüft einfach mit in_array, ob das Recht auch für diese Zeile vorhanden ist.
Beachte, dass die Sortierung in der Datenbank richtig abgestimmt sein muss, sonst funktioniert es nicht.
$rows = array ();
$cur_row = null;
$cur_rights = null;
while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
// if its the first time
if ($cur_row === null) {
$cur_row = array ('id' => $row['id'], 'id_type' => $row['id_type']);
$cur_rights = array ($row['right_name']);
// else if it has changed
} else if ($cur_row['id'] != $row['id'] || $cur_row['id_type'] != $row['id_type']) {
$cur_row['rights'] = $cur_rights;
$rows[] = $cur_row;
$cur_row = array ('id' => $row['id'], 'id_type' => $row['id_type']);
$cur_rights = array ($row['right_name']);
} else {
$cur_rights[] = $row['right_name'];
}
}
$cur_row['rights'] = $cur_rights;
$rows[] = $cur_row;
Ich hoffe, das hat Dir ein bisschen einen Denkansatz gegeben. :-)
Ach ja: Eventuell erscheinen einige Funktionen oder Parameter überflüssig - das liegt an der Vereinfachung. Das ganze ist nämlich bei mir noch etwas komplexer.
Viele Grüße,
Christian
Hast Du einen Beitrag? Nur her damit!
http://aktuell.de.selfhtml.org/tippstricks/beitrag.htm
SELF-Code: (http://emmanuel.dammerer.at/selfcode.html)
sh:) fo:) ch:] rl:( br:> n4:& ie:% mo:) va:) de:] zu:) fl:( js:| ss:) ls:[