Für dynamische Anwendungen ist es unumgänglich spezielle Bereiche nur bestimmten Usern zugänglich zumachen. Hierfür muss ein User identifiziert und ggf. auch einer bestimmten Rolle zugewiesen werden. Drupal bietet einen komfortablen Registrierungs- und Loginprozess. Um mit diesen Daten zu arbeiten dient das User-Objekt. Auf den nächsten Seiten soll eine, in PHP, geschriebene Anwendung in Drupal imlementiert werden. Bei der Anwendung handelt es sich um ein Anwesenheitsmanagementsystem (Arbeitszeiterfassung). Hierfür wurden zwei zusätzliche Rollen angelegt: - Mitarbeiter - Leiter Verwaltung Der Mitarbeiter soll Zugriff auf seine eigenen Daten haben und einen Gruppenkalender einsehen können. Der Leiter Verwaltung hat die gleichen Rechte und kann zusätzlich auf die Mitarbeiterdaten zugreifen, Mitarbeiter anlegen und bearbeiten, Genehmigungen erteilen, usw... . Die Anwendung verfügt über eine eigene Datenbank und ein eigenes CSS-Design.
Was steht nun in dem User-Objekt? Dazu lesen wir das Userobjekt erst einmal aus. Dazu verwenden wir erst einmal eine eigene Funktion, besser ist das Debugger-Modul zu verwenden, dazu aber später.
/**
* Startseite des AWS
*/
function aws_start()
{
// Holen des User-Objektes
global $user;
$uebergabe = 'Start AWS';
$uebergabe .= '';
$uebergabe .= array_auslesen($user);
return $uebergabe;
} // END aws_start
/**
* Einfache Funktion zum Auslesen von Arrays
*/
function array_auslesen($array)
{
// Das Array auslesen
foreach($array as $key => $wert)
{
if(!is_array($wert))
$uebergabe .= $key.' - '.$wert.'
';
else
{
$uebergabe .= $key.' (
';
$uebergabe .= array_auslesen($wert);
$uebergabe .= ')
';
}
}
return $uebergabe;
} // END array_auslesen
Ausgabe:
uid - 3
name - Mitarbeiter1
pass - cfe09803c312143de6ef0fe9dc436bc9
mail - mitarbeiter1@xxx.de
mode - 0
sort - 0
threshold - 0
theme -
signature -
created - 1208330988
access - 1208340810
login - 1208339914
status - 1
timezone -
language -
picture -
init -
mitarbeiter1@xxx.de
data - a:0:{}
sid - 8797c3216b5f0032fa1a38bda510e5f6
hostname - 127.0.0.1
timestamp - 1208340810
cache - 0
session -
roles (
2 - authenticated user
3 - Mitarbeiter
)
Hier die Definition der wichtigsten Punkte:
Über die Rolle wird im folgenden das weitere Menü gesteuert.
Als erstes soll unter dem Startmenü ein Menüpunkt erscheinen, der nur aktiv ist wenn ein User eingeloggt ist. Dafür gibt es zwei Möglichkeiten:
Um einen ersten Menüpunkt zu erzeugen der nur für eingeloggte Mitarbeiter sichtbar ist, wird folgender Code verwendet:
/**
* Das Menüsystem des AWS
*/
function aws_menu()
{
// Holen des User-Objektes
global $user;
$items = array();
if(!$may_chache && ($user -> uid > 0))
{
$items[] = array
(
'path' => 'aws',
'title' =>t( 'Arbeitszeiten'),
'callback' => 'aws_helper',
'access' => true,
'type' => MENU_NORMAL_ITEM,
);
$items[] = array
(
'path' => 'aws/start',
'title' =>t( 'Arbeitszeit Start'),
'callback' => 'aws_start',
'access' => true,
'type' => MENU_NORMAL_ITEM,
);
}
return $items;
}
Anschließend wird der Menüpunkt in den Startpunkt verschoben (admin/build/menu). Solange der User nicht angemeldt ist, ist der Menüpunkt nicht sichtbar.
Erst nach der Anmeldung wird der neue Menüpunkt sichtbar. Hierzu sind zwei Dinge notwendig
global $user;).if(!$may_chache && ($user -> uid > 0))).
Es kommt häufig vor das Daten schon in einer anderen Anwendung oder in einer anderen Datenbank liegen. Hier ist es nicht gewünscht alle Daten in Dupal zu integrieren, zumeist soll die externe Anwendung oder Datenbank genutzt werden. Drupal bietet dafür mehrere Möglichkeiten:
Es gibt noch eine Reihe fertiger Module mit denen die Authentifizierrung erledigt werden kann, z. B. das LDAP Integration um direkt auf eine Datenbank zuzugreifen. Generell schaut Drupal nur in der eigenen Datenbanktabelle {users} nach ob dort der User existiert, der sich grade versucht einzuloggen. Wenn dieser existiert wird das Passwort geprüft und geprüft ob der User aktiviert ist. Sind diese Prüfungen erfolgreich, werden die Userdaten geladen und im User-Objekt gespeichert. Damit sind dann auch die Berechtigungen global verfügbar. Es besteht jedoch auch die Möglichkeit einen eigenen Authentifizierungs-Mechanismus einzuhängen - (hook_auth()). Der Ablauf verändert sich dann ein wenig:
Das Ergebnis ist dass der User jetzt im System angemeldet ist. Solange er kein aktiviertes Konto hat, stehen Ihm aber nicht alle Möglichkeiten offen.
/**
* Implementation des Hook_auth
*/
function aws_auth($username, $password, $server = FALSE)
{
drupal_set_message('Authentifikation - user:'.$username.' - pw:'.$password.' ist zugelassen');
// Hier die Prüfung einbauen
$return = true;
return $return;
} // END aws_auth
Hier also ein "universeller" Bypass, der so natürlich nur lokal und nur zum Test verwendet werden sollte. Zumeist werden die Daten aus einer Datenbank geholt und Drupal mitgeteilt das der User Zugriff hat oder nicht. Wenn der User einen dauerhaften Zugriff auf das Drupal-System haben soll, besteht die Möglichkeit direkt einen Drupal-User anzulegen.
/**
* Implementation des Hook_auth
*/
function aws_auth($username, $password, $server = FALSE)
{
drupal_set_message('Authentifikation - user:'.$username.' - pw:'.$password.' ist zugelassen');
// Hier die Prüfung einbauen und die Daten holen
user_save('',
array
(
'name' => $username,
'pass' => $password,
'mail' => 'user@email.org',
'roles' => array
(2 => 'authenticated user', 3 => 'beliebige rolle'),
'status' => 1,
'init' => 'user@email.org',
)
);
$return = true;
return $return;
} // END aws_auth
Mit der Methode user_save können die Daten direkt an Drupal gegeben und der User dort angelegt werden. Wird der erste Parameter mit der $user -> uid angegeben, wird kein neuer Account angelegt sondern geprüft ob ein Account vorhanden ist und dieser bei Bedarf upgedatet. Der zweite Parameter sind die Daten aus dem User-Objekt die als Array zurückgegeben werden. Man sollte sich allerdings immer die Frage stellen ob das sinnvoll ist, denn für diesen User existieren ja dann zwei Datensätze an unterschiedlichen Orten die auch gepflegt werden müssen.
Die normale Profilseite eines Users in Drupal gibt nicht viel her. Man kann die Profile mit Drupal-Mitteln recht einfach erweitern und diese zusätzlichen Angaben auch ausgeben lassen. Dazu muss das Modul Profile (Dupal-Standardumfang) aktiviert werden und unter Verwalten -> Benutzerverwaltung können die Profile dann angepasst werden. Die Augabensteuerung und die Sichtbarkeiten für andere User sind alldings beschränkt. Daten aus externen Datenbanken oder Informationen die nicht im Profil sind können aber kaum ausgegeben werden.
Hierfür kann aber über den hook_user($op, &$edit, &$account, $category = NULL) direkt die Inhalte zugegriffen werden. Der Zugriff erfolgt wieder in einem eigenen Modul. Es soll in diesem Beispiel erst einmal eine Adresse eingeblendet werden, die nicht im Drupal-System gespeichert ist. Es soll weiterhin eine Prüfung erfolgen ob der User auch die Berechtigung hat die Daten zu sehen.
<?php //; $ Id: manipulation.module, UwBach, 2008/05/14 $
/**
* @file Menümanipulation der Anwendung
* Erster Versuch
*/
/**
* Funktion um Usereinstellungen zu maipulieren
* Hier wird der gespeicherte Benutzername durch den richtigen Namen ersetzt, soweit er erfasst ist
*/
function manipulation_user($op, &$edit, &$user, $category = NULL)
{
// Wenn der User ein Profil aufruft
if($op == 'view')
{
// Der nachgefragte User
$requested_user = $user;
// Falls der User keine Berechtigung hat
if(!$user -> uid)
// Prüfung für Zugangsberechtigung einfügen oder weglassen
return ;
else
{
// hole irgendwelche Fremddaten
$externe_daten = array
(
'strasse' => 'Musterstrasse',
'hausnummer' => '12a',
'plz' => '12345',
'ort' => 'Testhausen'
);
}
// Der angemeldete User
global $user;
// DEFAULT-Werte für die Sichtbarkeit der Angaben
$sichtbarkeit_adresse = FALSE;
// Falls der User seine eigenen Daten nachfragt - alles freigeben if($requested_user -> uid == $user -> uid)
{
$sichtbarkeit_adresse = TRUE;
} // Falls ein fremder Account nachgefragt wird - prüfen was freigegeben werden kann
else
{
// eigene Prüfung einfügen
} // Prüfen Ob die Adresse ausgeben werden soll
if($sichtbarkeit_adresse)
{
$items[] = array
(
'title' => t('Strasse'),
'value' => $externe_daten['strasse'],
'class' => 'adresse',
);
$items[] = array
(
'title' => t('Hausnummer'),
'value' => $externe_daten['hausnummer'],
'class' => 'adresse',
);
$items[] = array
(
'title' => t('Postleitzahl'),
'value' => $externe_daten['plz'],
'class' => 'adresse',
);
$items[] = array
(
'title' => t('Ort'),
'value' => $externe_daten['ort'],
'class' => 'adresse',
);
return array
(
t('Adresse') => $items);
} // END if($sichtbarkeit_adresse)
} // END if($op == 'view')
} // END manipulation_user()
Die Ausgabe hat sich jetzt verändert:
Im Modul User Funktion user_user($type, &$edit, &$user, $category = NULL) wird die Default-Ausgabe generiert und kann ggf. überschrieben werden. Die Umsetzung des Arrays erfolgt in der Funktion function theme_user_profile($account, $fields) ebenfalls in dem Modul User. Interessant ist noch die Angabe 'class' mit der CSS-Klassen erzeugt werden. Der Quelltext sieht dann so aus:
<div class="profile"> Damit kann durch die Einbindung einer einfachen CSS-Datei das eigene Design schnell umgesetzt werden (siehe Kapitel "CSS einbinden").
<h2 class="title">Verlauf</h2>
<dl>
<dt class="user-member">Mitglied seit</dt>
<dd class="user-member">1 Woche 35 Minuten</dd>
</dl>
<h2 class="title">Adresse</h2>
<dl>
<dt class="manipulation-adresse">Strasse</dt>
<dd class="manipulation-adresse">Musterstrasse</dd>
<dt class="manipulation-adresse">Hausnummer</dt>
<dd class="manipulation-adresse">12a</dd>
<dt class="manipulation-adresse">Postleitzahl</dt>
<dd class="manipulation-adresse">12345</dd>
<dt class="manipulation-adresse">Ort</dt>
<dd class="manipulation-adresse">Testhausen</dd>
</dl>
</div>