Zum Inhalt springen

Validierung von DateTime funktioniert nicht (@validate DateTime)

Erstellt am 15. März 2013 · 5 Antworten · letzte Antwort am 16. März 2013

Tags: Frage

semidark ·

Hi,

nach dem ich nun so ziemlich alles durchforstet habe was es zu dem Thema Validierung in Extbase zu lesen gibt muss ich mich nun doch mal an die Community wenden.

Folgendes Problem:

Ich habe ein Domain Model mit reichlich DateTime Eigenschaften. Diese möchte ich nun vorm Speichern validieren lassen.

Dies deklariere ich per Code Annotation wie ich es nun zig mal gelesen habe und auch bereits erfolgreich für den integer Typ eingesetzt habe:

Hier ein kurzer Auszug aus dem Domain Model:

class Tx_TestExt_Domain_Model_Test extends Tx_Extbase_DomainObject_AbstractEntity {

  /**
  * The DateTime property
  *
  * @var DateTime
  * @validate DateTime
  */
  protected $theDate;

  /**
  * The integer property
  *
  * @var integer
  * @validate integer
  */
  protected $theInteger;
}

Die Validierung von integer Werten funktioniert die von DateTime Objekten nicht.

Ich habe bereits alle caches Typo3 deaktiviert, geleert und zu letzt auch den Reflection Cache deaktiviert.

Außerdem habe ich mit der Schreibweise der DateTime validate annotation experimentiert.

- @validate Tx_Extbase_Validation_Validator_DateTimeValidator
- @validate datetime
- @validate DateTimeValidator

Alles ohne Erfolg.

Ich verwende TYPO3 4.5.25 mit extbase 1.3.4. Die verflixte DateTime Validator Klasse gibt es in dieser Version

http://api.typo3.org/typo3cms/45/html/_date_time_validator_8php_source.html

jemand ne Idee warum die einfach nicht greifen will?

Gruß
semidark

semidark ·

habe jetzt mal zum testen meinen eigenen Validator angelegt und der einfachheit halber die isValid Funktion vom Orginal dateTime Validator da rein kopiert:

<?php
class Tx_TestExt_Domain_Model_Test extends Tx_Extbase_Validation_Validator_AbstractValidator {
	
	public function isValid($value) {
		$this->errors = array();
		if ($value instanceof DateTime) return TRUE;
		$this->addError('The given subject was not a valid DateTime. Got: "' .gettype($value) . '"', 1238087674);
		return FALSE;
	}
}
?>

Das ganze dann mal mit dem Debugger angesehen und erstaunliches festgestellt:

Der Validator wird aufgerufen.

Wenn $value in der isValid Funktion des Validators ankommt hat diese wieder den Wert der vor dem bearbeiten des Objekts vergeben war.
Ist somit ein valides DateTime Objekt und wird somit als OK durchgewunken.

Wenn ich mir aber anschaue was der Browser an die updateAktion meines Controllers sendet ist das der fehlerhafte String den ich im HTML Formular eingetragen habe. Irgendwo auf dem weg zum Validator stellt extbase also den Orginalwert der Property wieder her.

Warum? Hab ich einfach nur nen riesen Denkfehler beim Thema Validierung? Ich meine... der Integer Validator verhält sich doch auch so wie man es erwarten würde... Hat es ggf. was damit zu tun das hier ein Objekt und nicht eine simple Variable verarbeitet wird?

Fragen über Fragen... :o

harald1972 ·

Guten Morgen,

also wo ich DateTime verwende, sieht das so aus
/**
* @var DateTime
* @validate NotEmpty
*/

Die Variable ist ein DateTime und darf nicht leer sein.
Weil @var DateTime angegeben ist, wird auch dieser Standardvalidator ausgeführt.
Die Validierung wird dann mit @dontvalidate umgangen (z.B. in der newAction mit $newElement=null)

Wie du sehen kannst, prüft die isValid() auch nur if($value instanceof DateTime).
Was ich jetzt verstanden hab ist, daß du einen fehlerhaften String hast.
DateTime gibt es in mehreren länderspezifischen Formaten. Weil das Format nur mit der Ausgabe und nicht mit der Logik zu tun hat, steckt das in meiner View:

<f:format.date format="d. m. Y">{project.start}</f:format.date>
<f:format.date format="d. m. Y">{project.end}</f:format.date>

Oder zum Vorbelegen eines textfelds:

<f:form.textfield property="start" value="{dateNow->f:format.date(format:'d.m.Y')}" />

Ach, beinah hätt ich's vergessen. DateTime ist sehr tolerant, was du eingeben kannst.
Selbst bei 1-2-3 macht er ein Datum draus. Oder 30-02-12345

Ich hoffe, das hilft irgendwie
Harald

semidark ·

Nur der Vollständigkeit halber...

viel Debugging Arbeit später die Erkentnis: Das muss ein BUG sein in #paralyzed#

und zwar in typo3/sysext/extbase/Classes/Property/Mapper.php

Während des Mapping-Prozesses geht die orginal Value, also die welche der Browser schickt verloren und wird durch den Wert ersetzt den die Object-Property vorher hatte. Damit ist dann auch das verhalten aus meinem Vorherigen Post zu erklären.

Ich eröffne mal einen Bug-Report zu dem Thema.

semidark ·

Hi Harald,

Danke für die Antwort.

ich werde deinen Tipp gleich mal ausprobieren wenn ich den Bug Report geschrieben habe. Soweit ich das sehe könnte die Annotation @validate NotEmpty tasächlich einen Einfluss auf das verhalten haben und als Workaround dienen.

Ich denke immer noch das es ein Bug ist, da ich das verhalten mit dem Auskommentieren der continue; Zeile im Mapper positiv beeinflussen konnte.

DateTime wird im im alten Mapper auf eine Weise behandelt die sonst kein Property Typ abbekommt. Und die folgenden Code finde ich schon halbwegs verdächtig...

<?
if ($targetType === 'DateTime' || is_subclass_of($targetType, 'DateTime')) {
	// TODO replace this with converter implementation of FLOW3
?>

TODO eben 😉

<?
	} elseif ($propertyMetaData['type'] === 'DateTime' || strpos($propertyMetaData['type'], '_') !== FALSE) {
		$propertyValue = $this->transformToObject($propertyValue, $propertyMetaData['type'], $propertyName);
		if ($propertyValue === NULL) {
			continue;
		}
?>

continue? Einfach soo?:o

Ich finde es sogar gut das extbase sehr viel Spielraum lässt was das Datumsformat angeht. Nur wenn ich "ösadjölkasjdölasdöaksdjlk" eintrage möchte ich schon das der Validator es mitbekommt 😉

Gruß
Semidark