Zum Inhalt springen

Array sortieren und erstes bzw. letztes child ausgeben

Erstellt am 20. November 2017 · 3 Antworten · letzte Antwort am 21. November 2017

Tags: Fluid, ViewHelper, TYPO3 8, Frage

mbuchegger ·

Also die Aufgabe ist ja echt simpel, und dennoch finde ich keine wirklich gute Lösung.

Ich hab Termine in einem Array, will nun den ersten Termin und den letzten Termin auslesen können.

Mein Ansatz:
Mal die Termine sortieren und dann den ersten ausgeben.
Wenn ich dann DESC sortiere, kann ich das selbe mit dem letzten machen.

Aber wie mach ich das in Fluid.

Angenommen:
{produktion.termine}

Ansatz für erstes:
{produktion.termine->v:iterator.sort(sortBy: 'datum', order: 'ASC')}

jetzt will ich aber nur das erste ausgeben, und das will ich als variable dann verwenden.

Dafür dachte ich an f:alias.
Aber...

<f:alias map="{test:'{produktion.termine->v:iterator.sort(sortBy: 'datum', order: 'ASC')}'}">
<f:debug>{test}</f:debug>
</f:alias>

ergibt mir einen Fehler, da ein array erwartet wurde, es aber ein string sein soll...

Das verwirrt mich extrem.
Warum ist so was nicht möglich, und welche Ansätze habt ihr da?

Ganz generell ist es eine echte Katastrophe mit DateTime zu arbeiten. Das funktioniert nie, wie ich mir das vorstelle. hmpf. 😃

lg M.

freeatweb ·

Verstehe ich das richtig, dass die Termine bereits sortiert an FLUID übergeben werden?

Wenn ja, würde ich mit iteration arbeiten.

Beispiel:

<f:for each="{produktion.termine}" as="termine" iteration="ter">
<f:if condition="{ter.isFirst}">
...hier die TErmindaten ausgeben - z.B. termine.startDate 
</f:if>
<f:if condition="{ter.isLast}">
...hier die TErmindaten ausgeben - z.B. termine.startDate 
</f:if>

</f:for>
mbuchegger ·

Hey.
Ne, das ist bisschen anders.

Also zumindest kann ich nicht davon ausgehen, dass die immer sortiert sind.
Außer es gibt ne Möglichkeit aus dem Model immer sortiert auszugeben.

Im Repository wäre das ja alles ganz leicht zu machen. Für meine Anwendung fällt mir aber keine wirklich einfache Lösung ein.

Tatsächlich ist das etwas verschachtelter (es geht um Shows):

Alles fängt an mit ner Show. Das ist zB Hamlet. Dann gibt es darunter Produktionen, also verschiedenste Inszenierungen verschiedener Theater / Produzenten. Und die haben dann wieder Termine. Soweit sollte das logisch sein.

Show
Produktion
Termine

Jetzt bin ich aber zB in der ShowAction von Show und möchte mir die Produktionen listen, und dabei den Zeitraum ausgeben von wann bis wann das gespielt wird.

Also gebe ich mir per "f:for each" mal die Produktionen aus und will dann eben das erste Datum in den Terminen und das letzte Datum der Termine ermitteln.

Hab mir dazu auch einfach bislang nen Getter im Model einfach geschrieben, der mir das ausgibt. Ich hab aber das Problem, dass das manchmal zu einem Fehler führt, wenn zu viele Vorstellungen eingetragen sind. Und da reden wir vielleicht von ca. 100 Vorstellungen wo das dann mal ein Problem macht. Das ist zwar eher selten, aber es kommt vor. Und dafür brauch ich ne Lösung.

Jetzt wollte ich das einfach via Fluid mal probieren.

Ziel ist aber, dass diese Ansicht in verschiedenen Arten von Datensätzen verwendet werden kann. zB auch ein Spielort soll die Produktionen listen können. Insofern ist es einfach mit klaren Variablen zu arbeiten.

Außerdem muss ich die Daten in Fluid vergleichen können. Wenn zB das letzte und erste Datum das selbe ist, soll kein 01.01.2017 - 01.01.2017 erscheinen, sondern nur ein 01.01.2017. Wenn ich das will, funktioniert das aber mit deinem Ansatz nicht mehr.

Ich brauche also das erste und letzte Datum jeweils als Variable, die ich abrufen kann. Und das hab ich wie gesagt auch schon geschafft - nur macht das Probleme, wenn zu viele Termine vorhanden sind.

Fehler:
Fatal error: Nesting level too deep - recursive dependency? in .../*/Classes/Domain/Model/Produktionen.php on line 2101

Deshalb versuche ich gerade nen anderen Ansatz zu finden.
Oder gibt es einen einfachen Weg, dass ich über das Model ein Array direkt vorsortieren kann? Und das eben in zwei Versionen. Wenn ich dann einmal ASC und DESC die Vorstellungen nach Datum sortiere, könnte ich via {produktion.termine.0} jeweils das erste auslesen. Das wäre dann natürlich einfach.

Aktuell ist das so im Model:

    protected function array_sort($array, $on, $order)
    {
        $new_array = array();
        $sortable_array = array();

        if (count($array) > 0) {
            foreach ($array as $k => $v) {
                if (is_array($v)) {
                    foreach ($v as $k2 => $v2) {
                        if ($k2 == $on) {
                            $sortable_array[$k] = $v2;
                        }
                    }
                } else {
                    $sortable_array[$k] = $v;
                }
            }

            switch ($order) {
                case SORT_ASC:
                    asort($sortable_array);
                break;
                case SORT_DESC:
                    arsort($sortable_array);
                break;
            }

            foreach ($sortable_array as $k => $v) {
                $new_array[$k] = $array[$k];
            }
        }

        return $new_array;
    }
    

    /**
     * Returns the start
     *
     * @return array $start
     */
    public function getStartDatum() {
        
        foreach($this->vorstellungen as $x => $y)
        $ausgabe[] = $y ;
        $ausgabe_sortiert = $this->array_sort($ausgabe, 'veranstaltungsdatum', SORT_ASC);
        
        if (count($this->vorstellungen)>0) {
            $ausgabe_master = reset(array_shift(array_values($ausgabe_sortiert)));
        } else {
            $ausgabe_master = null;
        }
        
        return $ausgabe_master;
    }
    
    /**
     * Returns the start
     *
     * @return array $start
     */
    public function getEndDatum() {
        
        foreach($this->vorstellungen as $x => $y)
        $ausgabe[] = $y ;
        $ausgabe_sortiert = $this->array_sort($ausgabe, 'veranstaltungsdatum', SORT_DESC);
        
        if (count($this->vorstellungen)>0) {
            $ausgabe_master = reset(array_shift(array_values($ausgabe_sortiert)));
        } else {
            $ausgabe_master = null;
        }
        
        return $ausgabe_master;
    }
mbuchegger ·

Hab nun ne Lösung dafür.

Da ich ne Variable brauche, hab ich jetzt einfach einen Abruf im Model ins Repository geschrieben, über welches der jeweilige Termin ausgegeben wird.

Das klappt wunderbar. Besonders schön ist das aber nicht.

lg M.