Aufgabe

Implementieren für das Symfony-basierte Lauftagebuch (Übung 6) ein Statistik-Feature. Dazu sollen die Einträge aller Läufer ausgewertet werden um folgende Ranglisten zu erstellen:

  • Die Top 5 Langstreckenläufer, d.h. die Läufer mit der größten zurückgelegten Gesamtstrecke.
  • Die Top 5 Schnellläufer, d.h. die Läufer mit der größten Gesamt-Durchschnittsgeschwindigkeit (= Gesamtstrecke ∕ Gesamtzeit).

Beide Ranglistenarten soll es in drei Varianten geben, die jeweils verschiedene Teilmengen der Gesamtdaten berücksichtigen:

  1. Die Top 5 über die gesamten Daten.
  2. Die Top 5 des letzten Monats (d.h. hier: Zeitraum von vor 30 Tagen bis heute).
  3. Die Top 5 der letzten Woche (d.h. hier: Zeitraum von vor 7 Tagen bis heute).

Ingesamt gibt es also 6 (= 2 × 3) Ranglisten mit je 5 Einträgen.

Darstellung

Die Ranglisten sollen jeweils als Tabellen mit Platzierung (1. bis 5.), Läufernamen als Link zum Läuferprofil, und jeweiligem Wert (also Gesamtstrecke bzw. Gesamt-Durchschnittgeschwindigkeit) angezeigt werden.

Sonderfälle (siehe auch Beispiel):

  • Gibt es im betreffenden Zeitraum weniger als 5 Läufer mit Tagebucheinträgen, dürfen die letzten Platzierung einfach fehlen.
  • Um eine besondere Behandlung von Gleichplatzierten müssen Sie sich auch nicht kümmern.

Beispiel

Top 5 Langstreckenläufer der letzten 7 Tage

Platz Läufer Strecke
1. Petra 15.1 km
2. Klausi 9.4 km
3. Maya 9.4 km
4. Franz 0.8 km

Umsetzung

Implementieren Sie die Logik nicht mit PHP-Mitteln (d.h. Schleifen, Arithmetik, ...), sondern lassen Sie die Datenbank die Arbeit machen. Nutzen Sie dafür die Doctrine Query Language (DQL), die Ihnen SQL-artige Ausdrücke ermöglicht, die auf Objekten (statt, wie bei SQL, Tabellen) angewendet werden. Pro Rangliste reicht ein einziger DQL-Query, der die Ergebnisse in einer Form ausgibt, die direkt einem Template übergeben werden können!

Hinterlegen Sie Ihre Ranglisten-Implementierungen in einer Repository-Klasse.

Natürlich sollen die Ranglisten auch angezeigt werden. Es ist Ihnen überlassen, ob Sie bestehende Controller/Templates ergänzen, oder neue Controller/Templates erstellen. Beides ist ähnlich leicht, da die eigentliche Logik ohnehin in einer Repository-Klasse liegen soll.

Hinweise

  • Mit einem Fixture können Sie programmatisch beliebig viele Läufer und Tagebucheinträge erzeugen. Sie sollten zum Testen mehr als fünf Läufer, mit jeweils mehr als zwei Einträgen verwenden, und Laufdaten nutzen, die über mehr als die letzten 30 Tage verteilt sind. Nur so können Sie die Unterschiede zwischen den Ranglisten sehen. Mit der PHP-Funktion mt_rand(int min, int max) können Sie zufällige, ganze Zahlen ermitteln.
  • In klassischen SQL-Abfragen erhalten Sie immer (Zeilen und Spalten von) skalare(n) Werte(n), also einfache Werte. Mit Doctrines DQL hingegen können Sie neben einfachen Werten auch ganze Objekte abfragen, und sogar Mischformen, also Objekte und Skalare!
  • Sie können DQL-Befehle direkt auf der Kommandozeile ausführen:
    $ php bin/console doctrine:query:sql "SELECT ..."
  • Für Debugging-Zwecke können Sie mit der Symfony-Funktion dump() besser lesbare Ausgaben erzeugen als mit PHPs var_dump() oder print_r().
  • Hilfreiche Abschnitte in der DQL-Doku: DQL-Joins, DQL-Funktionen und Aggregat-Funktionen, Max Result Items.
  • Die sechs Queries (für die sechs Ranglisten) sind einander vom Aufbau sehr ähnlich. Wenn Sie den QueryBuilder von Doctrine benutzen, können Sie einfach gemeinsame Teile wiederverwenden und Queries übersichtlich zusammenbauen.

Bewertungskriterien (max. 4 Punkte)

  • Beide Ranglisten-Arten sind implementiert.
  • Die drei verschiedenen Zeiträume sind implementiert.
  • Die Ranglisten sind so in DQL implementiert, dass jeweils nur ein Query auf der Datenbank ausgeführt wird und dieser Daten in einer Form zurückliefert, die direkt an ein Template weitergegeben werden kann: in PHP sollen also keine weiteren Berechnungen oder Sortierung durchgeführt werden. (2 Punkte)