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 | English Adventure PHP Framework  Bookmark @ Technorati Bookmark @ del.icio.us Bookmark @ Mr. Wong Bookmark @ Simpy Bookmark @ Google Bookmark @ Digg.com Adventure PHP Framework Seite 035_kontakt_formular_tutorial drucken!

Kontaktformular-Tutorial

Artikel bewerten:
Bitte bewerten Sie den Artikel per Klick auf einen der angezeigten Sterne:
Zurück zum Artikel!

1. Einleitung

Das vorliegende Tutorial möchte eine weitere Anwendung der Formular-TagLibs und des <core:importdesign />-Tags zeigen. Das hier diskutierte Kontakt-Formular bietet die Möglichkeit, Empänger-Adressen vor Grabbern und Bots zu schützen, die E-Mail-Adressen von Webseiten auslesen. Die Empfängerliste des Formulars ist beliebig konfigurier- und erweiterbar. Die Anwendung kann mit Hilfe des <core:importdesign />-Tags an beliebiger Stelle in eine PageController-basierte Anwendung eingebunden werden.


2. Grundlagen

Auch in diesem Tutorial werden Techniken eingesetzt, die bereits in den vorangegangenen Tutorials zur Anwendung gekommen sind. Der Autor geht davon aus, dass das Kapitel 2 des Kommentarfunktion-Tutorials gelesen und verstanden wurden. Kapitel 2 beschreibt dabei die Trennung der Funktionen einer Software in drei Schichten, denen unterschiedliche Funktionen zugeteilt werden. Weiterhin beschreibt das Kapitel, wie Domain-Objekte zur Kommunikation zwischen den genannten Schichten fungieren und welche Rolle das MVC-Pattern bei der Implementierung einer Anwendung spielt.


2.1. Konfiguration

Um die Applikation in unterschiedlichen Projekten einsetzbar zu machen müssen Projekt-spezifische Belange in Konfigurationsdateien ausgelagert werden. Konfiguration ist beim Kontaktformular in zweierlei Hinsicht notwendig: Zum einen müssen die Enpfänger-Namen und -Adressen konfigurierbar sein, zum anderen müssen die Ausgabetexte der verwendeten Formular-TagLibs (Validatoren) für das Projekt konfiguriert werden.

An dieser Stelle soll ein kleiner Exkurs zur Konfiguration der Formular-Validatoren eingeschoben werden:
Die Tags
  • <form:validate />
  • <valgroup:validate />
benötigen zur Ausgabe einer Validierungsmeldung eine sprachabhängige Konfigurationsdatei, die die entsprechenden Texte beinhaltet. Die Konfigurationsdatei wird dabei unter dem Pfad
  /config/tools/form/taglib/{CONTEXT}/{ENVIRONMENT}_formconfig.ini
erwartet. {CONTEXT} ist dabei der Context der aktuellen Applikation und {ENVIRONMENT} ist gegen den Wert der Umgebungsvariable der Registry zu ersetzen. Im Fall der vorliegenden Dokumentationsseite wird die Datei unter
  /config/tools/form/taglib/sites/demosite/DEFAULT_formconfig.ini
erwartet. Wie im Kapitel Standard-TagLibs unter 2.3.16 und 2.3.17 zu lesen ist, können jedem der genannten Tags die optionalen Attribute
  • msginputreq=""
  • msginputwrg=""
mitgegeben werden. Diese definieren einen Konfigurationsschlüssel, der einen sprachabhängigen Text enthällt, der bei Eingabe eines nicht gültigen Wertes angezeigt wird. Mit diesem Mechanismus werden zwei Bereiche abgedeckt: einerseits ist es möglich, einen Satz an Texten für eine komplette Applikation zu definieren und diese anschließend in mehreren Modulen nutzen zu können, zum anderen werden die Texte in einfache Textedateien ausgelagert und können einfach übersetzt werden.

Beispiel:
Soll bei der Validierung eines E-Mail-Feldes der Text
  Bitte geben Sie eine E-Mail-Adresse sein!
erscheinen, wenn das Feld nicht gefüllt wurde und
  Bitte geben Sie eine gültige E-Mail-Adresse sein!
wenn das Feld nicht mit einer syntaktisch richtigen E-Mail-Adresse gefüllt wurde, dann kann für dieses Feld innerhalb eines Formulars wie folgt ein Validator-Tag definiert werden:
  <form:validate
                  button="send"
                  field="email"
                  type="EMail"
                  msginputreq="Contact.EMail.InputRequired"
                  msginputwrg="Contact.EMail.InputWrong"
  />
Das Attribut button definiert dabei den Namen des Button, der die Validierung auslösen soll, das Attribut field das zu validierende Feld und type den Validator-Typ. Die Inhalte der Attribute msginputreq und msginputwrg wurden in diesem Fall mit dem Prefix "Contact.EMail." versehen um die Zugehörigkeit zur Applikation Kontaktformular und zum Feld E-Mail kenntlich zu machen. Diese Konvention hat sich eingebürgert, um schnell erkennen zu können, welcher Konfigurationsschlüssel zu welcher Applikation gehört. Des Weiteren ist es ratsam, die Konfigurationsdateien zu kommentieren.

Die Konfigurationsdatei muss damit bei Betrieb der Applikation in deutscher und englischer Sprache folgenden Inhalt haben:
[de]
Contact.EMail.InputRequired = "Bitte geben Sie eine E-Mail-Adresse sein!"
Contact.EMail.InputWrong = "Bitte geben Sie eine gültige E-Mail-Adresse sein!"

[en]
Contact.EMail.InputRequired = "Please fill the field sender name!"
Contact.EMail.InputWrong = "Please provide a valid email address!"

2.2. Mehrsprachigkeit

Das Framework bietet mehrere Möglichkeiten Applikationen und Module auf Mehrsprachigkeit auszulegen. Zum einen wird die Sprache eines Objekts in jedem DOM-Knoten mitgeführt und der Entwickler hat damit die Möglichkeit sprachabhängige Texte in einem DocumentController einzusetzen, zum anderen gibt es XML-Tags wie
  • <html:getstring />
  • <template:getstring />
  • <form:getstring />
die sprachabhängige Texte aus Konfigurationsdateien an enstprechenden Stellen anzeigen. Im Fall des Kontaktformulars wird eine Mischform eingesetzt. Als Basis für beide Möglichkeiten dient eine gemeinsame Konfigurationsdatei
 /config/modules/kontakt4/{CONTEXT}/{ENVIRONMENT}_language.ini
Diese wird mit folgenden Werten gefüllt:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Language file for the contact form module                                                        ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

[de]
; header
header.title = "Kontakt"

; hints on the form
formhint.text = "Wenn Sie mit mir in Kontakt treten möchten, dann benutzen Sie einfach dieses Formular. Geben Sie Ihre Nachricht ein und schon kann es los gehen. Ich werden mich dann umgehend mit Ihnen in Verbindung setzten. Bitte füllen Sie das Formular vollständig aus!"

; form labels
form.person = "Person / Gruppe: "
form.person.margin = "24"
form.name = "Ihr Name:"
form.name.margin = "65"
form.email = "Ihre E-Mail-Adresse:"
form.email.margin = "9"
form.subject = "Ihr Betreff:"
form.subject.margin = "65"
form.comment = "Ihre Nachricht:"
form.button = "Senden"
form.button.style = "margin-left: 335px;"
form.captcha = "Bestätigungscode:"

; confirmation text
message.text = "Vielen Danke für Ihre Anfrage. Ich werde mich umgehend mit Ihnen in Verbindung setzen!"

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

[en]
; header
header.title = "Contact"

; hints on the form
formhint.text = "If you want to contact me, please use the form provided below. Then I will immediately get in contact with you. Please fill all required fields!"

; form labels
form.person = "Person / group: "
form.person.margin = "33"
form.name = "Your name:"
form.name.margin = "57"
form.email = "Your email address:"
form.email.margin = "9"
form.subject = "Your subject:"
form.subject.margin = "49"
form.comment = "Your message:"
form.button = "Send"
form.button.style = "margin-left: 350px;"
form.captcha = "Security code:"

; confirmation text
message.text = "Many thanks for your message. I will get in contact with you immediately!"
Die Werte können damit z.B. per
  • <html:getstring namespace="modules::kontakt4" config="language" entry="form.person" />,
  • <template:getstring namespace="modules::kontakt4" config="language" entry="form.person" /> oder
  • <form:getstring namespace="modules::kontakt4" config="language" entry="form.person" />
ausgelesen werden. Die Beschriftung von Formular-Controls stellt eine zweite Möglichkeit dar, sprachabhängige Texte zur Anzeige zu bringen. In diesem Fall muss im DocumentController Einfluss auf die Beschriftung genommen werden. Dies kann mit folgenden Code passieren:
// Sprachabh&auml;ngige Konfiguration laden
$Config = &$this->__getConfiguration('modules::kontakt4','language');

// Referenz auf das Button-Control holen
$Button = &$Form->getFormElementByName('KontaktSenden');

// Sprachabh&auml;ngigen Text mit Hilfe von $this->__Language auslesen
$Button->setAttribute('value',$Config->getValue($this->__Language,'form.button')); 

2.3. Struktur des Moduls

Ähnlich der Struktur des Moduls "comments" wird auch dieses Software unter dem Ordner modules abgelegt. Hierzu dient der Ordner kontakt4, der wie folgt unterteilt wird:
  /modules/
           kontakt4/
                    biz/
                    data/
                    pres/
                         documentcontroller/
                         templates/
Der Ordner biz dient der Ablage der Business-Komponenten (je ein Domain-Objekt für die Daten des Formulars und die Empfänger), im Ordner data ist der Mapper beheimatet, der die Empfänger einliest und der Ordner pres dient zur Ablage der Controller- und Template-Dateien der Präsentationsschicht. Im Ganzen betrachtet soll das Kontaktformular aus den folgenden Dateien bestehen:

  • /modules/kontakt4/pres/templates/kontakt.html:
    Die Datei kontakt.html beinhaltet das Hauptdesign und steuert die Ausgabe von Formular oder Dankesseite mit einem <core:importdesign />-Tag.
  • /modules/kontakt4/pres/templates/formular.html:
    Die Datei formular.html beinhaltet das Formular.
  • /modules/kontakt4/pres/templates/meldung.html:
    In meldung.html ist der Inhalt der Dankesseite definiert.
  • /modules/kontakt4/pres/documentcontroller/kontakt_v2_controller.php:
    Für die Ausgabe des Formulars wird ein DocumentController benötigt, der in der Datei kontakt_v2_controller.php enthalten ist.
  • /modules/kontakt4/biz/contactManager.php:
    contactManager.php beheimatet die Business-Komponente, die den Ablauf der Software koordiniert.
  • /modules/kontakt4/biz/oRecipient.php:
    oRecipient.php beinhaltet das Empfänger-Domain-Objekt.
  • /modules/kontakt4/biz/oFormData.php:
    oFormData.php beinhaltet das Domain-Objekt für die Formulardaten.
  • /modules/kontakt4/data/contactMapper.php:
    Die Datei contactMapper.php dient zur Definition der Datenschicht-Komponente, die die Empfänger aus der Konfiguration als Domain-Objekte zur Verfügung stellt.
Wie bereits erwähnt müssen darüber hinaus folgende Konfigurations-Dateien vorgehalten werden:
  • /config/modules/kontakt4/{CONTEXT}/{ENVIRONMENT}_empfaenger.ini:
    Konfiguration der Empfänger
  • /config/tools/form/taglib/{CONTEXT}/{ENVIRONMENT}_formconfig.ini:
    Texte für die Validator-Tags
  • /config/modules/kontakt4/{CONTEXT}/{ENVIRONMENT}_language.ini:
    Sprachabhängige Texte.
Die Syntax der Konfigurationsdateien wurde bereits weiter oben diskutiert, die Inhalte werden im Folgenden noch genauer beschrieben.


3. Implementierung des Moduls

In diesem Tutorial soll wieder der TOP-DOWN-Designansatz verwendet werden. Das aktuelle Kapitel beschreibt daher die oben genannten Dateien ausgehend von der Präsentationsschicht und in der Reihenfolge der Aufzählung.


3.1. Datei kontakt.html

Die Templatedatei kontakt.html definiert das Grundgerüst des Moduls. Es beinhaltet die Überschrift, die per <html:getstring />-Tag aus der Sprach-Konfigurationsdatei eingebunden wird, und einen <core:importdesign />- Tag, der einen View definiert, der entweder das Formular (Standard) oder eine Dankesmeldung anzeigt:
<core:addtaglib namespace="tools::html::taglib" prefix="html" class="getstring" />
<font style="font-size: 26px; font weight: bold;"><html:getstring namespace="modules::kontakt4" config="language" entry="header.title" /></font>
<br />
<br />
<core:importdesign namespace="modules::kontakt4::pres::templates" template="[pagepart=formular]" />
Hinweis: Im Template wird das <core:importdesign />-Tag mit der pagepart-Option benutzt. Dies bedeutet, dass je nach URL-Parameter pagepart ein anderes Template aus den angegebenen Namespace eingebunden wird. Ist kein Parameter in der URL vorhanden wird die im Attribut template angegebene Templatedatei - das Formular - eingebunden.


3.2. Datei formular.html

Die hier behandelte Templatedatei enthält im Wesentlichen vier unterschiedliche Blöcke:
  • Definition des DocumentControllers (Zeile 1)
    Hier wird definiert, welcher Controller (MVC-Controller für den aktuellen DOM-Knoten) zur Transformation herangezogen wird.
  • Einbindung von weiteren TagLibs: (Zeilen 2-3)
    Um die Tag-Library "html:form" bzw. "html:getstring" nutzen zu können müssen diese zunächst mit einem "core:addtaglib"-Tag eingebunden werden.
  • Definition der HTML-Inhalte: (Zeilen 5-9)
    In den Zeilen 5 bis 9 wird das HTML-Grundgerüst des Formular-Views definiert. Dieser beinhaltet einen Hinweistext, der mit einem <html:getstring />-Tag eingebunden wird und einen <html:placeholder />-XML-Tag, der später vom DocumentController mit dem Inhalt des transformierten Formulars gefüllt wird.
  • Formular: (Zeilen 11-43)
    In den Zeilen 11 bis 43 wird das Formular definiert. Dieses beinhaltet eine Validator-Gruppe, die zur Anzeige der Validierungsmeldungen genutzt wird. Die Beschriftungen werden mit dem <form:getstring />-Tag uns der oben beschriebenen Konfigurationsdatei realisiert.
<@controller namespace="modules::kontakt4::pres::documentcontroller" file="kontakt_v4_controller" class="kontakt_v4_controller" @>
<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
<core:addtaglib namespace="tools::html::taglib" prefix="html" class="getstring" />
<html:getstring namespace="modules::kontakt4" config="language" entry="formhint.text" />
<br />
<div style="text-align: left; padding-left: 80px; font-size: 12px;">
  <html:placeholder name="Inhalt" />
</div>

<html:form name="Kontakt" method="post">
  <form:valgroup name="FormValGroup">
    <br />
    <div style="width: 400px; border: 1px solid red; padding: 5px;">
      <img src="<valgroup:placeholder name="WarnImage" />" /> <font style="font-size: 13px; font-weight: bold;"><valgroup:placeholder name="WarnText" />:</font>
      <br />
      <valgroup:validate type="text" field="AbsenderName" button="KontaktSenden" msginputreq="Contact.Sender.InputRequired" />
      <valgroup:validate type="text" field="AbsenderAdresse" button="KontaktSenden" msginputreq="Contact.EMail.InputRequired" msginputwrg="Contact.EMail.InputWrong" validator="EMail" />
      <valgroup:validate type="text" field="Betreff" button="KontaktSenden" msginputreq="Contact.Subject.InputRequired" />
      <valgroup:validate type="text" field="Text" button="KontaktSenden" msginputreq="Contact.Text.InputRequired" />
    </div>
    <br />
  </form:valgroup>
  <br />
  <span style="margin-right: <form:getstring namespace="modules::kontakt4" config="language" entry="form.person.margin" />px;"><form:getstring namespace="modules::kontakt4" config="language" entry="form.person" /></span><form:select name="Empfaenger" class="eingabe_feld" />
  <br />
  <br />
  <span style="margin-right: <form:getstring namespace="modules::kontakt4" config="language" entry="form.name.margin" />px;"><form:getstring namespace="modules::kontakt4" config="language" entry="form.name" /></span><form:text name="AbsenderName" class="eingabe_feld" style="width: 280px;" validate="true" button="KontaktSenden" />
  <br />
  <br />
  <span style="margin-right: <form:getstring namespace="modules::kontakt4" config="language" entry="form.email.margin" />px;"><form:getstring namespace="modules::kontakt4" config="language" entry="form.email" /></span><form:text name="AbsenderAdresse" class="eingabe_feld" style="width: 280px;" validate="true" validator="EMail" button="KontaktSenden" />
  <br />
  <br />
  <span style="margin-right: <form:getstring namespace="modules::kontakt4" config="language" entry="form.subject.margin" />px;"><form:getstring namespace="modules::kontakt4" config="language" entry="form.subject" /></span><form:text name="Betreff" class="eingabe_feld" style="width: 280px;" validate="true" button="KontaktSenden" />
  <br />
  <br />
  <form:getstring namespace="modules::kontakt4" config="language" entry="form.comment" />
  <br />
  <form:area name="Text" class="eingabe_feld" style="height: 200px; width: 400px; overflow: auto;" validate="true" button="KontaktSenden" />
  <br />
  <br />
  <form:getstring namespace="modules::kontakt4" config="language" entry="form.captcha" />
  <br />
  <br />
  <form:addtaglib namespace="modules::captcha::pres::taglib" prefix="form" class="captcha" />
  <form:captcha text_class="eingabe_feld" validate="true" button="KontaktSenden"/>
  <br />
  <br />
  <form:button name="KontaktSenden" class="eingabe_feld" />
</html:form>

3.3. Datei meldung.html

In der Datei meldung.html wird die Dankesmeldung definiert, die bei erfolgreichem Absenden des Formulars eingeblendet wird. In der Regel ist das ein Satz, der besagt, dass der Kunde baldige Rückantwort erhalten werden. In diesem Fall wird die Meldung aus einer Konfigurationsdatei gelesen, die einen mehrsprachigen, aber statischen Text enthält. Aus diesem Grund ist kein weiterer DocumentController notwenig.
<br />
<core:addtaglib namespace="tools::html::taglib" prefix="html" class="getstring" />
<html:getstring namespace="modules::kontakt4" config="language" entry="message.text" />
<br />
<br />

3.4. DocumentController kontakt_v4_controller

Der DocumentController kontakt_v4_controller erbt vom abstrakten DocumentController baseController (Interface). Auf Grund der Objekt-Struktur muss dies immer gegeben sein, die übrige Gestaltung der Klasse bleibt jedoch dem Programmierer überlassen. Es ist somit jederzeit möglich eigene Methoden zu definieren und weitere eigene Klassen per import() hinzuzuladen und zu verwenden. Im Fall des Kontakt-Formulars wird zum Aufbau des Formular-Views die private Methode __buildForm() verwendet. Zu Steuerung der Ausgabe des Designs kontakt.html wird die öffentliche Methode transformContent() implementiert. Sie beschreibt, dass das Formular so lange angezeigt wird, bis alle als Pflichtfelder gekennzeichneten Eingabe-Felder mit validen Werten ausgefüllt sind (siehe Zeile 60). Tritt dieser Fall ein, so wird die Business-Schicht instanziert, das Formular abgeschickt und der Bestätigungsview (Templatedatei meldung.html) angezeigt.
import('tools::variablen','variablenHandler');
import('modules::kontakt4::biz','contactManager');

class 
kontakt_v4_controller extends baseController
{

   var 
$_LOCALS;

   function 
kontakt_v4_controller(){

      
$this->_LOCALS variablenHandler::registerLocal(array('Empfaenger',
                                                             
'AbsenderName',
                                                             
'AbsenderAdresse',
                                                             
'Betreff',
                                                             
'Text'
                                                            
)
                                                      );

    
// end function
   
}

   function 
transformContent(){

      
// Referenz auf die Form holen
      
$Form = &$this->__getForm('Kontakt');

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

         
// Was wird gesendet?
         //
         // - Kontakt-Person-ID (Empf?nger-Person der Mail)
         // - Name
         // - E-Mail
         // - Betreff
         // - Text
         
$oFD = new oFormData();
         
$oFD->set('RecipientID',$this->_LOCALS['Empfaenger']);
         
$oFD->set('SenderName',$this->_LOCALS['AbsenderName']);
         
$oFD->set('SenderEMail',$this->_LOCALS['AbsenderAdresse']);
         
$oFD->set('Subject',$this->_LOCALS['Betreff']);
         
$oFD->set('Text',$this->_LOCALS['Text']);

         
// Formular absenden
         
$cM = &$this->__getServiceObject('modules::kontakt4::biz','contactManager');
         
$cM->sendContactForm($oFD);

       
// end if
      
}
      else{
         
$this->setPlaceHolder('Inhalt',$this->__buildForm());
       
// end else
      
}

    
// end function
   
}

   function 
__buildForm(){

      
// Referenz auf die Form holen
      
$Form__Kontakt = &$this->__getForm('Kontakt');

      
// Action setzen
      
$Form__Kontakt->setAttribute('action',$_SERVER['REQUEST_URI']);

      
// Button beschriften und formatieren
      
$Config = &$this->__getConfiguration('modules::kontakt4','language');
      
$Button = &$Form__Kontakt->getFormElementByName('KontaktSenden');
      
$Button->setAttribute('value',$Config->getValue($this->__Language,'form.button'));
      
$Button->setAttribute('style',$Config->getValue($this->__Language,'form.button.style'));

      
// Bild in der ValidatorGroup setzen (Auslesen der formconfig)
      
$Config = &$this->__getConfiguration('tools::form::taglib','formconfig');
      
$ValGroup = &$Form__Kontakt->getFormElementByName('FormValGroup');
      
$ValGroup->setPlaceHolder('WarnImage',$Config->getValue($this->__Language,'Contact.Warning.Image'));
      
$ValGroup->setPlaceHolder('WarnText',$Config->getValue($this->__Language,'Contact.Warning.Text'));

      
// Auswahlfeld Person
      
$Recipients = & $Form__Kontakt->getFormElementByName('Empfaenger');

      
// RecipientList laden
      
$cM = &$this->__getServiceObject('modules::kontakt4::biz','contactManager');
      
$RecipientList $cM->loadRecipients();

      for(
$i 0$i count($RecipientList); $i++){
         
$Recipients->addOption($RecipientList[$i]->get('Name'),$RecipientList[$i]->get('oID'));
       
// end if
      
}

      
// Formular transformieren und zur?ckgeben
      
return $Form__Kontakt->transformForm();

    
// end function
   
}

 
// end class
Bei näherer Betrachtung der Klasse kontakt_v4_controller wird deutlich, dass der DocumentController die Komponenten variablenHandler und contactManager verwendet. Die zuerst genannte Klasse ist eine im Framework integrierte Klasse, die für die Extraktion von REQUEST-Variablen verwendet wird und nicht im Request enthaltene Variablen mit Standard-Werten belegen kann. Details zu dieser Komponente können der Klassenreferenz entnommen werden. Die zweite Komponente ist die Business-Schicht des Kontaktformulars. Sie stellt der Präsentations-Schicht eine Schnittstelle zum Laden von Empfängern und Abschicken des Formulars zur Verfügung.


3.4.1. Methode transformContent()
In der Methode transformContent() findet die Generierung der Darstellung statt. Hierzu wird eine Referenz auf das Formular-Objekt geholt und anschließend geprüft, ob das Formular abgeschickt wurde und die Eingaben valide sind. Ist das nicht der Fall, wird der oben erwähnte Platzhalter mit der Formularausgabe gefüllt. Sind die Eingaben valide, so wird ein Form-Daten-Objekt erzeugt und mit Werten gefüllt. Anschließend wird die Business-Komponente mit Hilfe der privaten Methode __getServiceObject() erzeugt und die Methode sendContactForm() mit dem DomainObjekt oFormData als Parameter aufgerufen und das Formular abgesendet. Das Verschicken der Daten per Mail und die Weiterleitung wird dabei von der Businessschicht übernommen.


3.4.2. Methode __buildForm()
Die Funktion __buildForm() wird vom Autor gerne als "Helper-Funktion" bezeichnet, da siese lediglich die Ausgabe des Formulars kapselt. Die Methode übernimmt jedoch drei Aufgaben: Zuerst muss das action-Attribut mit dem für das Modul gültigen URL versehen werden, anschließend wird die Bild-URL für das Warnungs-Symbol der Validator-Gruppe gesetzt und schließlich das Select-Feld mit den Empfängern gefüllt. Weiterhin muss der Button des Formulars noch mit einem sprachabhängigen Wert beschriftet werden.

Setzen des action-Attributes:
Da jedes Objekt von "coreObject" erbt, besitzt dieses - genau wie das Form-Objekt - die Methode setAttribute(). Mit Hilfe dieser Funktion kann damit das Attribut action des Formular-Objektes gesetzt werden.

Konfigurieren der Validator-Gruppe:
Um den Platzhalter "WarnBild" und "WarnText" in der Validator-Gruppe setzen zu können, holt sich der Entwickler zunächst eine Referenz auf dieses Objekt. Im internen DOM ist die Validator-Gruppe ein Kind-Objekt des Formulars. Um eine Referenz auf ein Kind-Element zu bekommen, muss der Entwickler zunächst eine gültige Referenz auf das Formular-Objekt besitzen. Anschließend stehen die Methoden getFormElementByName() und getFormElementByID() zur Verfügung. Die Klasse, die die Funktion der Validator-Gruppe repräsentiert, besitzt gemäß API-Dokumentation die Methode setPlaceHolder(). Mit Hilfe dieser Funktion kann ein Platzhalter der Validator-Gruppe gefüllt werden.

Im Fall des "WarnImage" und "WarnText" werden sprachabhängige Konfigurationsdateien verwendet. Die URL des Warnhinweis-Bildes und der zugehörige Text befinden sich dabei in der Konfigurationsdatei
  /config/tools/form/taglib/{CONTEXT}/{ENVIRONMENT}_formconfig.ini
unter der Sektion [de] (für deutsche Sprache) und dem Schlüssel
  Contact.Warning.Image
Um einen sprachabhängigen Wert aus der Konfiguration zu lesen wird die Sektion über die interne Membervariable $this->__Language gesteuert, die je nach gewählter Sprache den entsprechenden zweistelligen ISO-Ländercode beinhaltet, der als Titel für die Sprachsektion in der Konfigurationsdatei gewählt wurde. Im vorliegenden DocumentController wird das Füllen der beiden Platzhalter per
   $Config = &$this->__getConfiguration('tools::form::taglib','formconfig');
   
$ValGroup = &$Form__Kontakt->getFormElementByName('FormValGroup');
   
$ValGroup->setPlaceHolder('WarnImage',$Config->getValue($this->__Language,'Contact.Warning.Image'));
   
$ValGroup->setPlaceHolder('WarnText',$Config->getValue($this->__Language,'Contact.Warning.Text')); 
erledigt.

Zum Schluss der Methode wird das Formular transformiert und an die aufrufende Methode zurückgegeben.


3.5. Klasse contactManager

Die Klasse contactManager ist eine Implementierung der Business-Schicht. Sie kapselt die eigentliche Geschäfts-Logik der Anwendung und kommuniziert mit weiter unten liegenden Schichten (Daten-Schicht oder weitere Treiber-Schichten). Im Fall des Kontakt-Formulars wird in der Business-Schicht das Formular abgesendet oder Empfängerdaten geladen. Dazu stehen der Präsentations-Schicht zwei öffentliche Methoden zur Verfügung: sendContactForm() um ein Formular abzusenden und loadRecipients() um Empfänger zu laden. Die Schnittstelle zwischen diesen beiden Schichten bilden die Domain-Objekte oFormData und oRecipient.
import('modules::kontakt4::biz','oFormData');
import('modules::kontakt4::biz','oRecipient');
import('modules::kontakt4::data','contactMapper');
import('tools::mail','mailSender');
import('tools::link','linkHandler');

class 
contactManager extends coreObject
{

   function 
contactManager(){
   }

   function 
sendContactForm($oFD){

      
// contactMapper holen
      
$cM = &$this->__getServiceObject('modules::kontakt4::data','contactMapper');


      
// E-Mail fuer Empfaenger aufsetzen
      
$MAIL = &$this->__getAndInitServiceObject('tools::mail','mailSender','Kontaktformular');


      
// Empfaenger setzen
      
$Recipient $cM->loadRecipientPerId($oFD->get('RecipientID'));
      
$MAIL->setRecipient($Recipient->get('Adresse'),$Recipient->get('Name'));

      
// Text einsetzen
      
$Text 'Sehr geehrter Empf?nger, sehr geehrte Empf?ngerin,';
      
$Text .= "\n\n";
      
$Text .= $oFD->get('SenderName').' (E-Mail: '.$oFD->get('SenderEMail').') hat Ihnen folgende Nachricht ?ber das Kontaktformular zukommen lassen:';
      
$Text .= "\n\n\n";
      
$Text .= $oFD->get('Text');
      
$MAIL->setContent($Text);

      
// Betreff setzen
      
$MAIL->setSubject($oFD->get('Subject'));

      
// Mail senden
      
$MAIL->sendMail();


      
// E-Mail fuer Absender aufsetzen
      
$MAIL->clearRecipients();
      
$MAIL->clearCCRecipients();
      
$MAIL->clearContent();

      
// Empfaenger setzen
      
$MAIL->setRecipient($oFD->get('SenderEMail'),$oFD->get('SenderName'));

      
// Text einsetzen
      
$Text 'Sehr geehrter Empf?nger, sehr geehrte Empf?ngerin,';
      
$Text .= "\n\n";
      
$Text .= 'Ihre Anfrage wurde an die Kontaktperson "'.$Recipient->get('Name').'" weitergeleitet. Wir setzen uns baldm?glich mit Ihnen in Verbindung!';
      
$Text .= "\n\n";
      
$Text .= 'Hier nochmals Ihr Anfragetext:';
      
$Text .= "\n";
      
$Text .= $oFD->get('Text');
      
$MAIL->setContent($Text);

      
// Betreff setzen
      
$MAIL->setSubject($oFD->get('Subject'));

      
// Mail senden
      
$MAIL->sendMail();


      
// Bestaetigungsseite anzeigen
      
$Link linkHandler::generateLink($_SERVER['REQUEST_URI'],array('pagepart' => 'meldung'));

      
$Reg = &Singleton::getInstance('Registry');
      
$URLRewriting $Reg->retrieve('apf::core','URLRewriting');

      if(
$URLRewriting != true){
         
$Link str_replace('&amp;','&',$Link);
       
// end if
      
}

      
header('Location: '.$Link);

    
// end function
   
}

   function 
loadRecipients(){
      
$cM = & $this->__getServiceObject('modules::kontakt4::data','contactMapper');
      return 
$cM->loadRecipients();
    
// end function
   
}

 
// end class
In den ersten beiden Zeilen werden wiederum Komponenten aus dem Framework eingebunden, die später für den Mailversand (mailSender)und das Generieren von Links (linkHandler) verwendet werden.
In der Methode sendContactForm() werden zwei ServiceObjekte initialisiert, die für den Versand notwendig sind: die Datenschicht um das ausgewählte Empfänger-Objekt zu laden und der mailSender um die Bestätigungs- und Benachrichtigungs-Mails zu versenden.
Die Methode loadRecipients() ist der Service für die Präsentationsschicht, die die Empfänger-Objekte läd.


4. Klasse contactMapper

Die Klasse contactMapper ist eine Implementierung des DataMapper-Patterns und dient der Business-Schicht um Daten aus der Empfänger-Konfigurationsdatei in Form von Domain-Objekten zur Verfügung zu stellen. Dazu läd der Mapper die Daten zunächst mit Hilfe der Funktion __getConfiguration() aus der Konfigurations-Datei und mappt dies anschließend in Empfänger-Domänen-Objekte (oRecipient).
import('modules::kontakt4::biz','oFormData');
import('modules::kontakt4::biz','oRecipient');

class 
contactMapper extends coreObject
{

   function 
contactMapper(){
   }

   function 
loadRecipients(){

      
// read config
      
$Config $this->__getConfiguration('modules::kontakt4','empfaenger');


      
// read relevant section
      
$Sections $Config->getConfiguration();


      
// initialize return array
      
$Recipients = array();


      
// parse config and generate recipients
      
foreach($Config->getConfiguration() as $Key => $Values){

         
$Count count($Recipients);
         
$Recipients[$Count] = new oRecipient();

         
// id
         
preg_match("/Kontakt ([0-9]+)/i",$Key,$Matches);
         
$Recipients[$Count]->set('oID',$Matches[1]);

         
// name
         
$Recipients[$Count]->set('Name',$Values['EmpfaengerName']);

         
// email
         
$Recipients[$Count]->set('Adresse',$Values['EmpfaengerAdresse']);

       
// end foreach
      
}


      
// return recipient list
      
return $Recipients;

    
// end function
   
}

   function 
loadRecipientPerId($Id){

      
$Rec $this->loadRecipients();

      if(!
is_array($Rec)){
         return array();
       
// end if
      
}
      else{

         for(
$i 0$i count($Rec); $i++){
            if(
$Rec[$i]->get('oID') == $Id){
               return 
$Rec[$i];
             
// end if
            
}
          
// end for
         
}

       
// end else
      
}

    
// end function
   
}

 
// end class
Die Konfigurationsdatei selbst ist mit mehreren Sektionen der Form
[Kontakt ([0-9]+)]
EmpfaengerName = "([A-Za-z0-9,.-_ ]+)"
EmpfaengerAdresse = "([A-Za-z0-9.-_@]+)"
aufgebaut. Die Methode loadRecipients() mappt dabei jede Sektion in ein Domain-Objekt (oRecipient) und liefert eine Liste dieser zurück. Jeder Empfänger kann beim Versenden des Formulars an Hand seiner eindeutigen ID (siehe Sektionsnamen) referenziert und per loadRecipientById() geladen werden.
Wird als Quelle keine Konfigurations-Datei, sondern eine Datenbank verwendet, muss lediglich die Implementierungen der Daten-Schicht-Methoden dahin geändert werden, dass die Daten aus der Datenbank statt aus der Datei gelesen werden.


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.

«   1   »
Einträge/Seite: | 5 | 10 | 15 | 20 |

1 Christian
12.10.2008, 23:12:17
Hallo Reiner,

aktuell wird keine Prüfung unternommen, von welchem Server das Formular abgeschickt wird. Lediglich ein Bild-CAPTCHA schützt das Formular, was letztlich einen ähnlichen Effekt hat.

Wie würdest du eine derartige Prüfung implementieren? Wollen wir im Forum weiter diskutieren?

Viele Grüße,
Christian

2 Reiner Rottmann
18.08.2008, 14:32:39
Unterstützt das Formular auch eine Verifizierung, dass Anfragen nur vom Webserver und keinen anderen Seiten kommen dürfen? Bei der Auswahl eines Webformulars ist es imho besonders wichtig, dass dieses nicht für Spam verwendet werden kann...

Powered by WebRing.