Formulare
Evtl. fragt ihr euch warum für jedes Formelement ein eigener ViewHelper programmiert wurde? Na ich denke, weil man sich damit erstens Zeit spart (Dank der Property-Eigenschaft) und zweitens Fehler reduzieren kann (Dank der Property-Eigenschaft). Spielen wir mal ein paar Beispiele durch:
Beispiel: Ohne Fluid
Wenn wir ohne TYPO3 bzw. ohne CMS ein einfaches Formular programmieren würden, dann könnte ein Eingabefeld in etwa so aussehen:
<input type="text" name="autoMarke" />
Innerhalb der Programmierung würden wir dann mit $_POST
oder ähnlichem wieder auf diesen Wert nach dem Absenden zugreifen. Im Falle von TYPO3 wird mit der TYPO3-API auf die Formulardaten zugegriffen:
$marke = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('autoMarke');
Aber egal wie, um die Sicherheit habt ihr euch selbst zu kümmern. Ihr müsst selbst prüfen, ob es sich um einen Text, eine Zahl oder booleschen Wert handelt.
Beispiel: Formulare mit Actions
Wer jetzt schonmal Extensions auf piBase
Basis programmiert hat erinnert sich evtl. noch an $this->piVars
. In diesem Array waren alle GET/POST-Variablen enthalten, die nur für diese eine Extension gültig waren. Bei Extbase geht dieser Schritt noch ein bisschen weiter. Hier wird nun sogar zwischen den jeweiligen Plugins unterschieden. Folgendes Formularfeld als Beispiel:
<input type="text" name="tx_sffluid_sffluid[autoMarke]" />
Das name
Attribut gibt an für welche Extension (das erste sffluid
) bzw. welches Plugin (das zweite sffluid
) der enthaltene Wert verfügbar gemacht werden soll. Wenn wir dieses Formular nun abschicken, können wir mit allen Actions der Extension sffluid
in dem Plugin sffluid
auf dieses Formularfeld zugreifen:
public function createAction(string $autoMarke) {
\TYPO3\CMS\Core\Utility\DebugUtility::debug($autoMarke, 'marke');
die('Ende');
}
Kein $_POST
, kein $_GET
und keine Verwendung irgendwelcher TYPO3 API. Das macht alles Extbase für uns, solange wir uns an die exakte Namensgebung halten. Ein Rechtschreibfehler im name
Attribut des Formularfeldes resultiert hier in diesem Beispiel in eine leere Ausgabe.
Beispiel: Formulare mit Extbase (Array)
Auch wenn das Actionbeispiel funktioniert, so setzt Extbase noch einen obendrauf. Denn was wäre, wenn wir ein großes Formular mit 30, 40 oder sogar 50 Formularfeldern hätten? Dann müssten wir auch die Action entsprechend erweitern und 50 Parameter übergeben. Das wäre eine ewig lange und vor allem unübersichtliche Action.
Bei Extbase gehört immer alles irgendwie zusammen und so wollen wir natürlich nicht nur unsere autoMarke
versenden, sondern mehrere Daten, die ein Auto betreffen. Also erstellt man sich ein Model, das z.B. Auto
heißt und vergibt diesem unter anderem die Eigenschaft marke
und schon könnte unser Formular folgendermaßen aussehen:
<input type="text" name="tx_sffluid_sffluid[auto][marke]">
<input type="text" name="tx_sffluid_sffluid[auto][farbe]">
<input type="text" name="tx_sffluid_sffluid[auto][ps]">
Und der Aufruf innerhalb der Action wird auch eine ganze Ecke kürzer:
public function createAction(array $auto) {
\TYPO3\CMS\Core\Utility\DebugUtility::debug($auto, 'auto');
die('Ende');
}
Beispiel: Formulare mit Extbase (Objekt)
Wenn wir mit Objekten arbeiten, können wir uns einiges an Schreibarbeit sparen und die Sache mit den name
Attributen ist eine ganze Ecke weniger fehleranfällig. In unserem f:form
ViewHelper geben wir mithilfe des name
Attributes an, wie unser Objekt heißen soll. Bei diesem Objektnamen handelt es sich später um den Variablennamen (Parameter) der an die aufgerufene Action übergeben wird. Also bitte keine Leerzeichen oder sowas.
Wenn wir unserem Template ein Objekt übergeben haben, dann können wir dieses Objekt mit dem f:form
ViewHelper verknüpfen. In diesem besonderen Fall stehen uns nun die property
Attribute zur Verfügung, die uns die Arbeit abnehmen das name
Attribut richtig zu setzen. Das Ergebnis ist das Gleiche wie aus dem oberen Array-Beispiel.
<f:form action="create" name="auto" object="{auto}">
<f:form.textfield property="marke"/><br>
<f:form.textfield property="farbe"/><br>
<f:form.textfield property="ps"/><br>
<f:form.submit value="Erstellen"/>
</f:form>
Nach Absenden des Formulars erhalten wir auch hier erstmal wieder ein Array, wenn uns Extbase nicht zuvorkommen würde:
public function createAction(\SFroemken\Sffluid\Domain\Model\Auto $auto) {
\TYPO3\CMS\Core\Utility\DebugUtility::debug($auto->getMarke(), 'Marke');
\TYPO3\CMS\Core\Utility\DebugUtility::debug($auto->getFarbe(), 'Farbe');
die('Ende');
}
Extbase liest vor dem Aufruf einer jeden Action die Parameter der aufzurufenden Action aus und kann somit den Typen der Variable ermitteln. Im vorherigen Beispiel hatte ich array
vor den Parameter geschrieben und konnte innerhalb der Action wie mit einem Array auf die Inhalte zugreifen. Hier in diesem Beispiel steht nun aber der Typ \SFroemken\Sffluid\Domain\Model\Auto vor dem Parameter. Extbase prüft, ob es eine Klasse mit diesem Typennamen gibt und versucht alle Werte des Arrays in das Model zu übertragen. Dabei muss der Schlüsselname eines Arrays mit dem Namen der Eigenschaft aus dem Model übereinstimmen. Wenn nicht, dann wird der Wert nicht mit in das Model aufgenommen.