Formulare, Parameter und Eingaben - Typo3: Extension selbst erstellen

Formulare, Parameter und Eingaben - Typo3: Extension selbst erstellen
Von Lars Ebert am 16.04.12, 13:00
Kategorien: Content Management Systeme, PHP, Programmieren, Tutorials and Typo3

Seit meinem letzten Artikel kannst du einfaches »Hello World«-Frontend-Plugin für Typo3 programmieren. Als nächstes werde ich dir zeigen, wie man ein etwas komplexeres Plugin entwickelt. Am Ende dieses Artikels wirst du in deinen Plugins Formulare und POST- und GET-Variablen verarbeiten können und aus Typo3 heraus Mails verschicken können. Zudem hast du dann die Basis für dein eigenes Kontaktformular-Plugin, dass du später beliebig erweitern und in deinen eigenen Projekten verwenden kannst.

Artikelserie: Typo3: Extension selbst erstellen

Dieser Artikel ist Teil einer mehrteiligen Artikelserie. Lies dir auch die restlichen Teile durch!

  1. Kickstarter, Grundlagen & Hallo Welt - Typo3: Extension selbst erstellen
  2. Formulare, Parameter und Eingaben - Typo3: Extension selbst erstellen
  3. Templates, CSS und TypoScript - Typo3: Extension selbst erstellen
  4. Lokalisierung und FlexForms - Typo3: Extension selbst erstellen
  5. Planung, Dokumentation und Veröffentlichung – Typo3: Extension selbst erstellen

Schritt 1: Mit dem Kickstarter fängt alles an

Wie schon im ersten Teil der Artikelserie benutzen wir zum Erstellen der Erweiterung den Kickstarter. Zur Erinnerung: Wir finden den Kickstarter im Erweiterungs-Manager, wenn wir oben »Neue Erweiterung erstellen« auswählen.

Im Gegensatz zu unserem ersten »Projekt« geben wir diesmal einen sinnvollen Erweiterungsschlüssel ein, denn vielleicht wollen wir später die Erweiterung doch noch irgendwo veröffentlichen.

Zuerst registrieren wir uns dafür auf typo3.org und melden im Extension Repository eine Extension an. Ein sinnvoller Name wäre zum Beispiel eine Kombination aus deinem Namen und der Funktion der Extension. Ich könnte zum Beispiel meine Extension »le_contactform« nennen, jeder könnte sofort erkennen, dass es sich bei der Extension um ein Kontaktformular handelt und durch meine Initialien ist der Schlüssel vermutlich noch nicht belegt.

Nachdem wir den Schlüssel registriert haben, tragen wir ihn im Kickstarter ein. Unter »General info« füllen wir ein paar Informationen über die Extension ein.

Ich habe unter »General info« ein paar Informationen über die Extension abgelegt.
So sehen meine Infos aus, aber deine Infos können natürlich davon abweichen!

Ist das geschehen, müssen wir als nächstes ein Frontend Plugin anlegen. Als Titel verwenden wir am besten etwas griffiges wie »Contact form« oder so ähnlich. Wieder wählen wir »Add to 'Insert Plugin' list in Content Elements« aus und setzen den Haken bei »Add icon to 'New Contenten Element' wizard«, damit das Plugin in der Inhaltselemente-Liste erscheint. Gib auch eine sinnvolle Beschreibung wie zum Beispiel »Adds a contact form to the page.« Nach dem Klick auf »Update…« können wir unter »View result« mit einem Klick auf »WRITE« die neue Extension anlegen. Dann importieren und installieren wir die neue Erweiterung.

Nun fügen wir noch schnell eine neue Seite namens »Kontakt« in die Webseite ein und platzieren dort das eben erstellte Contact-form-Plugin, damit wir auch sehen was wir tun.

Schritt 2: das Formular

Nachdem wir nun das Plugin in unsere Seite eingebettet haben, sehen wir mal wieder den ominösen Beispiel-Inhalt, den der Kickstarter immer einbaut. Diesen müssen wir jetzt durch das Kontaktformular ersetzen. Wie wir im letzten Teil gelernt haben, können wir das in der Datei pi1/class.tx_lecontactform_pi1.php. Wir kommentieren also die Zeilen 59 bis 71 aus, und fügen danach unseren eigenen Inhalt in die Variable $content ein.


$content = '
	<form action="' . $this->pi_getPageLink($GLOBALS['TSFE']->id) . '" method="POST">
	
	</form>
';

In Zeile 74 ermitteln wir mit der Methode pi_getPageLink, mit der wir die URL einer beliebigen Seite bekommen, die URL der aktuellen Seite. So landen die Nutzerangaben hinterher wieder auf der Seite, sodass das Plugin sie auswerten kann.

Als nächstes fügen wir die nötigen Eingabefelder für das Kontaktformular ein.


<form action="' . $this->pi_getPageLink($GLOBALS['TSFE']->id) . '" method="POST">
	<p>
		<label for="' . $this->prefixId . '_sender_name">Name:</label>
		<input type="text" id="' . $this->prefixId . '_sender_name" name="' . $this->prefixId . '[sender_name]" placeholder="Ihr Name" required="required" />
	</p>
	<p>
		<label for="' . $this->prefixId . '_sender_mail">E-Mail:</label>
		<input type="email" id="' . $this->prefixId . '_sender_mail" name="' . $this->prefixId . '[sender_mail]" placeholder="Ihre Mail-Adresse" required="required" />
	</p>
	<p>
		<label for="' . $this->prefixId . '_message">Nachricht:</label>
		<textarea id="' . $this->prefixId . '_message" name="' . $this->prefixId . '[message]" placeholder="Geben Sie hier Ihre Nachricht an uns ein!" required="required"></textarea>
	</p>
	<p>
		<input type="submit" name="' . $this->prefixId . '[send_message]" value="Nachricht versenden" />
	</p>
</form>

Bei der Vergabe der Namen müssen wir darauf achten, dass wir immer nach dem Muster le_contactform[NAME] vorgehen. Durch diese Schreibweise landen hinterher alle Parameter für dieses Plugin in dem Array $_POSt['le_contactform'] und die Schlüssel entsprechen den Namen der Variablen. In der Plugin-Datei haben wir Typo3 in Zeile 55 mit der Methode pi_setPiVarDefaults() genau diese Parameter ausgelesen, sodass wir diese später zum Beispiel mit $this->piVars['sender_name'] abrufen können.

Die Formularfelder sind alle da, das Design aber noch nicht.
Noch sieht das Kontaktforumlar nicht toll aus, aber das kommt später!

Schritt 3: Validieren, absenden und Meldung machen

Einen wichtigen (Teil-)Schritt, das Validieren, nimmt uns seit HTML5 der Browser schon ab. Wenn ein Nutzer ein mit required="required" als Pflichtfeld markiertes Feld nicht ausfüllt, bekommt er sofort eine Fehlermeldung und das Formular wird nicht abgesendet. Doch leider reicht das als Validierung nicht aus, denn zum einen unterstützen noch nicht alle Browser HTML5 und zum anderen gibt es immer noch künstliche Aufrufe durch Spambots und gelangweilte Hacker, wobei die Validierung durch den Browser natürlich auch nicht greift. Deshalb bauen wir jetzt zumindest einen einfachen Schutz ein, der dafür sorgt, dass zumindest alle Felder ausgefüllt sind.


$errors = array();
$message = '';
$class = '';
if(isset($this->piVars['send_message'])) {
	if(!isset($this->piVars['sender_name']) || trim($this->piVars['sender_name']) == '') {
		$errors['sender_name'] = 'Bitte geben Sie Ihren Namen ein!';
	}
	if(!isset($this->piVars['sender_mail']) || trim($this->piVars['sender_mail']) == '') {
		$errors['sender_mail'] = 'Bitte geben Sie Ihre Mail-Adresse ein. Wie sollen wir Ihnen denn sonst antworten?';
	}
	if(!isset($this->piVars['message']) || trim($this->piVars['message']) == '') {
		$errors['message'] = 'Haben Sie uns denn gar nichts zu sagen? Bitte geben Sie doch eine Nachricht an uns ein!';
	}
	
	if(count($errors) == 0) {
		//	Absenden der Nachricht
		
		$message = 'Ihre Nachricht wurde erfolgreich versandt. Danke! Wir werden uns schnellstmöglich mit Ihnen in Verbindung setzen.';
		$class = 'success';
	}
	else {
		$message = 'Die Nachricht konnte nicht abgesendet werden. Bitte überprüfen Sie Ihre Eingaben!';
		$class = 'error';
	}
}

Für jedes nicht ausgefüllte Feld schreibe ich in das Errors-Array einen Fehler. Wenn am Ende der Validierung keine Fehler vorliegen, kann die Nachricht getrost abgesendet werden, ansonsten wird eine Fehlermeldung generiert. Die ganzen Fehler-Variablen müssen wir jetzt nur noch im Formular selbst ausgeben. Dazu habe ich mir eine kleine Funktion geschrieben, die die Nachricht mit beliebigem Text umgibt, aber eben nur, wenn die Nachricht nicht leer ist.


function wrapMessage($message, $prefix, $suffix) {
	if(trim($message) != '') {
		return $prefix . $message . $suffix;
	}
	else {
		return '';
	}
}

Diese Funktion wenden wir nun an, um die gerade generierten Fehlermeldungen auszugeben.


$content = '
	<form action="' . $this->pi_getPageLink($GLOBALS['TSFE']->id) . '" method="POST">
		' . $this->wrapMessage($message, '<div class="' . $class . '">', '</div>') . '
		<p>
			<label for="' . $this->prefixId . '_sender_name">Name:</label>
			<input type="text" id="' . $this->prefixId . '_sender_name" name="' . $this->prefixId . '[sender_name]" placeholder="Ihr Name" required="required" value="' . htmlspecialchars($this->piVars['sender_name']) . '" />
			' . $this->wrapMessage($errors['sender_name'], '<div class="error">', '</div>') . '
		</p>
		<p>
			<label for="' . $this->prefixId . '_sender_mail">E-Mail:</label>
			<input type="email" id="' . $this->prefixId . '_sender_mail" name="' . $this->prefixId . '[sender_mail]" placeholder="Ihre Mail-Adresse" required="required" value="' . htmlspecialchars($this->piVars['sender_mail']) . '" />
			' . $this->wrapMessage($errors['sender_mail'], '<div class="error">', '</div>') . '
		</p>
		<p>
			<label for="' . $this->prefixId . '_message">Nachricht:</label>
			<textarea id="' . $this->prefixId . '_message" name="' . $this->prefixId . '[message]" placeholder="Geben Sie hier Ihre Nachricht an uns ein!" required="required">' . htmlspecialchars($this->piVars['message']) . '</textarea>
			' . $this->wrapMessage($errors['message'], '<div class="error">', '</div>') . '
		</p>
		<p>
			<input type="submit" name="' . $this->prefixId . '[send_message]" value="Nachricht versenden" />
		</p>
	</form>
';
Unter allen Feldern steht eine Fehlermeldung
Wird das Formular leer ausgefüllt oder fehlen einzelne Angaben, werden entsprechende Fehlermeldungen ausgegeben. Das Design folgt später!

Nun fehlen lediglich noch die entscheidendsten Zeilen, nämlich das Absenden der Daten per Mail an wen auch immer. Dies bewerkstelligen wir mit der PHP-Funktion mail().


if(count($errors) == 0) {
	$subject = '=?UTF-8?B?' . base64_encode(utf8_encode('Kontaktanfrage von ' . htmlspecialchars($this->piVars['sender_name']))) . '?=';
	
	$header = "From:" . htmlspecialchars($this->piVars['sender_mail']) . "\nContent-Type:text/plain; charset=utf-8\nContent-Transfer-Encoding: 8bit\n";
	
	@mail('//Deine Mail-Adresse hier//', $subject, $this->piVars['message'], $header);
	
	$message = 'Ihre Nachricht wurde erfolgreich versandt. Danke! Wir werden uns schnellstmöglich mit Ihnen in Verbindung setzen.';
	$class = 'message';
}

Unser Kontaktforumlar funktioniert jetzt im Grunde schon. Nur fehlen noch ein paar Kleinigkeiten, zum Beispiel das Design. Aber darum kümmern wir uns im nächsten Teil der Artikelserie.

Nächster Artikel der Serie

Dieser Artikel ist Teil der Artikelserie »Typo3: Extension selbst erstellen«.

Hier geht es zum nächsten Artikel der Serie: Templates, CSS und TypoScript - Typo3: Extension selbst erstellen