Benutzerverwaltung integrieren

Hier dreht sich alles um die auf der Webseite veröffentlichten Tutorials. // This forum is all about the APF tutorials.
Avedo

Benutzerverwaltung integrieren

Beitrag von Avedo » 18.03.2010, 16:10:26

Hallo!

Ich habe mir vor kurzem das Beispiel-Paket heruntergeladen, das Design meinen Vorstellungen angepasst, einige TagLibs hinzugefügt und das Kontakt-Formular integriert. Nun möchte ich die Website um eine Benutzerverwaltung bzw. einen Backendbereich erweitern. Dazu habe ich mir bereits die entsprechenden Tutorials (umgtManager, O/R-Mapper, etc.) durchgelsen, komme aber nicht weiter.

Es soll auf der Website in einer Sidebar ein Login-Formular angezeigt werden, falls der Benutzer noch nicht eingeloggt ist. Ist der Benutzer eingeloggt soll stattdessen die Backend-Startseite sowie eine Admin-Navigation (abhängig von der Art des Benutzers) angezeigt werden. Frage ist, wie ich das in mein aktuelles Design intergiere und wie die entsprechenden Module und taglibs aussehen müssen. Unklar ist mir auch, wie und wo ich das Login verarbeiten und die entsprechende Session setzen muss. Besonders interessieren würde mich auch, wie ein Formular und das entsprechende Modul zur Registrierung aussehen könnten. Skizzen reichen natürlich.

Liebe Grüsse,

Andreas

Benutzeravatar
dr.e.
Administrator
Beiträge: 4555
Registriert: 04.11.2007, 16:13:53

Re: Benutzerverwaltung integrieren

Beitrag von dr.e. » 18.03.2010, 18:54:00

Hallo Andreas,
Es soll auf der Website in einer Sidebar ein Login-Formular angezeigt werden, falls der Benutzer noch nicht eingeloggt ist. Ist der Benutzer eingeloggt soll stattdessen die Backend-Startseite sowie eine Admin-Navigation (abhängig von der Art des Benutzers) angezeigt werden.
Soweit ist die Anforderung klar.
Frage ist, wie ich das in mein aktuelles Design intergiere und wie die entsprechenden Module und taglibs aussehen müssen.
Die einfachste Form ist, für den Bereich deiner Sidebar einen Document-Controller zu erstellen, der an Hand des aktuellen Status entweder das Login-Formular oder das Menü anzeigt. Hier würde ich beim Login-Versuch im Controller einfach den umgtManager nutzen und bei erfolgreicher Authentifizierung den Benutzer in die Session schreiben:

Code: Alles auswählen

// ...auszuführen, wenn das Formular abgesendet wurde...
$user = $umgt->loadUserByUsernameAndPassword(...,...);
if($user == null){
   // Formular anzeigen
} else {
   $sm = new SesssionManager('namespace::of::the::login::module');
   $sm->saveSessionData('user',$user);
}
Unklar ist mir auch, wie und wo ich das Login verarbeiten und die entsprechende Session setzen muss. Besonders interessieren würde mich auch, wie ein Formular und das entsprechende Modul zur Registrierung aussehen könnten. Skizzen reichen natürlich.
Der umgtManager bietet dir mehrere Möglichkeiten einen Benutzer zu Authentifizieren (siehe http://adventure-php-framework.org/Seit ... mgtManager). Das bedeutet, dass du auch dein Formular so aufbauen kannst, dass du entweder E-Mail und Passwort oder Benutzer-Name und Passwort verlangst.
Anschließend kannst du nach dem Absenden die Daten aus dem Request beziehen und den Benutzer authentifizieren:

Code: Alles auswählen

$form = &$this->__getForm('login_form') ;
if($form->isSent()){
   $user = &$form->getFormElementByName('username');
   $pass = &$form->getFormElementByName('password');
   
   $user = $umgt->loadUserByUsernameAndPassword($user->getAttribute('value'),$pass->getAttribute('value'));

   if($user == null){
      $form->transformOnPlace(); // Fehlerfall!
   } else {
      $menu = &$this->__getTemplate('menu');
      $menu->transformOnPlace();
   }

} else {
   $form->transformOnPlace();
}
Ich hoffe, die Idee ist damit etwas klarer. Wenn du weitere Code-Snippets brauchst, sag Bescheid.
Viele Grüße,
Christian

Benutzeravatar
dr.e.
Administrator
Beiträge: 4555
Registriert: 04.11.2007, 16:13:53

Re: Benutzerverwaltung integrieren

Beitrag von dr.e. » 18.03.2010, 19:02:47

Hallo nochmal,

ich hatte oben vergessen zu beschreiben, wie eine Registrierung aussehen kann. Dies kannst du dir im Prinzip im UMGT-Modul abschauen. Hier gibt es eine Maske zur Erstellung eines neuen Benutzers. Konkret werden da einfach die relevanten Felder aufgeführt, ein Benutzer-Objekt erzeugt und per saveUser() gespeichert. Den Code dazu findest du in der Datei add_controller.php.

Solltest du dazu Fragen haben, dann gerne jederzeit, aber du wolltest erst mal Skizzen haben.
Viele Grüße,
Christian

Avedo

Re: Benutzerverwaltung integrieren

Beitrag von Avedo » 19.03.2010, 16:24:32

Hallo!

Ich habe mich heute morgen mal mit der Implementierung des Login-Formulars auseinander gesetzt. Ich habe dazu das usermanagement Modul um ein Template login.html, einen DocumentController login_controller.html und einige Stylesheet- und Konfigurations-Dateien erweitert. Die wichtigen Quellcodes findet ihr im Anhang. Das Formular wird nun mittels

Code: Alles auswählen

<core:importdesign namespace="modules::usermanagement::pres::templates" template="login" />
in mein Layout eingefügt. Das klappt auch soweit. Das Formular wird angezeigt und Fehlermeldungen bei falscher Eingabe ausgegeben. Wird das Formular jedoch zumindest Formal richtig ausgefüllt und abgesendet, tritt noch der folgende Fehler auf.
Fatal error: Call to a member function isValid() on a non-object in /home/www/web193/html/projects/apps/tools/form/taglib/html_taglib_form.php on line 197
Ich habe leider keinerlei Ahnung woran das liegt. Wäre nett, wenn mir da jemand helfen könnte.

Außerdem würde mich interessieren, ob die Umsetzung, so wie ich sie vorgenommen habe, ok ist und ob das Formular wirklich nur solange angezeigt wird, wie der Benutzer noch nicht eingeloggt ist.

EDIT: Gibt es eigentlich einen Satz an Basiseinträgen, die für die grundlegenden Operationen im Usermanagement angelegt werden müssen und wie prüfe ich, ob ein Benutzer die richtigen Berechtigungen (lesen, schreiben im Forum) besitzt? Außerdem sind mir die Begrifflichkeiten Rollen und Gruppen noch nicht ganz klar.

Liebe Grüße,

Andreas

login.html

Code: Alles auswählen

<@controller 
	namespace="modules::usermanagement::pres::documentcontroller" 
	file="login_controller" 
	class="login_controller" @>
	
<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
<core:addtaglib namespace="tools::html::taglib" prefix="html" class="getstring" />

<div class="login-form">
   <html:form name="login" method="post">
      <div>
         <form:error id="toperror">
            <div class="error-container">
         </form:error>
         <form:listener control="email" id="addr-error">
            <listener:placeholder name="content" /><br />
         </form:listener>
         <form:listener control="password" id="pass-error">
            <listener:placeholder name="content" /><br />
         </form:listener>
         <form:error id="bottomerror">
            </div>
         </form:error>
         <form:addvalidator
            class="TextLengthValidator"
            button="send"
            control="email|password"
         />
         <form:addvalidator
            class="EMailValidator"
            button="send"
            control="email"
         />
         <form:addfilter
            class="EMailFilter"
            button="send"
            control="email"
         />
         <label for="login-form-email">
            <form:getstring namespace="modules::usermanagement" config="language" entry="form.email" />
         </label>
         <form:text id="login-form-email" name="email" />
         <label for="login-form-pass">
            <form:getstring namespace="modules::usermanagement" config="language" entry="form.pass" />
         </label>
         <form:password id="login-form-pass" name="password" />
         <div class="fullsizebox buttonbox">
            <form:button name="send" class="button"/>
         </div>
      </div>
   </html:form>
</div>
login_controller.php

Code: Alles auswählen

<?php

	import('tools::link','FrontcontrollerLinkHandler');
	import('modules::usermanagement::biz','umgtManager');

	/**
	 * @package modules::usermanagement::pres::documentcontroller
	 * @class login_controller
	 *
	 * Document controller for the login view of the usermanagement module.
	 * If a user is just a guest it will show the loginform and if a user is logged
	 * in it will show a administration menu in the left sidebar.
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 19.03.2010<br />
	 */
	class login_controller extends baseController {

		public function login_controller(){
		}

		/**
		 * @public
		 *
		 * Displays the form or the administration menu 
		 * and handles the user input.
		 *
		 * @author Andreas Wilhelm
		 * @version
		 * Version 0.1, 19.03.2010<br />
		 */
		function transformContent() {
			// Load the login form, ...
			$form = &$this->__getForm('login') ;

			// ... generate a generic action url, ...
			$action = FrontcontrollerLinkHandler::generateLink($_SERVER['REQUEST_URI'],$_REQUEST);
			
			// ... assign it to the form tag ...
			$form->setAction($action);
			
			// ... and check if it was submitted.
			if( $form->isSent() && $form->isValid() ) {
				// Get the submitted email address ...
				$user = &$form->getFormElementByName('email');
				
				// ... and the password.
				$pass = &$form->getFormElementByName('password');
				
				// Get the business object, ... 
				$umgt = &$this->__getAndInitServiceObject('modules::usermanagement::biz','umgtManager','Default'); 

				// ... load the user with this email and password ...
				$user = $umgt->loadUserByUsernameAndPassword(
					$user->getAttribute('value'),
					$pass->getAttribute('value')
				);

				// ... and check if he exists.
				if( $user == null ) {
					// User does not exists so show the login form.
					$form->transformOnPlace();
				} 
				
				else {
					// User does exist so create a new user session ...
					$sm = new SesssionManager('modules::usermanagement::pres::documentcontroller::login_controller');
					$sm->saveSessionData('user', $user);
   
   				// ... and show the administration menu
					$menu = &$this->__getTemplate('menu');
					$menu->transformOnPlace();
				}
			}
			
			// The form was not submitted.
			else {
				// Load the language configuration, ...
				$config = &$this->__getConfiguration('modules::usermanagement','language');
				
				// ... label the submit button, ...
				$button = &$form->getFormElementByName('send');

				$button->setAttribute('value',$config->getValue($this->__Language,'form.button'));

				// ... fill listeners with the language dependent values ...
				$addrError = &$form->getFormElementByID('addr-error');
				$addrError->setPlaceHolder(
					'content', 
					$config->getValue($this->__Language,'form.email.error')
				);
				
				$passError = &$form->getFormElementByID('pass-error');
				$passError->setPlaceHolder(
					'content', 
					$config->getValue($this->__Language,'form.pass.error')
				);

				// ... and dump the form.
				$form->transformOnPlace();
			}
		}
	}

?>

Benutzeravatar
dr.e.
Administrator
Beiträge: 4555
Registriert: 04.11.2007, 16:13:53

Re: Benutzerverwaltung integrieren

Beitrag von dr.e. » 19.03.2010, 19:42:14

Hallo Andreas,
Das klappt auch soweit.
Saubere Implementierung! Gefällt mir. :)
Wird das Formular jedoch zumindest Formal richtig ausgefüllt und abgesendet, tritt noch der folgende Fehler auf.
Fatal error: Call to a member function isValid() on a non-object in /home/www/web193/html/projects/apps/tools/form/taglib/html_taglib_form.php on line 197
An dieser Stelle werden alle Kinder des Formulars (=konkrete Formular-Elemente; das APF erzeugt aus den Tags einen kompletten DOM-Baum wie ein Browser auch) nach ihrem Validitäts-Status befragt. Ein Kind scheint kein Objekt des Typs coreObject (1.11) bzw. APFObject (1.12) zu sein oder einfach kein Objekt zu sein.

Ich habe dein Beispiel mal lokal mit der Version 1.11 und 1.12 nachvollzogen und es kam nicht zum Fehler. Welche Version hast du benutzt?
EDIT: Gibt es eigentlich einen Satz an Basiseinträgen, die für die grundlegenden Operationen im Usermanagement angelegt werden müssen und wie prüfe ich, ob ein Benutzer die richtigen Berechtigungen (lesen, schreiben im Forum) besitzt? Außerdem sind mir die Begrifflichkeiten Rollen und Gruppen noch nicht ganz klar.
An sich nicht. Es reicht lediglich das Tabellen-Setup durchzuführen und dann die entsprechenden Benutzer / Gruppen / Permissions / PermissionSets / Rollen anzulegen.

Rollen sind für die Zuordnung von Funktions-Berechtigungen gedacht (Welche Funktion darf der Benutzer ausführen?) und Gruppen (und natürlich auch explizit Benutzer) dienen der Zuordnung zu Objekten hinsichtlich der Sichbarkeit. Soll ein Benutzer A den Blog-Eintrag B sehen dürfen, muss eine Assoziation zwischen A und B existieren. Wenn der Benutzer A dann den Eintrag B auch noch bearbeiten können soll, muss er über die Rolle auch noch die relevante Permission haben. Mehr Informationen findest du in der Doku (siehe UML) und im Thread Benutzer- und Gruppenrechte mit dem Usermanagementmodul. Sollten noch Fragen offen bleiben, klären wir diese natürlich! :)
Viele Grüße,
Christian

Avedo

Re: Benutzerverwaltung integrieren

Beitrag von Avedo » 19.03.2010, 22:05:29

Hallo Christian!
Ein Kind scheint kein Objekt des Typs coreObject (1.11) bzw. APFObject (1.12) zu sein oder einfach kein Objekt zu sein.
Wieso wurde denn von Version 1.11 auf 1.12 der Name von coreObject zu APFObject geändert? Das macht doch ein Update des APFs auf die neuste Version deutlich schwerer.
Ich habe dein Beispiel mal lokal mit der Version 1.11 und 1.12 nachvollzogen und es kam nicht zum Fehler. Welche Version hast du benutzt?
Ich verwende die Version 1.11 und habe nun ein Update auf 1.12 vollzogen. Es funktioniert dennoch nicht.
An sich nicht. Es reicht lediglich das Tabellen-Setup durchzuführen und dann die entsprechenden Benutzer / Gruppen / Permissions / PermissionSets / Rollen anzulegen.
Welche Gruppen / Permissions / PermissionSets / Rollen muss ich denn anlegen um in die Benutzerverwaltung zu kommen.

Zu der Bedeutung von Rollen und Gruppen hätte ich noch eine Frage. Wie kann ich dynamisch neue Bereiche registrieren (mit Bereich ist hier zum Beispiel eine Arbeitsgruppe oder ein Forum gemeint) und dort verschiedene Rechte an eine Person vergeben.

Ein Beispiel
Ein Benutzer A soll in Forum B schreiben und lesen, in Forum C nur lesen und in Forum D schreiben, lesen und sogar editieren dürfen.

Wie kann ich in diesem Fall dynamisch die entsprechenden Rechte vergeben und erzeugen?

Liebe Grüße,

Andreas

Benutzeravatar
dr.e.
Administrator
Beiträge: 4555
Registriert: 04.11.2007, 16:13:53

Re: Benutzerverwaltung integrieren

Beitrag von dr.e. » 20.03.2010, 01:58:56

Hallo Andreas,
Wieso wurde denn von Version 1.11 auf 1.12 der Name von coreObject zu APFObject geändert? Das macht doch ein Update des APFs auf die neuste Version deutlich schwerer.
Der Grund ist, dass die Benennung der Klasse nicht den Coding-Conventions entsprach und im Release 1.12 ein TODO die Verbesserung der Konsistenz der API beschreibt. Siehe hierzu die Roadmap im Wiki. Es ist richtig, die Migration auf die Version 1.12 gestaltet sich etwas holprig, doch die Vorteile des Refactoring liegen auf der Hand: man sieht in der API-Dokumentation sofort, was ein Objekt "kann". Bisher war das durch generische get()- und set()-Methoden verschleiert.
Im Grunde musst du jedoch "nur" die relevanten Text-Ersetungen in deinen Klassen durchführen, die aktuelle SVN-Version hat bereits alle Umstellungen inkludiert. Siehe hierzu http://wiki.adventure-php-framework.org ... rsion_1.12 und de/viewtopic.php?f=10&t=285.
Ich verwende die Version 1.11 und habe nun ein Update auf 1.12 vollzogen. Es funktioniert dennoch nicht.
Ok, dann schlage ich vor, dass du mir den Quellcode, den du lokal geschrieben hast zusammen zippst und hier im Forum anhängst. Die Libs des APF kannst du weglassen, dann wird das ZIP kleiner. Ich versuche das dann lokal nachzuvollziehen. So sollten wir den Fehler schnell finden. Sollte dein Projekt nicht öffentlich zugänglich gemacht werden, kannst du mir den Code auch per PN schicken. Diskretion ist selbstverständlich!
Welche Gruppen / Permissions / PermissionSets / Rollen muss ich denn anlegen um in die Benutzerverwaltung zu kommen.
Keine. Du musst lediglich wie unter http://adventure-php-framework.org/Seit ... -1-Backend beschrieben das UMGT-Backend einbinden und die relevanten Objekte für deine Anwendung anlegen. NAch dem DB-Setup sind keine weiteren Schritte in der Datenbank notwendig, dass das Backend lauffähig ist.
Zu der Bedeutung von Rollen und Gruppen hätte ich noch eine Frage. Wie kann ich dynamisch neue Bereiche registrieren (mit Bereich ist hier zum Beispiel eine Arbeitsgruppe oder ein Forum gemeint) und dort verschiedene Rechte an eine Person vergeben.
Ich würde für die einzelnen Bereiche eigene Rollen definieren. In einem Forum gibt es einen Admin, einem Moderator und einen registrierten Benutzer (vereinfacht gesprochen). Diese drei Rollen legst du an - zusammen mit den Permissions, die du benötigst. Anschließend weist du die Permissions einem PermissionSet zu (z.B. darf ja jeder Einträge erstellen) und weist diese einer Rolle zu. Erstellst du nun bei der Registrierung einen neuen Benutzer, gibst du diesem zunächst die Rolle eines registrierten Benutzers. Er darf damit die relevanten Funktions-Elemente (z.B. Button für Eintrag erstellen) sehen.
Ein Beispiel
Ein Benutzer A soll in Forum B schreiben und lesen, in Forum C nur lesen und in Forum D schreiben, lesen und sogar editieren dürfen.
Wie kann ich in diesem Fall dynamisch die entsprechenden Rechte vergeben und erzeugen?
Hierzu nutzt du das oben beschriebene Backend oder nutzt den UmgtManager und schreibst den Code dafür in deiner Applikation selbst. Beides ist möglich.
Was die konkrete Implementierung angeht, würde ich grundsätzlich auf Foren Lese-Rechte vergeben, sprich diesen Fall erst garnicht einschränken. Hat dann ein Benutzer A eine Assoziation zum Forum B und D darf er mit diesen auch etwas "anstellen". Besitzt er nun auch noch die Permission zum Schreiben, wird ihm das entsprechende Control (Editieren-Button o.ä.) angeboten.

Da du eine mehrfache Rechte-Vergabe abbilden möchtest (Permissions pro Forum und jeweils getrennt für ein Forum) würde ich hier entweder ein PermissionSet pro Forum vorschlagen oder eine Beziehung zwischen Permission und Forum schaffen um die Bedeutung in der Datenbank abzubilden. Letzteres ist vermutlich die sauberste Lösung, jedoch auch etwas aufwändiger, da dich der UmgtManager out-of-the-box da nicht unterstützt. Diese Änderungen müsstest du direkt mit dem GORM in der Datenbank vornehmen. Das ist kein Hexenwerk, nur muss deine Applikation diese Logik selbst implementieren.

Ich habe schon mehrfach über die Erweiterung des Umgt um eine explizite Rechte-Verwaltung nachgedacht, nur ist das konzeptionell nicht so einfach generisch umzusetzen - ich weiß ja nicht, welche Objekte der Anwender in seiner Applikation je haben wird (z.B. ein Forum). Man müsste mit Stellvertreter-Objekten arbeiten, was nicht immer so einfach ist, weil die Applikation dann die Auflösung zwischen Objekt-ID des Stellvertreters und dem eigentlichen Objekt machen müsste. Sofern du noch eine Idee hast, wie man das für alle Anwendungs-Fälle passend umsetzen kann, können wir gerne darüber diskutieren.
Viele Grüße,
Christian

Avedo

Re: Benutzerverwaltung integrieren

Beitrag von Avedo » 20.03.2010, 11:35:57

Guten Morgen!

Vielen Dank für deine Erläuterungen. Mit diesem Problem muss ich mich nochmal etwas ausführlicher beschäftigen.

Ich bin übrigens vor längerer Zeit über dieses Diagramm gestolpert. Das wäre doch eine einfache und schöne Lösung für eine explizite Rechte-Verwaltung. Gruppen werden hier gar nicht mehr benötigt. Man weißt einem Benutzer einfach mehrerer Rollen zu, die er, abhängig von der gerade verwendeten Applikation oder dem gerade verwendeten Objekt annimmt.

Liebe Grüße,

Andreas

Benutzeravatar
dr.e.
Administrator
Beiträge: 4555
Registriert: 04.11.2007, 16:13:53

Re: Benutzerverwaltung integrieren

Beitrag von dr.e. » 20.03.2010, 22:15:49

Hallo Andreas,

danke für den Link, das ist konzeptionell sehr nahe an der Überlegung, die ich hatte. In meiner Vorstellung hättest du zusätzlich zum UML unter http://adventure-php-framework.org/Seit ... atenmodell noch ein Objekt "ApplicationObjectProxy" mit einer Beziehung (jeweils Assoziation) zu "Group" und "User". Um die speziellen Berechtigungen auf Objekte abbilden zu können, würde dann noch eine Beziehung zwischen "Role" oder der "Permission" direkt und dem "ApplicationObjectProxy" ausgeprägt sein.

In deiner Anwendung wäre IMHO die Rolle ausreichend, wenn man das noch granularer gestalten will, muss "Permission" sein. Das ist aber sicher weniger optimal für die Performance - obwohl. :roll: Sollte eigentlich passen. Ich nehme das mal für 1.13 oder 1.14 als Erweiterung auf. Reicht dir das oder hast du aktuell keine Lösung für das Problem?
Viele Grüße,
Christian

Avedo

Re: Benutzerverwaltung integrieren

Beitrag von Avedo » 22.03.2010, 15:55:27

Hallo!

Habe mir gerade nochmal das Login angesehen. Leider erhalte ich, auch jetzt nach dem SVN-Update immernoch den Fehler.

Code: Alles auswählen

Fatal error: Call to a member function isValid() on a non-object ...
An dieser Stelle werden alle Kinder des Formulars ... nach ihrem Validitäts-Status befragt. Ein Kind scheint kein Objekt des Typs coreObject (1.11) bzw. APFObject (1.12) zu sein ...
Wie kann ich das denn überprüfen. Die Objekte der einzelnen Elemente werden doch vollkommen automatisch anhand der login.html erzeugt. Darauf habe ich doch keinen Einfluss oder sehe ich da etwas falsch. Habe ich vielleicht etwas bei der Benennung falsch gemacht?

Liebe Grüße,

Andreas

Benutzeravatar
dr.e.
Administrator
Beiträge: 4555
Registriert: 04.11.2007, 16:13:53

Re: Benutzerverwaltung integrieren

Beitrag von dr.e. » 22.03.2010, 16:56:42

Hallo Andreas,

ich bin (gerade habe ich keine IDE zur Hand) etwas ratlos. Die Methode isValid() wird in einer Schleife aufgerufen, die ihre Kinder prüft. Sind keine Kinder vorhanden, sollten diese also auch nicht geprüft werden. Kannst du mir mal die Zeile und den zuhegörigen Stacktrace schicken, in der das passiert? An sich kann das nur die html_taglib_form in der Zeile 173 sein, sofern es die Kinder des Formulars selbst betrifft - also

Code: Alles auswählen

public function isValid(){
   foreach($this->__Children as $objectId => $DUMMY){
      if($this->__Children[$objectId]->isValid() === false){
         return false;
      } 
   }
   return true;
}
- oder der Aufruf der Methode isValid() in einem Document-Controller selbst. Passiert das bei

Code: Alles auswählen

$form = &$this->__getForm('...');
if($form->isValid()){
...
}
Wie kann ich das denn überprüfen. Die Objekte der einzelnen Elemente werden doch vollkommen automatisch anhand der login.html erzeugt. Darauf habe ich doch keinen Einfluss oder sehe ich da etwas falsch. Habe ich vielleicht etwas bei der Benennung falsch gemacht?
Zunächst hast du keinen Einfluss auf die Generierung der Kind-Objekte, wenn du eine Taglib nicht selbst implementiert hast. Bei eigenen Taglibs kannst du natürlich entscheiden, wie mit dem Inhalt der Tags umgegangen werden soll. Der Inhalt kann wiederum weitere Tags enthalten, die du mit Hilfe des Page-Controllers parsen kannst. Bei den Formularen sind z.B. alle <form:* />-Tags in der Taglib <html:form /> bekannt und werden daher bei der Erzeugung des DOM-Baumes auch als Kinder angelegt.
In deinem Fall definierst du das Formular im Template login.html, das bedeutet, dass das deine Möglichkeit ist, die Kinder direkt zu beeinflussen. Was die Benennung angeht, kann sicher ein Fehler unterlaufen sein, poste einfach mal die Definition des Formulars. Grundsätzlich sind jedoch die typischen Fehler abgefangen und die Taglib sagt dir schon, was du falsch gemacht hast.
Viele Grüße,
Christian

Avedo

Re: Benutzerverwaltung integrieren

Beitrag von Avedo » 22.03.2010, 18:16:05

Hallo Christian,

Leider gibt es keinen Stacktrace, de ich dir posten könnte. Er gibt einfach nur den Fehler

Code: Alles auswählen

Fatal error: Call to a member function isValid() on a non-object in /home/www/web193/html/projects/apps/tools/form/taglib/html_taglib_form.php on line 201 
aus. Das Template für das Formular sieht wie folgt aus:

Code: Alles auswählen

<@controller 
	namespace="modules::usermanagement::pres::documentcontroller" 
	file="login_controller" 
	class="login_controller" @>
	

<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />

<core:addtaglib namespace="tools::html::taglib" prefix="html" class="getstring" />


<div class="login-form">

   <html:form name="login" method="post">

      <div>

         <form:error id="toperror">

            <div class="error-container">

         </form:error>

         <form:listener control="login-form-email" id="addr-error">

            <listener:placeholder name="content" /><br />

         </form:listener>

         <form:listener control="login-form-password" id="pass-error">

            <listener:placeholder name="content" /><br />

         </form:listener>

         <form:error id="bottomerror">

            </div>

         </form:error>

         <form:addvalidator

            class="TextLengthValidator"

            button="login-form-send"

            control="login-form-email|login-form-password"

         />

         <form:addvalidator

            class="EMailValidator"

            button="login-form-send"

            control="login-form-email"

         />

         <form:addfilter

            class="EMailFilter"

            button="login-form-send"

            control="login-form-email"

         />

         <label for="login-form-email">

            <form:getstring namespace="modules::usermanagement" config="language" entry="form.email" />

         </label>

         <form:text id="login-form-email" name="login-form-email" />

         <label for="login-form-pass">

            <form:getstring namespace="modules::usermanagement" config="language" entry="form.pass" />

         </label>

         <form:password id="login-form-pass" name="login-form-password" />

         <div class="fullsizebox buttonbox">

            <form:button name="login-form-send" class="button"/>

         </div>

      </div>

   </html:form>

</div>
Der dazugrhörige DocumentController so:

Code: Alles auswählen

<?php


	import('tools::link','FrontcontrollerLinkHandler');

	import('modules::usermanagement::biz','umgtManager');



	/**

	 * @package modules::usermanagement::pres::documentcontroller

	 * @class login_controller

	 *

	 * Document controller for the login view of the usermanagement module.
	 * If a user is just a guest it will show the loginform and if a user is logged
	 * in it will show a administration menu in the left sidebar.

	 *

	 * @author Andreas Wilhelm

	 * @version

	 * Version 0.1, 19.03.2010<br />

	 */

	class login_controller extends base_controller {



		public function login_controller(){

		}



		/**

		 * @public

		 *

		 * Displays the form or the administration menu 
		 * and handles the user input.

		 *

		 * @author Andreas Wilhelm

		 * @version

		 * Version 0.1, 19.03.2010<br />

		 */

		function transformContent() {

			// Load the login form, ...

			$form = &$this->__getForm('login') ;



			// ... generate a generic action url, ...

			$action = FrontcontrollerLinkHandler::generateLink($_SERVER['REQUEST_URI'],$_REQUEST);
			
			// ... assign it to the form tag ...

			$form->setAction($action);
			
			// ... and check if it was submitted.
			if( $form->isSent() && $form->isValid() ) {
				// Get the submitted email address ...
				$user = &$form->getFormElementByName('login-form-email');
				
				// ... and the password.
				$pass = &$form->getFormElementByName('login-form-password');
				
				// Get the business object, ... 
				$umgt = &$this->__getAndInitServiceObject('modules::usermanagement::biz','umgtManager','Default'); 

				// ... load the user with this email and password ...
				$user = $umgt->loadUserByUsernameAndPassword(
					$user->getAttribute('value'),
					$pass->getAttribute('value')
				);

				// ... and check if he exists.
				if( $user == null ) {
					// User does not exists so show the login form.
					$form->transformOnPlace();
				} 
				
				else {
					// User does exist so create a new user session ...
					$sm = new SesssionManager('modules::usermanagement::pres::documentcontroller::login_controller');
					$sm->saveSessionData('user', $user);
   
   				// ... and show the administration menu
					$menu = &$this->__getTemplate('menu');
					$menu->transformOnPlace();
				}
			}
			
			// The form was not submitted.
			else {
				// Load the language configuration, ...
				$config = &$this->__getConfiguration('modules::usermanagement','language');
				
				// ... label the submit button, ...
				$button = &$form->getFormElementByName('login-form-send');

				$button->setAttribute('value',$config->getValue($this->__Language,'form.button'));

				// ... fill listeners with the language dependent values ...
				$addrError = &$form->getFormElementByID('addr-error');

				$addrError->setPlaceHolder(
					'content', 
					$config->getValue($this->__Language,'form.email.error')
				);
				
				$passError = &$form->getFormElementByID('pass-error');

				$passError->setPlaceHolder(
					'content', 
					$config->getValue($this->__Language,'form.pass.error')
				);

				// ... and dump the form.
				$form->transformOnPlace();
			}
		}
	}

?>
Liebe Grüße,

Andreas

Benutzeravatar
dr.e.
Administrator
Beiträge: 4555
Registriert: 04.11.2007, 16:13:53

Re: Benutzerverwaltung integrieren

Beitrag von dr.e. » 22.03.2010, 21:11:02

Hallo Andreas,

ich habe deine Sourcen 1:1 in dein Projekt kopiert und konnte absolut keinen Fehler feststellen. Das Login-Formular wird angezeigt, ich kann versuchen mich zu authentifizieren und es gibt lediglich einen Fehler beim Versuch die DB zu konnektieren. Das ist aber auch klar. Ich teste lokal gegen PHP 5.2.x auf Windows und 5.3 auf meiner Fedora-Büchse.

Kannst du zum Test mal in die Datei html_taglib_form.php folgendes ab Zeile 199 kopieren:

Code: Alles auswählen

echo '<br />Count of form children: '.count($this->__Children);
foreach($this->__Children as $objectId => $DUMMY){
   echo '<br />Current tag name: '.get_class($this->__Children[$objectId]); 
}
Sollte alles glatt gehen, haben wir hier eine Anzahl, die mit den Ausgaben korrelliert und korrekte Klassen-Namen. Sollte das auch keine korrekte Ausgabe liefern, habe ich fast die Befürchtung, dass wir hier in einen PHP-Bug laufen.
Dateianhänge
avedo_form_error.zip
(910.39 KiB) 110-mal heruntergeladen
Viele Grüße,
Christian

Avedo

Re: Benutzerverwaltung integrieren

Beitrag von Avedo » 23.03.2010, 01:32:10

Guten Abend!

Nehme ich das Passwort aus der connections.ini raus erhalte ich auch nur den Verbindungsfehler. Ich habe mal die Zeile eingefügt und mir ist etwas lustiges aufgefallen. Scheinbar wird die Methode isValid() zwei mal aufgerufen. Beim ersten Aufruf geht alles glatt.

Code: Alles auswählen

Count of form children: 12
Current tag name: form_taglib_listener
Current tag name: form_taglib_listener
Current tag name: form_taglib_addfilter
Current tag name: form_taglib_addvalidator
Current tag name: form_taglib_addvalidator
Current tag name: form_taglib_error
Current tag name: form_taglib_error
Current tag name: form_taglib_button
Current tag name: form_taglib_text
Current tag name: form_taglib_password
Current tag name: form_taglib_getstring
Current tag name: form_taglib_getstring 
Beim zweiten Aufruf

Code: Alles auswählen

Count of form children: 12
Current tag name: form_taglib_listener
Current tag name: form_taglib_listener
Current tag name: form_taglib_addfilter
Current tag name: form_taglib_addvalidator
Current tag name: form_taglib_addvalidator
Current tag name: form_taglib_error
Current tag name: form_taglib_error
Current tag name: form_taglib_button
Current tag name:
Current tag name: form_taglib_password
Current tag name: form_taglib_getstring
Current tag name: form_taglib_getstring
Fehlt der neunte Eintrag. Frag mich bloß nicht wieso. Ich habe keine Ahnung. Kann es sein, dass dieser Eintrag irgendwo ausversehen gelehrt wird?

Liebe Grüße,

Andreas

Benutzeravatar
dr.e.
Administrator
Beiträge: 4555
Registriert: 04.11.2007, 16:13:53

Re: Benutzerverwaltung integrieren

Beitrag von dr.e. » 23.03.2010, 09:23:29

Hallo Andreas,

das ist schon mal ein guter Ansatz, das Kind-Objekt ist tatsächlich null. Ich verstehe zwar noch nicht, warum, aber ich kann es wenigstens schon mal nachvollziehen. :roll:

Melde mich, sobald ich das Problem gefunden und behoben habe.
Viele Grüße,
Christian

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast