Direkt zur Hauptnavigation springen Direkt zum Inhalt springen
Alle Beiträge

TYPO3, Extbase: Formulardaten manuell validieren

Nicht jedes Feld eines Formulars gehört zu einem Modell. Ein Häkchen „Ich habe die Bedingungen gelesen“ etwa: Es soll geprüft werden, ohne dass eine Eigenschaft dafür existiert. Extbase erlaubt das — der Code dafür sieht heute allerdings anders aus als 2015.

Der erste Blick: geht es auch ohne?

Für alles, was als Argument der Aktion ankommt, ist das Attribut der kürzere Weg:

use TYPO3\CMS\Extbase\Attribute\Validate;
#[Validate(validator: 'NotEmpty')]
#[Validate(validator: 'Boolean', options: ['is' => true])]
public function speichernAction(bool $bedingungenAkzeptiert): ResponseInterface
{
    // ...
}

Wichtig für alle, die von einer älteren Installation kommen: TYPO3 14 wertet Annotationen in Kommentaren nicht mehr aus. Aus @Extbase\Validate("NotEmpty") im Docblock wird ein echtes PHP-Attribut, und die Klassen dafür liegen nun unter TYPO3\CMS\Extbase\Attribute.

Von Hand prüfen

Bleibt der Fall, dass der Wert kein Argument ist, sondern aus der Anfrage kommt. Dann werden die Validatoren einzeln erzeugt und zusammengesetzt:

$werte = $this->request->getArguments();
$nichtLeer = GeneralUtility::makeInstance(NotEmptyValidator::class);
$nichtLeer->setOptions([]);
$wahr = GeneralUtility::makeInstance(BooleanValidator::class);
$wahr->setOptions(['is' => true]);
$pruefung = GeneralUtility::makeInstance(ConjunctionValidator::class);
$pruefung->setOptions([]);
$pruefung->addValidator($nichtLeer);
$pruefung->addValidator($wahr);
$ergebnis = $pruefung->validate($werte['bedingungenAkzeptiert'] ?? null);
if ($ergebnis->hasErrors()) {
    $this->addFlashMessage(
        LocalizationUtility::translate('must_agree_license_term', 'MeineExtension'),
        '',
        ContextualFeedbackSeverity::ERROR
    );
    return new ForwardResponse('lizenz');
}

Drei Stellen, die alten Code stolpern lassen

  • Kein ObjectManager mehr.$this->objectManager->get(...) gibt es nicht mehr; Objekte kommen über GeneralUtility::makeInstance() oder, besser, über den Konstruktor. Der ValidatorResolver eignet sich dafür nicht: Er ist als @internal markiert und damit kein Teil der öffentlichen Schnittstelle. Die Validator-Klassen direkt zu erzeugen ist der verlässlichere Weg.
  • forward() ist weg. Statt die Methode aufzurufen, gibt die Aktion eine ForwardResponse zurück.
  • FlashMessage::ERROR ist weg. Die Stufe ist heute ein Enum: ContextualFeedbackSeverity::ERROR.

Geprüft mit TYPO3 14.