[Frage] DateTime in Extbase 6.1

  • hauke_ hauke_
    T3PO
    0 x
    9 Beiträge
    0 Hilfreiche Beiträge
    16. 10. 2013, 11:21

    Hallo Leidensgenossen!
    Ich versuche unter 6.1 ein einfaches DateTime Feld sauber abzubilden. D.h. im Model als

    1. /**
    2.  * dateOfBirth
    3.  *
    4.  * @var \DateTime
    5.  * @validate NotEmpty
    6.  */
    7. protected $dateOfBirth;

    und im Fluid als

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

    Zusätzlich eine Type Conversation im Controller

    1. /**
    2. * Action-Unabhaengige Inits
    3. * @return void
    4. */
    5. public function initializeAction() {
    6. //DATE TIME "dateOfBirth" muss für den Property mapper konvertiert werden ... string > DATE TIME
    7.  
    8. if (isset($this->arguments['client'])) {
    9. $this->arguments['client']
    10. ->getPropertyMappingConfiguration()
    11. ->forProperty('dateOfBirth')
    12. ->setTypeConverterOption('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\DateTimeConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT, 'd.m.Y');
    13. }
    14. }

    Alles schön im gut - wenn der Client schon besteht (edit/update). Beim neu Anlegen (new/create)- und einem validate Fehler im Formular (Name leer) - wird das eingegebene Datum gelöscht. Doof.

    Test Sources auf github:

    https://github.com/netfeld/t3

    Hat jemand eine Idee?

    Gruß, Hauke


  • 1
  • frohike frohike
    T3PO
    0 x
    18 Beiträge
    0 Hilfreiche Beiträge
    22. 01. 2014, 14:41

    Beim Erstellen heißt das Objekt nicht "client" sondern "newClient". Oder wie auch immer Du Dein Model benannt hast. Vergleiche den form name: <f:form name="newClient" ...> in New.html
    z.B.:
    $this->arguments['newClient']

    Quelle: http://www.ausgebloggt.de/2013/10/23/extbase-6-1-datetime-format-anpassen/

    Funktioniert jetzt bei mir, nur mit Uhrzeiten (ohne Datum) hab ich noch ein Problem. Aber das ist ein anderer Thread.

  • hauke_ hauke_
    T3PO
    0 x
    9 Beiträge
    0 Hilfreiche Beiträge
    22. 01. 2014, 16:10

    Hallo Frohike,
    danke für deine Antwort.

    Ich nutze halt überall nur client - nicht newClient.

    D.h.

    1. public function createAction(\Netfeld\Test\Domain\Model\Client $client) {

    als auch im Template

    1. <f:form action="create" name="client" object="{client}">

    Das soll dann trotzdem als

    1. $this->arguments['newClient']
    übergeben werden? Sehr merkwürdig.

    Also bei dir geht tatsächlich:

    1) neues Objekt 2) Fehlerhafte Eingabe (z.B. fehlendes req.) 3) Wiederanzeige mit korrektem Datum?

    Das wäre ja einfach...

    Beste Grüße, Hauke

  • frohike frohike
    T3PO
    0 x
    18 Beiträge
    0 Hilfreiche Beiträge
    22. 01. 2014, 18:06

    Da hab ich wohl was missverstanden. Wenn Du das "new" weggenommen hast (der extension_builder erzeugt das Prefix) dann ist meine vorige Antwort irrelevant. Jetzt stehe ich vor genau dem gleichen Problem wie Du.

    Was ich herausgefunden habe: wenn man einen expliziten value angibt, so gibt das das von Dir beschriebene Fehlverhalten. Bei einem Validierungsfehler beim Anlegen wird das Datumsfeld wieder leer angezeigt (falsch).

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

    Beim Bearbeiten des Datensatzes wird das Datum erst korrekt angezeigt, bei einem Validierungsfehler wird der zuvor eingegebene Wert angezeigt (korrekt).

    Wenn man den value weglässt, so wird bei einem Validierungsfehler beim Anlegen der Wert wieder angezeigt (korrekt). Aber beim Bearbeiten ist das Feld leer (falsch). Bei einem Validierungsfehler beim Bearbeiten wird der zuvor eingegebene Wert angezeigt (korrekt).

    1. <f:form.textfield property="dateOfBirth" />

    Das kann doch nicht sein, dass bisher noch niemand das Problem hatte bzw. gelöst hat?

  • frohike frohike
    T3PO
    0 x
    18 Beiträge
    0 Hilfreiche Beiträge
    22. 01. 2014, 20:13

    Nach langem hin und her habe ich nur eine Lösung gefunden: Das DateTime Objekt zu ignorieren und die Daten als String bzw. Integer zu speichern.

    1. // Model:
    2. /**
    3. * Datum
    4. *
    5. * @var \string
    6. */
    7. protected $date;
    8.  
    9. /**
    10. * Returns the date
    11. *
    12. * @return \string $date
    13. */
    14. public function getDate() {
    15. return date('d.m.Y', $this->date);
    16. }
    17.  
    18. /**
    19. * Sets the date
    20. *
    21. * @param \string $date
    22. * @return void
    23. */
    24. public function setDate($date) {
    25. list($d,$m,$y) = explode('.', $date);
    26. $this->date = mktime(0,0,0,$m,$d,$y);
    27. }

    1. Template:
    2. <f:form.textfield property="date" />

    Nach allem was ich gelesen habe dürfte es einen Bug in der Validierung von DateTime geben.

  • harald1972 harald197...
    Sternenflotten-Admiral
    0 x
    198 Beiträge
    13 Hilfreiche Beiträge
    17. 03. 2015, 08:28

    Der Thread ist zwar nicht mehr der jüngste... ;)

    Ist das Problem jetzt gelöst?
    Die Ausweichlösung mit dem String ist nicht gerade als "sauber" zu bezeichnen.
    Wie sieht dein SQL aus? Steht denn in der DB noch int(11)? Nach meiner Erkenntnis sind das 32Bit, reicht bis zum Jahr 2038.

    Gruß
    Harald

  • frohike frohike
    T3PO
    0 x
    18 Beiträge
    0 Hilfreiche Beiträge
    17. 03. 2015, 10:30

    Hallo Harald,

    hab mir das Problem in der Zwischenzeit nicht mehr angeschaut (auch nicht unter 6.2), aber ich habe es damals so gelöst dass ich im Model die erforderliche Konvertierung gemacht habe (ich weiß, ist nicht sauber, aber ich hab die Geduld verloren). In der DB wird das Datum auf bewährte Weise als Integer gespeichert. D.h. Getter und Setter arbeiten mit den formatierten Strings (d.m.Y) und in der DB steht der Timestamp. Code für Model steht oben. Repository und Controller brauchen nix Spezielles.

    Mir ist aufgefallen, dass im aktuellen extension_builder (für 6.2) ein Datumsfeld nicht mehr als Integer angelegt wird sondern als DateTime in der DB steht. Das zeigt mir, dass sich hier etwas verändert hat, aber ich habe mich noch nicht damit auseinander gesetzt.

    Ich denke, dass PHP und MySQL in der Lage sind, Integer größer als 32 Bit handzuhaben. Dazu muss das DB Feld mit dem Timestamp aber anders als int(11) definiert sein - entweder bigint oder int(11) unsigned.
    Aber damit beschäftige ich mich genauer in 22 Jahren ;)

    HTH - Hope that helps

  • 1