Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
301c2c6
init
tombrain Oct 5, 2026
45f2d58
Update composer.json and composer.lock for Golden Master testing setup
tombrain Oct 5, 2026
2fc9993
Restrict PHP version matrix to only 8.3 for Golden Master testing
tombrain Oct 5, 2026
8c0dfc9
Merge pull request #1 from tombrain/add_unittest_by_golden_master
tombrain Oct 5, 2026
c44219f
Refactor template system to use Composer dependencies
tombrain Oct 5, 2026
6b2447b
Add initial admin account setup and language translations
tombrain Oct 5, 2026
aab1e49
Remove error message regarding installation folder from various admin…
tombrain Oct 5, 2026
79a14fe
fix: TEsts lauf jetzt auch al HG-Action
tombrain Oct 9, 2026
8f9a77a
fix: sortiertes Lesen von Dateien
tombrain Oct 9, 2026
d376943
aktualisierung der golden master
tombrain Oct 9, 2026
9228157
refactor: update assertions to static context in test files
tombrain Oct 9, 2026
07eb9e0
fix(classlib): loadFile() liest das Spielende (n.V./i.E.)
tombrain Oct 9, 2026
46b1b76
fix(classlib): direkter Vergleich auch fuer Gleichstand am Tabellenende
tombrain Oct 9, 2026
5dc15f5
fix(classlib): Auswaertssieg am gruenen Tisch im direkten Vergleich
tombrain Oct 9, 2026
9c7a756
fix(classlib): liga::factory() statisch und mit richtigem Klassennamen
tombrain Oct 9, 2026
303fc6d
fix(classlib): aktuellerSpieltag() liefert den Spieltag aus Actual
tombrain Oct 9, 2026
2f79470
fix(classlib): ligaFussball::sortTable() ohne Warnungen
tombrain Oct 9, 2026
ae152d6
fix(classlib): calcLigaStats() zaehlt nur gespielte Partien
tombrain Oct 9, 2026
b55d317
fix(classlib): SerieToHTML() ueberschreibt die Serie nicht mehr
tombrain Oct 9, 2026
b59d29e
fix(classlib): strAfterChar() ohne Trennzeichen liefert ''
tombrain Oct 9, 2026
bcd5105
fix(classlib): readLigaDir() mit grossgeschriebener Endung
tombrain Oct 9, 2026
ac399e4
fix(classlib): HTML_icon() prueft alle Bildendungen trotz Alternativtext
tombrain Oct 9, 2026
879b178
test: Unit-Tests fuer die classlib
tombrain Oct 9, 2026
aec9ccc
fix: direkter Vergleich erkennt Gleichstand am vollen Punktestand
tombrain Oct 9, 2026
b9430e5
fix(classlib): direkter Vergleich wie in lmo-calctable.php
tombrain Oct 9, 2026
b11a928
fix: direkter Vergleich mit zehn und mehr punktgleichen Teams
tombrain Oct 9, 2026
3acb992
fix: beidseitiges Ergebnis zaehlt fuer beide Teams vollstaendig
tombrain Oct 9, 2026
f81c735
fix: Strafen ab Spieltag X zaehlen erst, wenn X erreicht ist
tombrain Oct 9, 2026
79ce96a
fix(classlib): Bonus-Gegentore mit richtigem Vorzeichen
tombrain Oct 9, 2026
854d19c
fix(classlib): Strafen wie im Kern buchen
tombrain Oct 9, 2026
e544aef
fix(classlib): beidseitiges Ergebnis (ET=3) auswerten
tombrain Oct 9, 2026
aedd892
test: Tabellen echter und konstruierter Ligen gegen Kern und classlib
tombrain Oct 9, 2026
1579d7b
fix(classlib): direkter Vergleich nur mit den Partien der Tabelle
tombrain Oct 9, 2026
0b51996
test: Kern und classlib rechnen an jedem Spieltag dieselbe Tabelle
tombrain Oct 9, 2026
2606709
fix(classlib): writeFile() mehrmals im selben Request
tombrain Oct 9, 2026
ace290f
test: Ligen ueber die classlib anlegen, speichern und wieder lesen
tombrain Oct 9, 2026
36673e5
fix(classlib): Spieltagswerte wie die Handicap-Reihenfolge erhalten
tombrain Oct 10, 2026
1fc3888
fix(classlib): writeFile() behaelt Titel und aktuellen Spieltag
tombrain Oct 10, 2026
309b42d
fix(classlib): updateAddons() findet Ligen in Unterordnern
tombrain Oct 10, 2026
fea3ed6
fix(security): lmo-rueckrunde.php nur fuer angemeldete Admins
tombrain Oct 10, 2026
2bb8fcd
test: classlib erhaelt jedes Feld der Ligadatei
tombrain Oct 10, 2026
f212e5e
Version 4.2.0
tombrain Oct 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Snapshots werden byte-genau verglichen: immer LF, auch unter Windows (core.autocrlf)
tests/GoldenMaster/__snapshots__/** text eol=lf
49 changes: 49 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Golden-Master-Tests direkt auf dem Runner (ohne Docker), siehe TESTING.md
name: Tests

on:
push:
pull_request:
workflow_dispatch:

jobs:
golden-master:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# vorerst nur die Version, mit der die Snapshots aufgezeichnet wurden
php: ['8.3']
name: PHP ${{ matrix.php }}

steps:
- uses: actions/checkout@v4

# faketime fixiert die Zeit (Kalender, "heute"-Markierungen) wie im Docker-Image
- name: faketime installieren
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends faketime

- name: PHP einrichten
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: gd
# wie das offizielle Docker-Image: keine php.ini, nur Standardwerte
ini-file: none
coverage: none
tools: composer:v2

- name: Composer-Cache
uses: actions/cache@v4
with:
path: ~/.composer/cache
key: composer-${{ matrix.php }}-${{ hashFiles('composer.lock') }}
restore-keys: composer-${{ matrix.php }}-

- name: Abhaengigkeiten installieren
run: composer install --no-interaction --no-progress --prefer-dist

- name: Tests
env:
GOLDEN_MODE: compare
run: vendor/bin/phpunit
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
vendor/
.original/
.phpunit.result.cache
lmo/vendor/
coverage/
# Laufzeitdateien einer Installation (legt lmo-setup.php an)
lmo/config/init-parameters.php
lmo/config/lmo-auth.php
lmo/config/.defaults-stamp
lmo/config/cfg.txt
lmo/config/*/cfg.txt
lmo/addon/tipp/lmo-tippauth.txt
# Rohdaten von tests/RealData/bin/fetch_openligadb.php
tests/RealData/.cache/
60 changes: 44 additions & 16 deletions README.md

Large diffs are not rendered by default.

280 changes: 280 additions & 0 deletions TESTING.md

Large diffs are not rendered by default.

85 changes: 84 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ _Hier schreiben wir Changelog Hinweise der nächsten Version._


### Changed
* Seitenquelltextausgabe der beiden Datein lmo-savehtml.php und lmo-savehtml1.php verbessert. Außerdem den Tabellen der beiden Seiten runde Ecken verpasst.


### Deprecated

Expand All @@ -20,8 +20,49 @@ _Hier schreiben wir Changelog Hinweise der nächsten Version._
### Fixed


### Security


***
## [4.2.0] - 2026-10-10

_Hier hätten wir die Changelogs für 4.2.0._

### Added
* Ersteinrichtung ohne Installer: Beim ersten Aufruf wird die Konfiguration aus `config-default/` angelegt, das erste Admin-Konto wird über ein Formular erstellt (Texte dafür in allen Sprachen).
* Sprachauswahl im Fuß des Admin-Bereichs.
* Automatische Tests (PHPUnit, Docker, GitHub Action), siehe TESTING.md: Golden-Master-Tests für öffentliche Seiten und Admin-Bereich, Unit-Tests für die classlib, Tabellenvergleich mit 75 echten Ligen (OpenLigaDB, Abschlusstabellen aus Wikipedia) und 10 konstruierten Ligen.
* classlib: Spieltage merken sich weitere Werte der Ligadatei (`spieltag::setParameter()` / `getParameter()`), z.B. die Handicap-Reihenfolge.

### Changed
* Die Mindestanforderung des Webservers beträgt jetzt PHP 8.0 (bisher 7.4). Der Admin-Bereich weist bei älteren PHP-Versionen darauf hin.
* Seitenquelltextausgabe der beiden Datein lmo-savehtml.php und lmo-savehtml1.php verbessert. Außerdem den Tabellen der beiden Seiten runde Ecken verpasst.
* Template-System über Composer (`pear/html_template_it`, neue Klasse `LMO_Template`) statt der mitgelieferten Dateien IT.php und ITX.php.
* Addon-Reiter, Viewer-Vorlagen und Ligalisten im Admin-Bereich erscheinen in fester (alphabetischer) Reihenfolge statt in der des Dateisystems.
* Wertung „beidseitiges Ergebnis“: Das Ergebnis zählt für beide Mannschaften vollständig aus Sicht der Heimmannschaft (Sieg/Unentschieden/Niederlage, Punkte, Minuspunkte). Bisher wurden nur Spiel und Tore gezählt.
* Straf-/Bonuspunkte und -tore „ab Spieltag X“ zählen erst, wenn Spieltag X Ergebnisse hat. Bisher wurden sie in der Gesamttabelle sofort eingerechnet.
* Die classlib rechnet Tabellen jetzt wie die Haupttabelle (direkter Vergleich, Strafen, beidseitiges Ergebnis). Minitabelle und Statistik zeigen damit dieselbe Tabelle.

### Deprecated


### Removed
* Installer (`install/`) entfernt, ebenso die nicht mehr benötigten PEAR-Dateien für FTP, Socket und Cache.

### Fixed
* Direkter Vergleich: Gleichstand wurde nur an der letzten Ziffer der Punkte erkannt (59 und 49 Punkte galten als gleich).
* Direkter Vergleich mit zehn und mehr punktgleichen Teams und Minuspunkten: Das beste Team stand am Ende der Gruppe.
* classlib: Spielende (n.V./i.E.) wurde aus der Ligadatei nicht gelesen und ging beim Speichern verloren.
* classlib, direkter Vergleich: Gleichstand am Tabellenende wurde nicht ausgewertet, ein zugesprochener Auswärtssieg falsch gebucht, und es wurden immer alle Spiele der Saison gewertet statt nur die der angezeigten Tabelle (Spieltag, Heim/Auswärts).
* classlib, Strafen: Strafe entfiel, wenn die Mannschaft am Spieltag des Strafbeginns spielfrei war; Bonus-Gegentore wurden mit falschem Vorzeichen verrechnet; Strafen zählten auch in Heim- und Auswärtstabelle.
* classlib, Speichern (`writeFile()`, genutzt von „Rückrunde erzeugen“ und „Spieltage verschieben“): Handicap-Reihenfolge, Titel und aktueller Spieltag gingen verloren; ein zweites Speichern im selben Aufruf brach ab; Ligen in Unterordnern wurden danach nicht gefunden (HTML-Export und Statistik ohne Daten).
* classlib, Statistik: Es wurden auch nicht gespielte Partien gezählt; die Serienanzeige überschrieb ihren eigenen Text.
* classlib: `ligaFussball::sortTable()` lief unter PHP 8 nur mit Warnungen, `liga::factory()` war nicht aufrufbar, `aktuellerSpieltag()` lieferte den folgenden Spieltag, `strAfterChar()`, `readLigaDir()` (Endung `.L98`) und `HTML_icon()` (Suche nach .jpg/.png mit Alternativtext) korrigiert.

### Security
* Cross Site Scripting/XSS Lücke geschlossen
* `lmo-rueckrunde.php` ließ sich ohne Anmeldung direkt aufrufen und schrieb dann die angegebene Ligadatei neu. Jetzt nur noch für angemeldete Admins.
* Tippspiel: Neue Passwörter werden mit Argon2id bzw. bcrypt gespeichert.


***
Expand Down Expand Up @@ -118,6 +159,48 @@ _Here we write changelog notes for the next version._
### Security


***
## [4.2.0] - 2026-10-10

_Here we had the changelogs for 4.2.0._

### Added
* First-time setup without the installer: on the first request the configuration is created from `config-default/`, and the first admin account is created through a form (texts available in all languages).
* Language selection in the footer of the admin area.
* Automated tests (PHPUnit, Docker, GitHub Action), see TESTING.md: golden master tests for public pages and the admin area, unit tests for the classlib, table comparison against 75 real leagues (OpenLigaDB, final tables from Wikipedia) and 10 constructed leagues.
* classlib: match days keep additional values of the league file (`spieltag::setParameter()` / `getParameter()`), e.g. the handicap order.

### Changed
* The minimum requirement for the web server is now PHP 8.0 (previously 7.4). The admin area shows a notice on older PHP versions.
* Improved the page source output of lmo-savehtml.php and lmo-savehtml1.php; the tables on both pages now have rounded corners.
* Template system via Composer (`pear/html_template_it`, new class `LMO_Template`) instead of the bundled files IT.php and ITX.php.
* Addon tabs, viewer templates and league lists in the admin area appear in a fixed (alphabetical) order instead of the file system order.
* Rating "result for both sides": the result counts completely for both teams from the home team's point of view (win/draw/loss, points, minus points). Previously only the match and the goals were counted.
* Penalty/bonus points and goals "from match day X" only count once match day X has results. Previously they were included in the overall table immediately.
* The classlib now calculates tables like the main table (head-to-head comparison, penalties, result for both sides). The mini table and the statistics therefore show the same table.

### Deprecated


### Removed
* Removed the installer (`install/`) and the PEAR files for FTP, socket and cache that are no longer needed.

### Fixed
* Head-to-head comparison: a tie was detected by the last digit of the points only (59 and 49 points were treated as equal).
* Head-to-head comparison with ten or more tied teams and minus points: the best team was placed last in its group.
* classlib: the end of a match (after extra time / penalties) was not read from the league file and was lost when saving.
* classlib, head-to-head comparison: ties at the bottom of the table were not evaluated, an awarded away win was booked incorrectly, and all matches of the season were counted instead of only those of the displayed table (match day, home/away).
* classlib, penalties: a penalty was dropped if the team had no match on the match day the penalty starts; bonus goals against were applied with the wrong sign; penalties also counted in the home and away tables.
* classlib, saving (`writeFile()`, used by "create second half of season" and "move match days"): handicap order, title and current match day were lost; a second save in the same request aborted; leagues in subfolders were not found afterwards (HTML export and statistics without data).
* classlib, statistics: unplayed matches were counted as well; the streak output overwrote its own text.
* classlib: `ligaFussball::sortTable()` only ran with warnings under PHP 8, `liga::factory()` could not be called, `aktuellerSpieltag()` returned the following match day; fixed `strAfterChar()`, `readLigaDir()` (extension `.L98`) and `HTML_icon()` (search for .jpg/.png with alternative text).

### Security
* Closed a cross site scripting (XSS) vulnerability.
* `lmo-rueckrunde.php` could be called directly without login and then rewrote the given league file. Now restricted to logged-in admins.
* Prediction game: new passwords are stored with Argon2id or bcrypt.


***
## [4.1.4] - 2024-10-20

Expand Down
60 changes: 60 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"name": "lmo/lmo_php8",
"description": "The Liga Manager Online (LMO for short) is free software for managing sports leagues with tables on the Internet.",
"type": "project",
"keywords": [
"LMO",
"Liga Manager Online",
"Sportligen verwalten"
],
"license": "GPL-2.0-only",
"authors": [
{
"name": "Rene Marth (joker)",
"homepage": "https://www.liga-manager-online.de",
"role": "Extension developer"
},
{
"name": "Henshingly",
"homepage": "https://www.vest-sport.de",
"role": "Developer"
}
],
"support": {
"forum": "https://www.liga-manager-online.org/forum/"
},
"require": {
"php": ">=8.0",
"pear/html_template_it": "dev-master"
},
"require-dev": {
"phpunit/phpunit": "^9.6"
},
"suggest": {
"ext-gd": "Fuer die Grafiken (Fieberkurve, Tippspiel-Grafiken)"
},
"autoload": {
"classmap": [
"lmo/includes/LmoTemplate.php"
]
},
"autoload-dev": {
"psr-4": {
"Lmo\\Tests\\GoldenMaster\\": "tests/GoldenMaster/",
"Lmo\\Tests\\Unit\\": "tests/Unit/",
"Lmo\\Tests\\RealData\\": "tests/RealData/"
}
},
"scripts": {
"test": "phpunit",
"test:record": "GOLDEN_MODE=record phpunit"
},
"config": {
"vendor-dir": "lmo/vendor",
"bin-dir": "vendor/bin",
"platform": {
"php": "8.0.30"
},
"sort-packages": true
}
}
Loading
Loading