Adventure,PHP,Framework,PageController,FrontController,Pattern,Objektorientierung,OO,Software,Design,Wiederverwendbarkeit,UML,Tutorial,Benchmark,ausgezeichnete Performance

Suche:    
Downloads  |  SVN!  |  Roadmap  |  Forum!  |  Bugtracking  |  Gästebuch  |  Backlinks!  |  Referenzen!  |  Sitemap  |  Impressum  
 
Deutsch Adventure PHP Framework  Bookmark @ Technorati Bookmark @ del.icio.us Bookmark @ Mr. Wong Bookmark @ Simpy Bookmark @ Google Bookmark @ Digg.com Adventure PHP Framework Seite 059_gaestebuch_tutorial_3 drucken!

Gästebuch-Tutorial (3)

Artikel bewerten:
Dieser Artikel wurde noch nicht bewertet. Bewerten Sie diesen Artikel als erstes!
Die folgenden Kapiteln beschreiben den Entwurf des Verwaltungs-Backends. Die Ausgabe desselben kann unter Demo-Gästebuch eingesehen werden.


9. Entwurf der Backend-Funktionalitäten

Der Aufbau des Gästebuchs hinsichtlich Templates bietet bereits die Möglichkeit, unterschiedliche Views in den unteren Bereich einzubinden. Wie im Kapitel 8.2 bereits dargelegt, kann durch den <core:importdesign />-Tag überd en URL-Parameter gbview gesteuert werden, welche View eingebunden wird. Diese Tatsache wird bei der Einbindung der Backend- Komponenten ausgenutzt und jeder "Admin-View" über diesen Mechanismus eingebunden.


9.1. Definition der Views

Das Gästebuch beinhaltet gemäß Datenmodell (siehe Kapitel 2) zwei Objekttypen, die zur Bearbeitung angeboten werden müssen: Entry und Comment. Für diese sind jeweils zwei Aktionen - bearbeiten und löschen - denkbar. Zudem muss es mölich sein, einem Eintrag einen Kommentar hinzuzufügen und sich als Administrator anzumelden. Im Ganzen sind das dann 6 weitere Views.
Der View "display" muss zudem um einen Login-Link und die Ausgabe von Bearbeitungsmöglichkeiten zu einem Entry oder Comment ergänzt werden.


9.2. Erweiterung des Display-Views

Um im eingeloggten Zustand Einträge und Kommentare bearbeiten zu können, wird das Template display.html um fünf HTML-Templates erweitert. Diese definieren das Aussehen der Bearbeiten- und Löschen-Links:
<html:template name="AdminDelete">
  <a href="<template:placeholder name="Link" />" title="Beitrag löschen!"><strong>[ del ]</strong></a>
</html:template>

<html:template name="AdminEdit">
  <a href="<template:placeholder name="Link" />" title="Beitrag bearbeiten!"><strong>[ edt ]</strong></a>
</html:template>

<html:template name="AdminAddComment">
  <a href="<template:placeholder name="Link" />" title="Kommentar hinzufügen!"><strong>[ cmt ]</strong></a>
</html:template>

<html:template name="AdminDeleteComment">
  <a href="<template:placeholder name="Link" />" title="Kommentar löschen!"><strong>[ del ]</strong></a>
</html:template>

<html:template name="AdminEditComment">
  <a href="<template:placeholder name="Link" />" title="Kommentar bearbeiten!"><strong>[ edt ]</strong></a>
</html:template>
Des Weiteren werden die Templates für die Ausgabe eines Eintrags und eines Kommentars um weitere Platzhalter erweitert, die die Links zur Bearbeitung aufnehmen können:
<html:template name="Comment">
  [..]
  <div style="width: 98%; text-align: right;">
    <template:placeholder name="AdminEditComment" /> <template:placeholder name="AdminDeleteComment" />
  </div>
</html:template>
<html:template name="Entry">
  [..]
  <div style="width: 100%; text-align: right;">
    <template:placeholder name="AdminAddComment" /> <template:placeholder name="AdminEdit" />
    <template:placeholder name="AdminDelete" />
  </div>
  <br />
  <br />
</html:template>

Der für den View zuständige Document-Controller wurde - um die Funktion zur Verfügung stellen zu können - ebenfalls um fünf weitere Methoden erweitert, die die Bearbeitungs- Möglichkeiten an Hand der oben aufgeführten Templates zu generieren. Diese wird natürlich nur angezeigt, wenn ein Administrator eingeloggt ist. Beispielhaft sei hier die Methode __showAdminDelete() aufgeführt, die den Bearbeitungs-Link für das Löschen eines Eintrags generiert.
   function __showAdminDelete($EntryID){

      if(
$this->__sessMgr->loadSessionData('AdminView') == true){

         
// Template holen
         
$Template__AdminDelete = &$this->__getTemplate('AdminDelete');

         
// Link generieren und einsetzen
         
$Link linkHandler::generateLink(
                                           
$_SERVER['REQUEST_URI'],
                                           array(
'gbview' => 'admindelete','entryid' => $EntryID)
                                          );
         
$Template__AdminDelete->setPlaceHolder('Link',$Link);

         
// Template zurückgeben
         
return $Template__AdminDelete->transformTemplate();

       
// end if
      
}

      return (string)
'';

    
// end function
   
Die Funktionen im Überblick:
Die Methode prüft zuerst, ob ein Administrator eingeloggt ist und er AdminView angezeigt werden darf. Ist das nicht der Fall wird ein Leer-String zurückgegeben.
Ist der AdminView gewünscht, so holt sich die Methode eine Referenz auf das Template, das das Ausehen des Links definiert, generiert den Link und erzeugt die Ausgabe. Diese Ausgabe wird dann bei jedem angezeigten Eintrag eingebunden. Dazu wurde das HTML-Template zur Anzeige eines Eintrags um den Platzhalter AdminDelete erweitert, der in der Methode __generateEntry() mit der Ausgabe der Methode __showAdminDelete() gefüllt wird:

   function __generateEntry($Entry){

      
// Referenz auf das Template holen
      
$Template__Entry = &$this->__getTemplate('Entry');

      
// Werte setzen
      
$Template__Entry->setPlaceHolder('AdminDelete',$this->__showAdminDelete($Entry->get('ID')));
      
$Template__Entry->setPlaceHolder('AdminEdit',$this->__showAdminEdit($Entry->get('ID')));
      
$Template__Entry->setPlaceHolder('AdminAddComment',$this->__showAdminAddComment($Entry->get('ID')));
      
$Template__Entry->setPlaceHolder('ID',$Entry->get('ID'));
      
$Template__Entry->setPlaceHolder('Name',$Entry->get('Name'));

      [..]

    
// end function
   
Wie im Code-Beispiel angedeutet wird die Ausgabe des Links zum Löschen eines Eintrags und zum Hinzufügen eines Kommentars im gleichen Stil eingebunden. Auf diese Weise bleibt die Generierung des Links in den Methoden __showAdmin*() gekapselt und kann später einfach angepasst werden.


9.3. Login-View

Damit die Bearbeitung nicht durch beliebige Personen passieren kann, wird ein Login eingeführt. Wie in Kapitel 2 besprochen, werden im Gästebuch-Objekt die Admin-Zugangsdaten verwaltet. Diese können im Login angefragt und der potentielle Administrator so authentifiziert werden. Der Login-View besteht im Wesentlichen aus zwei Teilen: der Template-Datei, die das Formular und entsprechende Hinweistexte enthält und der Document-Controller. Diese werden im Folgenden genauer erläutert:


9.3.1. Template-Datei adminlogin.html
Die Template-Datei adminlogin.html definiert ein Formular und eine HTML-Template das eine Meldung enthält, die ausgegeben werden soll, wenn die Zugangsdaten nicht mit den in der Datenbank gespeicherten Daten übereinstimmen. Das Formular enthält zwei Elemente und einen Button:
<@controller namespace="modules::guestbook::pres::documentcontroller" class="guestbook_adminlogin_v1_controller" file="guestbook_adminlogin_v1_controller" @>
<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
<br />
<br />
<strong>Gästebuch administrieren:</strong>
<br />
<br />
Hier kannst du dich einloggen um das Gästebuch zu administrieren.
<br />
<br />
<html:placeholder name="Form" />

<html:form name="AdminLogin" method="post" action="">
  <form:placeholder name="LogInError" />
  Benutzer: <form:text name="Username" class="eingabe_feld" style="width: 200px; margin-left: 20px;" validate="true" button="AdminLogin" />
  <br />
  Passwort: <form:password name="Password" class="eingabe_feld" style="width: 200px; margin-left: 16px;" validate="true" button="AdminLogin" />
  <br />
  <br />
  <form:button name="AdminLogin" value="Login" class="eingabe_feld" style="margin-left: 227px;"/>
</html:form>

<html:template name="LogInError">
  <font style="color: red; font-weight: bold;">Die von Ihnen eingegebenen Zugangsdaten sind falsch!</font>
  <br />
  <br />
</html:template>
9.3.2. Controller-Datei guestbook_adminlogin_v1_controller.php
Die Datei guestbook_adminlogin_v1_controller.php implementiert den Document-Controler für den Login-View.
import('modules::guestbook::biz','guestbookManager');
import('core::session','sessionManager');
import('modules::guestbook::pres::documentcontroller','guestbookBaseController');

class 
guestbook_adminlogin_v1_controller extends guestbookBaseController
{

   var 
$_LOCALS;

   function 
guestbook_adminlogin_v1_controller(){

      
$this->_LOCALS variablenHandler::registerLocal(array(
                                                             
'Username',
                                                             
'Password',
                                                             
'logout'
                                                            
)
                                                      );

    
// end function
   
}

   function 
transformContent(){

      
// Logout
      
if($this->_LOCALS['logout'] == 'true'){

         
// Inhalte der Session erstören
         
$oSessMgr = new sessionManager('Module_Guestbook');
         
$oSessMgr->destroySession('Module_Guestbook');

         
// Auf Anzeige-Seite weiterleiten
         
$Link linkHandler::generateLink($_SERVER['REQUEST_URI'],array('gbview' => 'display','logout' => ''));
         
header('Location: '.$Link);

       
// end if
      
}

      
// Referenz auf das Formular holen
      
$Form__AdminLogin = &$this->__getForm('AdminLogin');

      if(
$Form__AdminLogin->get('isValid') && $Form__AdminLogin->get('isSent')){

         
// Manager holen
         
$gM = &$this->__getGuestbookManager();

         
// Prüfen, ob Zugangsdaten gültig sind
         
if($gM->validateCrendentials($this->_LOCALS['Username'],$this->_LOCALS['Password']) == true){

            
// Session starten
            
$oSessMgr = new sessionManager('Module_Guestbook');
            
$oSessMgr->saveSessionData('LoginDate',date('Y-m-d'));
            
$oSessMgr->saveSessionData('LoginTime',date('H:i:s'));
            
$oSessMgr->saveSessionData('AdminView',true);

            
// Auf Anzeige-Seite weiterleiten
            
$Link linkHandler::generateLink($_SERVER['REQUEST_URI'],array('gbview' => 'display'));
            
header('Location: '.$Link);

          
// end if
         
}
         else{
            
$this->setPlaceHolder('Form',$this->__displayForm(true));
          
// end else
         
}

       
// end if
      
}
      else{
         
$this->setPlaceHolder('Form',$this->__displayForm());
       
// end elseif
      
}

    
// end function
   
}

   function 
__displayForm($ShowLogInError false){

      
// Referenz auf das Formular holen
      
$Form__AdminLogin = &$this->__getForm('AdminLogin');

      
// Fehlermeldung ausgeben, falls gewünscht
      
if($ShowLogInError == true){

         
// Template mit Meldung holen
         
$Template__LogInError = &$this->__getTemplate('LogInError');

         
// Template in Form einsetzen
         
$Form__AdminLogin->setPlaceHolder('LogInError',$Template__LogInError->transformTemplate());

       
// end if
      
}

      
// Formular transformieren und zurückgeben
      
return $Form__AdminLogin->transformForm();

    
// end function
   
}

 
// end class
Die Methode transformContent() kapselt dabei die Funktionen für Logout und Login. Um einen Benutzer auszuloggen wird die vorhandene Session zerstört und der Benutzer auf den View "display" weitergeleitet. Beim Login-Versuch wird zunächst das Firmular solange gezeigt, bis es korrekt ausgefüllt wurde. Anschließend wird gepräft, ob die Zugangsdaten korrekt sind. Wurden falsche Daten eingegeben, wird die im Template LogInError definierte Warnmeldung in das Formular eingesetzt und ausgegeben. Sind die Daten korrekt, wird die Information, dass ein Administrator eingeloggt ist, in der Session gespeichert und der Administrator wird auf den View "display" weitergeleitet.
Für die Formular-Prüfung können einfache Bedingungs-Konstrukte verwendet werden, da das Formular-Objekt zur Zeit der Ausführung eines Document-Controllers die Request-Parameter bereits vollständig verarbeitet hat. Damit steht dem Entwickler die Information, ob das Formular abgesendet und korrekt ausgefüllt wurde, über die Attribute isSent und isSent zur Verfügung. Die beiden Attribute können mit der get()- Methode abgefragt werden. Zum Test kann folgender PHP-Code verwendet werden:
$Form__AdminLogin = &$this->__getForm('AdminLogin');

if(
$Form__AdminLogin->get('isSent')){
   echo 
'<br />Formular wurde abgesendet!';
 
// end if
}

if(
$Form__AdminLogin->get('isValid')){
   echo 
'<br />Formular wurde mit korrekten Werten ausgef&uuml;llt!';
 
// end if
Nach dem erfolgreichen Login ist dann dem display-View ebenfalls bekannt, dass die Administrations-Buttons abgezeigt werden sollen.


9.4. Kommentar-View

Ein weiterer View ist der View zum Hinzufügen eines Kommentars. Auch diese wird durch eine Template-Datei (adminaddcomment.html) und eine Document-Controller-Datei (guestbook_adminaddcomment_v1_controller.php) repräsentiert.


9.4.1. Template-Datei adminaddcomment.html
Die Template-Datei definiert ein Formular, mit dem ein Kommentar hinzugefügt werden kann. Die Formular-Felder Title und Text verfügen über die Attribute validate und button um die Validierung der Felder zu definieren:
<@controller namespace="modules::guestbook::pres::documentcontroller" class="guestbook_adminaddcomment_v1_controller" file="guestbook_adminaddcomment_v1_controller" @>
<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
<br />
<br />
<strong>Neuen Kommentar verfassen:</strong>
<br />
<br />
Hier kannst du deinen Kommentar zum ausgewählen Eintrag verfassen! Fülle die Pflicht-Felder vollständig aus!
<br />
<br />
<html:placeholder name="Form" />

<html:form name="GuestbookAddComment" method="post" action="">
  <table cellpadding="0" cellspacing="0" class="formtable">
    <tr>
      <td class="formtable_row_description">
        Ihr Titel: *
      </td>
      <td class="formtable_row_control">
        <form:text name="Title" class="eingabe_feld" style="width: 300px;" validate="true" button="CreateCommentButton" />
      </td>
    </tr>
    <tr>
      <td colspan="2" class="formtable_row_description">
        <br />
        <strong>Ihr Text:</strong> *
        <br />
        <br />
        <form:area name="Text" class="eingabe_feld" style="height: 200px; width: 480px; overflow: auto;" validate="true" button="CreateCommentButton" />
      </td>
    </tr>
  </table>
  <br />
  <span style="font-size: 11px;">
    <strong>Hinweis:</strong> Die mit "*" gekennzeichneten Felder sind Pflichtfelder!
  </span>
  <br />
  <br />
  <br />
  <form:button name="CreateCommentButton" value="Speichern" class="eingabe_feld" />
  <form:hidden name="entryid" value="" />
</html:form>
9.4.2. Controller-Datei guestbook_adminaddcomment_v1_controller.php
import('modules::guestbook::biz','guestbookManager');
import('modules::guestbook::pres::documentcontroller','guestbookBaseController');

class 
guestbook_adminaddcomment_v1_controller extends guestbookBaseController
{

   var 
$_LOCALS;

   function 
guestbook_adminaddcomment_v1_controller(){

      
$this->_LOCALS variablenHandler::registerLocal(array(
                                                             
'Title',
                                                             
'Text',
                                                             
'entryid'
                                                            
)
                                                      );

    
// end function
   
}

   function 
transformContent(){

      
// Referenz auf das Formular holen
      
$Form__GuestbookAddComment = &$this->__getForm('GuestbookAddComment');

      
// Aktion für Eintrag
      
if($Form__GuestbookAddComment->get('isSent') == true){

         if(
$Form__GuestbookAddComment->get('isValid')){

            
// Manager holen
            
$gM = &$this->__getGuestbookManager();

            
// Eintrag erzeugen
            
$Comment = new Comment();
            
$Comment->set('Title',$this->_LOCALS['Title']);
            
$Comment->set('Text',$this->_LOCALS['Text']);

            
// Eintrag speichern
            
$gM->saveComment($this->_LOCALS['entryid'],$Comment);

          
// end if
         
}

       
// end if
      
}

      
// Formular anzeigen
      
$ID = &$Form__GuestbookAddComment->getFormElementByName('entryid');
      
$ID->setAttribute('value',$this->_LOCALS['entryid']);
      
$this->setPlaceHolder('Form',$Form__GuestbookAddComment->transformForm());

    
// end function
   
}

 
// end class
Die Implementierung des Controllers beschränkt sich hier auf die Anzeige des Formulars und die Organisation der Kommentar-Speicherung. Hierzu prüft der Controller - wie bereits oben erlätert - ob das Formular abgeschickt und richtig ausgefüllt wurde und involviert in diesem Fall die Business-Komponente guetbookManager um den Kommentar zu speichern.
Der guestbookManager muss für die Verwendung mit der aktuellen Gästebuch-ID initialisiert initialisiert werden. Um diese Funktionaliät nur einmal bereit stellen zu müssen, wurde ein weiterer Basis-Controller implementiert (guestbookBaseController), der die Initialisierung in der privaten Methode __getGuestbookManager() erledigt. Leitet ein Document-Controller nun von diesem ab, so kann die Business-Komponente einfach durch
// Manager holen
$gM = &$this->__getGuestbookManager(); 
statt durch
// guestbookid vom Vater holen
$Parent = &$this->__Document->getByReference('ParentObject');
$GuestbookID $Parent->getAttribute('guestbookid');

// Manager holen
$gM = &$this->__getAndInitServiceObject('modules::guestbook::biz','guestbookManager',$GuestbookID); 
initialisiert werden. Dieser Ansatz wird innerhalb von Modulen sehr häufig verwendet im gemeinsam genutzte Funktionen auslagern zu können.


9.5. Weitere Views

Die übrigen Views können im Offline-Package (siehe Downloads) im Ordner apps/modules/guestbook/pres/templates/ analysiert werden. Die zugehörigen Controller werden dabei jeweils in der ersten oder zweiten Zeile definiert und befinden sich im Ordner apps/modules/guestbook/prtes/documentcontroller/.


10. Erweiterung Business-Schicht

Um die Backend-Funktionalitäten anbieten zu können muss die Klasse guestbookManager um die Services
  • validateCrendentials($Username,$Password)
  • deleteEntry($Entry)
  • deleteComment($Comment)
gegenüber dem in Kapitel 2 vorgestellten Design erweitert werden. Die Methode validateCrendentials() übernimmt dabei die Validierung der vom Benutzer eingegebenen Zugangsdaten für das Backend, deleteEntry() und deleteComment() werden für die Aktionen "Eintrag löschen" und "Kommentar löschen" benötigt.


11. Erweiterung Daten-Schicht

Die Datenschicht muss um die Services
  • deleteEntry($Entry)
  • deleteComment($Comment)
gegenüber dem in Kapitel 2 vorgestellten Design erweitert werden. Die Methode deleteEntry() übernimmt dabei das Löschen eines Eintrags, deleteComment() löscht einen Kommentar. Diese werden für die Aktionen "Eintrag löschen" und "Kommentar löschen" benötigt.


12. Schlussbemerkung

Das hier aufgeführte Software-Design wurde unter Berücksichtigung der Möglichkeiten des Adventure-PHP-Frameworks erstellt, beinhaltet aber ausgenommen den Implementierungs- Details wichtige Grundsätze der objektorientierten Programmierung.


Kommentare

Möchten Sie den Artikel eine Anmerkung hinzufügen, oder haben Sie ergänzende Hinweise? Dann können Sie diese hier einfügen. Die bereits verfassten Anmerkungen und Kommentare finden Sie in der untenstehenden Liste.


Für diesen Artikel liegen aktuell keine Kommentare vor.


Powered by WebRing.