Kontaktformular-Tutorial
Diese Seite beinhaltet veraltete Komponenten, die nicht mehr im
Release 1.11 enthalten sind. Die Seite
befindet sich deshalb bis zum Entfernen dieser Meldung in einem Bearbeitungszustand. Sollten
Fragen auftauchen, können diese gerne im
Forum gestellt werden.
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.
Im Release 1.11 wurde das HTML-Markup des Moduls vollständig überarbeitet. Aus diesem
Grund muss bei der Einbindung des Moduls die beiliegende CSS-Datei
(siehe
/modules/kontakt4/pres/css/contact.css im Release-Package)
in den Header der betreffenden Seite eingebunden werden. Diese beinhaltet bereits einen Basis-Satz
an CSS-Definitionen und muss an den jeweiligen Stil der Seite angepasst werden. Eine genaue
Beschreibung kann dem Wiki unter
Kontakt-Formular-Modul
entnommen werden.
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.
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
Code
/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
Code
/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
APF-Template
Bitte geben Sie eine E-Mail-Adresse sein!
erscheinen, wenn das Feld nicht gefüllt wurde und
APF-Template
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:
APF-Template
<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:
APF-Konfiguration
[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!"
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
APF-Template
/config/modules/kontakt4/{CONTEXT}/{ENVIRONMENT}_language.ini
Diese wird mit folgenden Werten gefüllt:
APF-Konfiguration
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Deutsche Texte ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[de]
; Header
header.title = "Kontakt"
; Hinweise zum Formular
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!"
; Formular
form.person = "Person / Gruppe: "
form.name = "Ihr Name:"
form.email = "Ihre E-Mail-Adresse:"
form.subject = "Ihr Betreff:"
form.comment = "Ihre Nachricht:"
form.button = "Senden"
form.captcha = "Bestätigungscode:"
; confirmation text
message.text = "Vielen Danke für Ihre Anfrage. Ich werde mich umgehend mit Ihnen in Verbindung setzen!"
; validation messages
form.name.error = "Bitte füllen Sie das Feld Absender-Name!"
form.email.error = "Bitte geben Sie eine gültige E-Mail-Adresse sein!"
form.subject.error = "Bitte füllen Sie das Feld Betreff!"
form.text.error = "Bitte füllen Sie das Feld Text!"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Englisch texts ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[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.name = "Your name:"
form.email = "Your email address:"
form.subject = "Your subject:"
form.comment = "Your message:"
form.button = "Send"
form.captcha = "Security code:"
; confirmation text
message.text = "Many thanks for your message. We will get in contact with you immediately!"
; validation messages
form.name.error = "Please provide a sender name!"
form.email.error = "Please provide a valid email address!"
form.subject.error = "Please fill the subject field!"
form.text.error = "The message may not be empty!"
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:
PHP-Code
// Sprachabhängige Konfiguration laden
$Config = &$this->__getConfiguration('modules::kontakt4','language');
// Referenz auf das Button-Control holen
$Button = &$Form->getFormElementByName('KontaktSenden');
// Sprachabhängigen Text mit Hilfe von $this->__Language auslesen
$Button->setAttribute('value',$Config->getValue($this->__Language,'form.button'));
Ä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:
APF-Template
/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.
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.
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:
APF-Template
<core:addtaglib namespace="tools::html::taglib" prefix="html" class="getstring" />
<font style="..."><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.
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.
APF-Template
<@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=".."><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="..." 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>
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.
APF-Template
<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.
PHP-Code
import('tools::request','RequestHandler');
import('modules::kontakt4::biz','contactManager');
class kontakt_v4_controller extends baseController {
var $_LOCALS;
function kontakt_v4_controller(){
$this->_LOCALS = RequestHandler::getValues(array('Empfaenger',
'AbsenderName',
'AbsenderAdresse',
'Betreff',
'Text'
)
);
}
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);
}
else{
$this->setPlaceHolder('Inhalt',$this->__buildForm());
}
}
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'));
}
// Formular transformieren und zurückgeben
return $Form__Kontakt->transformForm();
}
}
Bei näherer Betrachtung der Klasse
kontakt_v4_controller wird deutlich, dass der
DocumentController die Komponenten
RequestHandler 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.
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.
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
Code
/config/tools/form/taglib/{CONTEXT}/{ENVIRONMENT}_formconfig.ini
unter der Sektion
[de] (für deutsche Sprache) und dem Schlüssel
APF-Konfiguration
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
PHP-Code
$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.
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.
PHP-Code
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 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('&','&',$Link);
}
header('Location: '.$Link);
}
function loadRecipients(){
$cM = & $this->__getServiceObject('modules::kontakt4::data','contactMapper');
return $cM->loadRecipients();
}
}
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.
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).
PHP-Code
import('modules::kontakt4::biz','oFormData');
import('modules::kontakt4::biz','oRecipient');
class contactMapper extends coreObject {
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']);
}
// return recipient list
return $Recipients;
}
function loadRecipientPerId($Id){
$Rec = $this->loadRecipients();
if(!is_array($Rec)){
return array();
}
else{
for($i = 0; $i < count($Rec); $i++){
if($Rec[$i]->get('oID') == $Id){
return $Rec[$i];
}
}
}
}
}
Die Konfigurationsdatei selbst ist mit mehreren Sektionen der Form
APF-Template
[Kontakt <em>([0-9]+)</em>]
EmpfaengerName = "<em>([A-Za-z0-9,.-_ ]+)</em>"
EmpfaengerAdresse = "<em>([A-Za-z0-9.-_@]+)</em>"
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
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...
2
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