Termine finden und kleine Umfragen ohne Registrierung (Code-Pool des VEBS)
  • PHP 60.8%
  • Twig 20.2%
  • CSS 11.4%
  • JavaScript 6.8%
  • Dockerfile 0.8%
Find a file
vebs-jg 2d2d411ae5 Terminfinder: erste öffentliche Fassung im Code-Pool
Termin- und Umfrage-Werkzeug ohne Registrierung (PHP, MySQL/MariaDB),
aufbereitet nach den Vorgaben des VEBS-Code-Pools: EUPL 1.2, Einstellungen
über .env mit Trennung von Test- und Live-Betrieb, Testdaten, Dokumentation
nach Vorlage. Frische Versionsgeschichte; die bisherige Entwicklung ist im
CHANGELOG zusammengefasst.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 00:07:34 +01:00
bin Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
docs Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
migrations Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
public Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
scripts Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
src Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
templates Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
tests Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
vendor Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
.dockerignore Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
.env.example Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
.gitignore Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
.htaccess Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
CHANGELOG.md Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
CLAUDE.md Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
composer.json Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
composer.lock Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
docker-compose.traefik.example.yml Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
docker-compose.yml Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
Dockerfile Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
LICENSE Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00
README.md Terminfinder: erste öffentliche Fassung im Code-Pool 2026-11-06 00:07:34 +01:00

Terminfinder

In einem Satz: Termine finden und kleine Umfragen machen, ohne dass sich jemand registrieren muss – auf dem eigenen Server statt bei einem fremden Dienst.

Für wen Schul- und Kita-Leitungen, Lehrerinnen und Lehrer, Erzieherinnen und Erzieher, Verwaltung, Elternvertretungen – alle, die Termine abstimmen
Einrichtungsart beide (Schule und Kita)
Schwierigkeitsgrad mittel
Pflegestatus aktiv betreut – zuletzt aktualisiert: 06.11.2026
Einreichende Einrichtung Verband Evangelischer Bekenntnisschulen und Kitas e. V. (VEBS)
Lizenz EUPL 1.2

Was die Anwendung macht

Du legst eine Umfrage an – mit Terminvorschlägen (Datum und Uhrzeit) oder mit eigenen Antworten – und schickst den Link herum. Wer den Link hat, trägt seinen Namen ein und klickt je Vorschlag „Ja“, „Nein“ oder „Vielleicht“. Eine Tabelle zeigt sofort, welcher Termin am besten passt. Niemand braucht ein Konto; zum Verwalten bekommst du einen eigenen, geheimen Link.

Typischer Fall: Die Klassenleitung sucht einen Termin für den Elternabend, schickt den Link in die Eltern-Gruppe und sieht nach zwei Tagen, an welchem Abend die meisten können.

Der Terminfinder ist bewusst schlicht: PHP und MySQL bzw. MariaDB, keine Benutzerkonten, keine KI, keine Dienste von Dritten. Er läuft auf einem einfachen Webhosting genauso wie mit Docker auf einem eigenen Server.

Voraussetzungen

  • Server: entweder ein Webhosting mit PHP ab 8.1 (mit pdo_mysql), MySQL oder MariaDB und Apache (für die .htaccess-Dateien) – oder ein eigener Server mit Docker und Docker Compose.
  • Geplante Aufgaben (Cronjob): einmal täglich, damit alte Umfragen gelöscht werden.
  • Optional: ein E-Mail-Konto mit SMTP-Zugang für Benachrichtigungen an die Organisatorin oder den Organisator.
  • Eigene Webseiten mit Datenschutzerklärung und Impressum, auf die der Terminfinder verlinkt.
  • Vorwissen: Dateien auf ein Webhosting hochladen, eine Datenbank im Verwaltungsbereich des Hostings anlegen, eine Textdatei bearbeiten. Für den Docker-Weg: Grundkenntnisse auf der Kommandozeile.
  • Die PHP-Bibliotheken liegen fertig im Ordner vendor/. Composer brauchst du nicht.

Installation Schritt für Schritt

Erst ausprobieren: Testumgebung auf dem eigenen Rechner

Die Testumgebung arbeitet nur mit erfundenen Daten und verschickt keine E-Mails. Du brauchst PHP ab 8.1 und eine lokale MariaDB oder MySQL.

  1. Projekt herunterladen (Zip-Datei vom Repository oder git clone) und im Terminal in den Projektordner wechseln.
  2. Testdatenbank einmalig anlegen (als Datenbank-Verwalter, z. B. mit mysql -u root):
    CREATE DATABASE termine_test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    CREATE USER 'termine_test'@'localhost' IDENTIFIED BY 'termine_test';
    CREATE USER 'termine_test'@'127.0.0.1' IDENTIFIED BY 'termine_test';
    GRANT ALL PRIVILEGES ON termine_test.* TO 'termine_test'@'localhost', 'termine_test'@'127.0.0.1';
    
  3. Testdaten erzeugen (legt die Tabellen neu an und füllt sie mit erfundenen Umfragen):
    php scripts/testdaten_erzeugen.php
    
  4. Anwendung starten und im Browser http://localhost:8000 öffnen:
    php -S localhost:8000 -t public
    

Eine .env brauchst du dafür nicht. Unten auf jeder Seite steht „Testumgebung“.

Weg A: Webhosting mit PHP und MySQL

  1. Den ganzen Projektordner (mit vendor/) per FTP oder Dateimanager auf das Webhosting hochladen, z. B. in einen Ordner terminfinder/.
  2. Im Verwaltungsbereich des Hostings den Dokumentstamm (Webroot) der Domain oder Subdomain auf terminfinder/public setzen. Nur dieser Ordner darf öffentlich erreichbar sein. Die .htaccess im Projektordner sperrt als Sicherheitsnetz alles andere – sie wirkt aber nur unter Apache, nicht unter nginx.
  3. Eine Datenbank (MySQL oder MariaDB) im Verwaltungsbereich anlegen und die Datei migrations/001_init.sql importieren (meist über phpMyAdmin, „Importieren“).
  4. Im Projektordner (nicht in public/) eine Datei .env anlegen: Inhalt von .env.example kopieren und ausfüllen, mindestens TERMINFINDER_UMGEBUNG=live, BASE_URL, APP_SECRET und die DB_…-Angaben. Beim Datenbank-Rechner (DB_HOST) genau den Namen eintragen, den das Hosting anzeigt – das ist nicht immer localhost.
  5. Eine geplante Aufgabe (Cronjob) anlegen, die täglich bin/cleanup.php ausführt. Dabei dieselbe PHP-Version wählen wie für die Website; bei manchen Hostern steht eine neue Aufgabe zunächst auf einer sehr alten Version.
  6. Die Domain im Browser öffnen und eine Probe-Umfrage anlegen. Falls du SSH-Zugang hast, prüft php bin/test-mail.php deine@adresse.de den Mailversand und zeigt Fehler im Klartext.

Weg B: Eigener Server mit Docker

  1. Projekt auf den Server holen (git clone …) und in den Ordner wechseln.
  2. cp .env.example .env, dann die .env ausfüllen (siehe „Konfiguration“) und schützen: chmod 600 .env. Für den Echtbetrieb TERMINFINDER_UMGEBUNG=live und z. B. DB_NAME=termine, DB_USER=termine setzen.
  3. Starten:
    docker compose up -d --build
    
    Beim ersten Start legt der Datenbank-Container Datenbank, Benutzer und Tabellen an.
  4. Die Anwendung ist dann nur auf dem Server selbst unter 127.0.0.1:8080 erreichbar (Port über APP_PORT). Davor gehört ein Webserver oder Proxy mit HTTPS. Mit Traefik: docker-compose.traefik.example.yml nach docker-compose.override.yml kopieren und DOMAIN in der .env setzen.
  5. Täglichen Löschlauf in die Crontab des Servers eintragen (crontab -e), Pfad anpassen:
    0 4 * * * cd /pfad/zum/terminfinder && docker compose exec -T app php bin/cleanup.php
    
  6. Mailversand prüfen: docker compose exec app php bin/test-mail.php deine@adresse.de

Zum Ausprobieren mit Docker: in der .env TERMINFINDER_UMGEBUNG=test und einen Datenbanknamen mit _test am Ende setzen, dann nach dem Start docker compose exec app php scripts/testdaten_erzeugen.php.

Konfiguration

Alle Einstellungen stehen in der Datei .env im Projektordner (Vorlage mit Erklärungen: .env.example). Mit Docker kommen sie als Umgebungsvariablen in den Container; echte Umgebungsvariablen haben Vorrang vor der .env. Die .env enthält Zugangsdaten und gehört nie in ein Repository.

Einstellung Bedeutung
TERMINFINDER_UMGEBUNG test (Standard) oder live. Ohne live läuft die Anwendung immer in der Testumgebung: Datenbankname muss auf _test enden, keine E-Mails, fester Test-Schlüssel.
APP_NAME Name in Kopfzeile, Seitentitel und Mails (Standard: Terminfinder)
BASE_URL Adresse der Anwendung, z. B. https://termine.meine-schule.de (live Pflicht)
APP_SECRET Zufälliger Schlüssel, mindestens 32 Zeichen (live Pflicht). Nicht nachträglich ändern, sonst erkennt die Anwendung abgegebene Stimmen nicht mehr als „meine“.
POLL_RETENTION_DAYS Nach wie vielen Tagen Umfragen gelöscht werden (Standard 180, 0 = nie)
DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD Datenbank (live Pflicht); DB_ROOT_PASSWORD nur für Docker
MAIL_HOST, MAIL_PORT, MAIL_ENCRYPTION, MAIL_USERNAME, MAIL_PASSWORD, MAIL_FROM_ADDRESS, MAIL_FROM_NAME Mailversand per SMTP; MAIL_HOST leer = keine Mails. MAIL_ENCRYPTION: tls (Port 587), ssl (Port 465) oder keine
BETREIBER_NAME, HOMEPAGE_URL Name und Website deiner Einrichtung (Fußzeile)
DATENSCHUTZ_URL, IMPRESSUM_URL Links auf deine Datenschutzerklärung und dein Impressum; /datenschutz leitet auf die Datenschutzerklärung weiter
QUELLCODE_URL Link auf den Quellcode, z. B. dein Repository (die EUPL verlangt, dass Nutzer den Code finden können)
LOGO_URL, LOGO_ALT, FAVICON_URL Eigenes Logo und Symbol im Browser-Tab. Dateien in public/eigenes/ ablegen (wird nicht ins Repository übernommen), dann z. B. LOGO_URL=/eigenes/logo.png. Ohne Logo erscheint nur der Schriftzug.
APP_PORT, DOMAIN Nur für Docker bzw. das Traefik-Beispiel

Fehlt im Live-Betrieb eine Pflichtangabe, startet die Anwendung nicht. Auf der Seite steht dann nur „noch nicht vollständig eingerichtet“, die genaue Ursache steht im Fehlerprotokoll des Servers.

Farben anpassen: oben in public/style.css unter :root. Orange und Rot sind zugleich die Farben für „Vielleicht“ und „Nein“ – bei anderen Farben auf guten Kontrast achten.

Bedienung

  • Umfrage erstellen: Auf der Startseite Titel, optional eine Beschreibung und deinen Namen eintragen. Wähle „Terminumfrage“ (Datum und Uhrzeit) oder „Umfrage mit eigenen Antworten“. Kurzschreibweise beim Datum: 031226 wird zu „Do, 3.12.2026“, 1510 wird zu „15:10 Uhr“. Optional: E-Mail-Adresse für Benachrichtigungen, „Vielleicht“ erlauben, Passwort für die Umfrage.
  • Zwei Links: Nach dem Erstellen siehst du den Link zum Teilen und den Verwaltungslink. Den Verwaltungslink sofort speichern – er wird nur dieses eine Mal angezeigt und ist der einzige Schlüssel zum Verwalten.
  • Abstimmen: Name eintragen, bei jedem Vorschlag Ja, Nein oder Vielleicht wählen, absenden. Auf demselben Gerät lässt sich die eigene Stimme später ändern. Die Tabelle hebt die Termine mit den meisten Ja-Stimmen hervor.
  • Kommentare: Unter der Abstimmung kann jede und jeder einen Hinweis hinterlassen.
  • Verwalten (über den Verwaltungslink): Umfrage schließen und wieder öffnen, einzelne Teilnahmen entfernen, Vorschläge ändern oder löschen (solange noch niemand dafür gestimmt hat), Ergebnis als CSV-Datei für Excel herunterladen, Umfrage ganz löschen.

Datenschutz

  • Verarbeitete Daten: Titel und Beschreibung der Umfrage; Name und (freiwillig) E-Mail-Adresse der Person, die die Umfrage anlegt; Name, (freiwillig) E-Mail-Adresse und Antworten der Teilnehmenden; Kommentare mit Namen. Ein optionales Umfrage-Passwort wird nicht im Klartext gespeichert, sondern nur als Prüfwert (Hash). IP-Adressen speichert die Anwendung nicht in der Datenbank (Protokolle des Webservers bzw. Hostings gesondert prüfen).
  • Cookies: ein Sitzungscookie (PHPSESSID, Schutz der Formulare) und je Umfrage ein Cookie kairos_vote_<Nummer>, das die eigene Stimme wiedererkennt (signiert, 180 Tage gültig). Kein Tracking.
  • Speicherort: ausschließlich in deiner Datenbank auf deinem Server bzw. Webhosting.
  • Löschung: Umfragen samt allen Stimmen und Kommentaren werden nach POLL_RETENTION_DAYS Tagen gelöscht (Standard 180), sofern der tägliche Löschlauf eingerichtet ist. Die Person mit dem Verwaltungslink kann jederzeit einzelne Teilnahmen oder die ganze Umfrage löschen.
  • Externe Dienste: keine. Keine KI, keine eingebundenen Schriften oder Skripte von Dritten. E-Mails gehen nur über den Mailserver, den du einstellst, und nur an die Person, die die Umfrage angelegt hat.
  • Datenschutzerklärung: Der Terminfinder bringt keine eigene mit. Ergänze deine Datenschutzerklärung um einen Abschnitt mit den Punkten oben und trage den Link in DATENSCHUTZ_URL ein.
  • Testumgebung: Für Erprobung und Anpassung gibt es Testdaten mit erfundenen Personen (scripts/testdaten_erzeugen.php), echte Daten sind dafür nicht nötig.
  • Hinweis: Vor dem Einsatz mit echten Daten den eigenen Datenschutzbeauftragten einbinden.

Bekannte Grenzen

  • Keine Benutzerkonten: Wer den Verwaltungslink verliert, kann die Umfrage nicht mehr verwalten (nur noch direkt in der Datenbank).
  • Titel, Beschreibung und Passwort lassen sich nach dem Anlegen nicht mehr ändern; Vorschläge nur, solange noch niemand dafür gestimmt hat.
  • Nur Deutsch. Kein Kalender-Export, keine Erinnerungsmails; Benachrichtigungen gehen nur an die Person, die die Umfrage angelegt hat.
  • Schutz vor Spam nur über ein verstecktes Formularfeld, keine Begrenzung der Anfragen.
  • CSV-Export: Einträge, die mit =, +, - oder @ beginnen, kann ein Tabellenprogramm als Formel lesen. Exporte nur aus Umfragen öffnen, deren Teilnehmende du kennst, oder die Warnung des Tabellenprogramms beachten.
  • Die Testumgebung braucht eine lokale MariaDB oder MySQL.
  • Die .htaccess-Sperre des Projektordners wirkt nur unter Apache.

Haftungshinweis

Bereitstellung ohne Gewähr. Prüfung und Einsatz liegen in der Verantwortung des nutzenden Trägers. Der VEBS stellt den Code nur bereit.

Lizenz

EUPL 1.2, siehe LICENSE (amtliche deutsche Fassung).

Mitgelieferte Bibliotheken im Ordner vendor/ (jeweils mit eigener Lizenzdatei), alle mit der EUPL vereinbar:

Bibliothek Version Lizenz
Twig (Vorlagen) 3.28 BSD-3-Clause
PHPMailer (Mailversand) 6.12 LGPL-2.1-only
symfony/deprecation-contracts 3.7 MIT
symfony/polyfill-ctype 1.37 MIT
symfony/polyfill-mbstring 1.38 MIT

Für Docker werden die öffentlichen Images php:8.3-apache und mariadb:11 verwendet.

Ansprechpartner

Verband Evangelischer Bekenntnisschulen und Kitas e. V. (VEBS), Geschäftsstelle – Kontakt über www.vebs.de. Der VEBS stellt den Code bereit, betreibt aber keine Installationen für andere und leistet keinen Support (siehe Haftungshinweis).

Für die Weiterentwicklung

  • Mit KI anpassen: Die Datei CLAUDE.md enthält die Regeln des Code-Pools für KI-Assistenten (z. B. Claude Code). Wie die Anwendung entstanden ist und welche Teile man typischerweise anpasst: docs/entstehung.md.
  • Tests: php tests/run.php (der Abgleich der Datumslogik zwischen PHP und JavaScript braucht Node.js).
  • Datenbankänderungen nur über neue Dateien in migrations/ (nächste Nummer), zuerst mit den Testdaten prüfen.
  • Aufbau: public/ (öffentlich: index.php mit allen Seiten, CSS, JavaScript), src/ (PHP-Klassen, u. a. Config.php für die Einstellungen), templates/ (Twig-Vorlagen), migrations/ (Datenbankschema), bin/ (Löschlauf, Mailtest), scripts/ (Testdaten), tests/, vendor/ (Bibliotheken).
  • Änderungen: CHANGELOG.md.