TYPO3 / Extbase: Validierung von Unterobjekten deaktivieren

Hallo und ein frohes neues Jahr euch allen! (Bitte nicht aufs Datum gucken)

Endlich komm ich mal wieder dazu einen Artikel zu schreiben der mir schon lange in den Fingern juckt.
Und zwar wurden wir im vergangenen Jahr immer wieder mit der schlechten Performance von Extbase (unter 6.2) konfrontiert. Umso mehr Datensätze man hat, welche wiederum Relationen haben, desto länger braucht Extbase zur Verarbeitung von Actions.

Man stelle sich hierzu in einem Zeiterfassung die Erstellung / Anzeige einer Buchung bzw. eines „Postens“ vor, welche eine Relation zu einem Kunden hat, welcher nochmal Relationen zu hunderten anderen Datensätzen hat. In diesem Fall kann man spürbar merken, wie sich der Seitenaufbau in die Länge zieht.

Das Problem betrifft nicht nur die Erstellung / Bearbeitung von Datensätzen über das Frontend, sondern in der Regel auch die showAction von Datensätzen.

Die Ursache für das Problem ist die Validierung von Unterobjekten durch Extbase, welche in der Regel kein Unterobjekt bei der Validierung auslässt. Selbst durch Annotationen wie „ignorevalidation“ oder alt „dontvalidate“ wird das Problem nicht gelöst, man erhält lediglich keine Fehlermeldungen bei Validierungsfehlern – die Validierung wird aber dennoch durchgeführt. Die Validierung von Unterobjekten kann sowieso häufig zu Problemen führen.

Um das Problem zu lösen muss man einen Blick in seinen Controller werfen. Gucken wir uns hierzu eine ganz simple showAction an, in der dieses Problem zum Beispiel auftaucht:

/**
 * action show
 * @param \TYPO3\TgmZeiterfassung\Domain\Model\Posten $posten
 * @return void
 */
public function showAction(\TYPO3\TgmZeiterfassung\Domain\Model\Posten $posten) {
	$this->view->assign('posten', $posten);
}

Obwohl man es nicht denken würde, findet hierbei selbst in der showAction eine Validierung inkl. aller Unterobjekte statt! Warum? Alleine durch die Deklaration des Parameters als das dazugehörige Model löst die Validierung aus.
Eine einfache Lösung in der showAction wäre es den Parameter nicht mehr als Model auszuweisen sondern einfach als Integer. Anschließend kann man sich über das Repository über die UID das Objekt holen – hierbei findet keine Validierung von diesem Ausmaß statt. Beispiel:

/**
 * action show
 * @param integer $posten
 * @return void
 */
public function showAction($posten) {
    $posten = $this->postenRepository->findByUid($posten);
    $this->view->assign('posten', $posten);
}

Die eben genannte Lösung ist möglich, aber noch nicht besonders elegant. Außerdem funktioniert sie nur für die showAction. Bei der Bearbeitung oder Erstellung von Datensätzen muss ein vollständiges Objekt an die jeweiligen Action übergeben werden.

Die bessere Variante orientiert sich an unserem Artikel bzgl. der dynamischen Validierung bei Extbase Objekten. Per initializeActions kann man die Validierung von allen Objekten verändern und so natürlich auch verhindern, dass Unterobjekte validiert werden.

Beispiel: Validierung für die createAction unterbinden:

public function initializeCreateAction() {
	if ($this->arguments->hasArgument('newPosten')) {
		/** @var \TYPO3\CMS\Extbase\Validation\Validator\ConjunctionValidator */
		$conjunctionValidator = $this->arguments->getArgument('newPosten')->getValidator();
		// Alle alten Validatoren entfernen
		foreach ($conjunctionValidator->getValidators() as $validator) {
			$conjunctionValidator->removeValidator($validator);
		}
	}
}

Das Beispiel entfernt jedoch alle Validatoren von dem Objekt. Dies betrifft also auch Eigenschaften des Objekts, die wir vielleicht durch Extbase validieren lassen wollen. In unserem Projekt findet die Validierung jedoch per Javascript statt, weshalb wir alle Validatoren entfernen können. Um spezielle Unterobjekte von der Validierung auszuschließen, könnt ihr innerhalb des foreach prüfen welcher Validator momentan dran ist und diesen nur entfernen wenn es sich um einen Validator für ein Unterobjekt handelt.

Thats it.

2 Kommentare

Schreibe einen Kommentar zu jokumer Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Highlighting von Codes ist mit den Tags  [ts], [php], [html], [javascript], [xml] oder [code] möglich.