srhinow/training-plan-manager

Wöchentlicher Trainingsplan (Wochentag + Von–Bis + Gruppe) für das Contao CMS – schlanke Alternative zu wiederkehrenden Kalender-Events

Maintainers

Package info

gitlab.com/srhinow/training-plan-manager

Issues

Type:contao-bundle

pkg:composer/srhinow/training-plan-manager

Transparency log

Statistics

Installs: 10

Dependents: 0

Suggesters: 0

Stars: 0

0.6.1 2026-08-17 21:46 UTC

This package is not auto-updated.

Last update: 2026-08-17 20:20:05 UTC


README

Ein schlankes Contao-5-Bundle zur Verwaltung eines wöchentlichen Trainingsplans: Wochentag + Von–Bis + Gruppe, ohne die Umständlichkeit wiederkehrender Kalender-Events.

Gedacht für Vereine/Schulen mit festem Wochenrhythmus (z. B. Kampfsport, Fitness), bei denen der Kalender nur für echte Einzeltermine (Prüfungen, Ausflüge, Lehrgänge) zuständig bleiben soll.

Warum

Wiederkehrende Trainingszeiten als vollwertige Kalender-Events zu pflegen (Datum, Uhrzeit, Wiederholung, Ausnahmen) ist für Redakteure umständlich. Im Kern ist ein Trainingsplan aber nur ein fester Wochenplan. Dieses Bundle bildet genau das ab.

Funktionsumfang

  • Datenmodell tl_training_time: title, weekday (Mo–So), timeStart/timeEnd, trainingGroup (Fremdschlüssel auf tl_training_group), optional location/note, beliebig viele Ausfall-Zeiträume (cancellations, rowWizard), trainingMode, published.
  • Backend-Modul „Trainingszeiten": flache, sortierbare Liste, in Sekunden editierbar; Trainingsgruppen als eigene Einstellungs-Tabelle (tl_training_group: title, alias, appliesToAll).
  • Betriebsart-Umschalter „Regelbetrieb ↔ Ferienbetrieb": ein Klick publiziert die Termine der Ziel-Betriebsart und blendet die der anderen aus. Slots mit trainingMode = always bleiben unberührt.
  • Frontend-Module (Kategorie „Trainingsplan"):
    • training_next – nächstes anstehendes Training
    • training_list – kommende Termine, nach Tag/Datum gruppiert (Markup wie die Contao-Event-Liste)
    • training_calendar – Wochenkalender Mo–So mit Vor/Zurück-Navigation
    • training_feed – „Trainingsplan abonnieren": fertige Abo-Adressen je Gruppe, Kopier-Knopf und webcal://-Link
  • Insert-Tags: {{next_training_day}}, {{next_training_date}}, {{next_training_datetime}}.
  • iCalendar-Abo unter /training-plan/schedule.ics (siehe unten).

Bedienung im Backend

Alles liegt unter Inhalte → Trainingszeiten. Die Liste zeigt oben drei Schaltflächen: den Betriebsart-Umschalter, „Trainingsgruppen" und „Mehrere bearbeiten".

1. Trainingsgruppen anlegen (Button „Trainingsgruppen"): Name + Alias, z. B. „Anfänger", „Fortgeschrittene" und – falls zeitweise gemeinsam trainiert wird – „alle". Der Alias ist es, der später in der Abo-Adresse steht (?group=anfaenger).

2. Bei einer gemeinsamen Gruppe („alle") die Checkbox „Termine gelten für alle Gruppen" (appliesToAll) setzen. Sie sitzt bewusst an der Gruppe, nicht am einzelnen Termin – sonst müsste sie an jedem Ferientermin einzeln gepflegt werden. Wirkung siehe Gemeinsame Termine.

3. Trainingszeiten anlegen: Titel, Wochentag, Von–Bis, Gruppe und Betriebsart:

BetriebsartBedeutung
Regelbetriebnormale Zeiten, im Ferienbetrieb ausgeblendet
FerienbetriebFerienzeiten (meist gemeinsames Training), im Regelbetrieb ausgeblendet
immerläuft in beiden Fällen; der Umschalter fasst diese Termine nie an

4. Umschalten: Der Button oben links heißt je nach Lage „Ferienbetrieb einschalten" bzw. „Regelbetrieb einschalten" und publiziert mit einem Klick die Termine der Ziel-Betriebsart, während er die der anderen ausblendet. Einzeln „Veröffentlichen" muss also niemand.

5. Ausfälle (Ferien, Feiertage, Einzeltermine) trägt man am jeweiligen Trainingstermin unter „Ausfälle" als Zeiträume ein – siehe Trainingsfreie Zeiten.

Kalender-Abo (iCal)

https://<domain>/training-plan/schedule.ics
https://<domain>/training-plan/schedule.ics?group=<gruppen-alias>

Die URL ist als Abonnement gedacht (Google Kalender „Per URL hinzufügen", Apple Kalender „Kalenderabo", Thunderbird „Netzwerk-Kalender") — nicht als einmaliger Download.

Jede Trainingszeit wird zu einem wiederkehrenden Termin (RRULE:FREQ=WEEKLY) statt zu einer Liste ausgerollter Einzeltermine. Das Abo läuft dadurch nicht nach ein paar Monaten leer, und die Kalender-App zeigt den Plan unbegrenzt weiter. Eingetragene Ausfall-Zeiträume erscheinen als EXDATE, verschwinden also auch im abonnierten Kalender.

Die Zeiten sind lokale Zeiten mit TZID, nie UTC — ein Training um 17:00 bleibt über den Sommer-/Winterzeit-Wechsel hinweg um 17:00. Die Zeitzone liegt als VTIMEZONE-Komponente bei, das Dokument ist also selbsttragend.

Ausgegeben werden nur veröffentlichte Trainingszeiten — der Umschalter Regelbetrieb/Ferienbetrieb wirkt damit automatisch auch auf das Abo. Die Termin-UIDs sind stabil (training-<id>@<domain>), Änderungen aktualisieren beim Abonnenten also den bestehenden Termin, statt einen zweiten anzulegen.

Gemeinsame Termine („Termine gelten für alle Gruppen")

Trainiert im Ferienbetrieb die ganze Gruppe zusammen, hängen diese Termine üblicherweise an einer eigenen Gruppe („alle"). Damit ein Abo trotzdem stimmt, hat tl_training_group das Feld appliesToAll: Termine einer so markierten Gruppe erscheinen zusätzlich in jedem anderen Gruppen-Abo.

Ein Mitglied abonniert damit einmalig seine Gruppe und sieht im Regelbetrieb nur die eigenen Termine, im Ferienbetrieb die gemeinsamen — ohne das Abo zu wechseln:

BetriebsartAbo „Anfänger" zeigtAbo „Fortgeschrittene" zeigt
RegelbetriebAnfänger-Termine (+ immer-Termine der Gruppe „alle")Fortgeschrittenen-Termine (+ dieselben immer-Termine)
Ferienbetriebgemeinsame Ferienterminegemeinsame Ferientermine

Das Modul „Trainingsplan abonnieren" bietet für solche Gruppen bewusst keinen eigenen Link an; ein zusätzliches Abo würde dieselben Termine ein zweites Mal in den Kalender legen.

Ohne gesetztes Flag verhält sich alles wie vor 0.6.0: Ein Gruppen-Abo enthält ausschließlich die Termine dieser einen Gruppe — und läuft im Ferienbetrieb entsprechend leer.

Trainingsfreie Zeiten

Ausfälle (Ferien, Feiertage, Einzelausfälle) werden ausschließlich am Trainingszeiten-Datensatz gepflegt – über die Ausfall-Zeiträume (cancellations). Es gibt bewusst keine Anbindung an Kalender aus contao/calendar-bundle: sie wäre eine zweite, konkurrierende Pflegestelle für dieselbe Information. Alle Ausgaben (Module wie Insert-Tags) berücksichtigen die Ausfälle damit einheitlich.

Installation

composer require srhinow/training-plan-manager
vendor/bin/contao-console contao:migrate   # legt tl_training_time + tl_training_group an

Datenmodell

weekday ist ISO-8601 kodiert (1 = Montag … 7 = Sonntag), passend zu date('N') für die „nächstes Training"-Berechnung. timeStart/timeEnd sind Contao-time-Felder (Unix-Timestamp auf dem Referenztag 1970-01-01). cancellations ist ein serialisiertes rowWizard-Array aus from/to-Datumswerten (ISO Y-m-d).

Entwicklung

composer install
composer run qa           # php-cs-fixer (Dry-Run) + PHPStan + PHPUnit
composer run cs-fix       # Coding-Standard anwenden
composer run unit-tests   # nur PHPUnit

Die Tests decken die Terminberechnung (TrainingScheduleCalculator) und das Parsen der Ausfall-Zeiträume (TrainingTimeModel) ab; sie laufen ohne Datenbank und ohne Contao-Framework. Die Zeitzone ist in phpunit.xml.dist auf Europe/Berlin festgenagelt, weil die Wochen-Schritte über Sommer-/Winterzeit-Wechsel hinweg korrekt bleiben müssen.

Lizenz

GPL-3.0-or-later · © Sven Rhinow