Zwei vorbestehende, bislang rote Pruefungen behoben.
1) PHP lief in UTC, MySQL in der System-Zeitzone (hier CEST, +2h). Ueberall,
wo ein in PHP berechneter Zeitstempel gegen MySQL NOW() verglichen wird,
liefen die Uhren dadurch gegeneinander:
- Hinweise mit kurzer Restlaufzeit galten sofort als abgelaufen
(notices: valid_from = NOW() aus MySQL, valid_until aus PHP date()).
- Auth-Token (Passwort-Reset, E-Mail-Verifikation) liefen bis zu 2h zu
frueh ab (expires_at aus PHP date(), Pruefung gegen NOW()).
bootstrap.php pinnt die PHP-Zeitzone jetzt deterministisch aus
APP_TIMEZONE (Standard Europe/Berlin), app_db_pdo() setzt die DB-Session
per numerischem Offset auf dieselbe Zeit. Damit stimmen beide Uhren
ueberein. Behebt check-m8-tenant-isolation (11/1 -> 12/0).
2) check-m3-settings-flow stammte aus M3 und lieferte nicht die spaeter
hinzugekommenen Pflichtfelder (pdf_row_height_px,
payment_reminder_interval_days). Dadurch schlug bereits das Update fehl und
alle Folge-Assertions kippten. Der Test sendet jetzt den vollstaendigen
Feldsatz wie das Einstellungsformular und prueft die beiden Felder mit.
Die Update-Funktion selbst war korrekt (7/6 -> 15/0).
Voller Regressionslauf gruen: http-smoke 33/0, role-matrix 55/0,
tenant-isolation 12/0, m3-auth 9/0, password-email 14/0, settings 15/0,
tenant-resolution 12/0, billing 10/0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
41 lines
1.2 KiB
PHP
41 lines
1.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/bootstrap.php';
|
|
|
|
function app_db_pdo(): PDO
|
|
{
|
|
static $pdo = null;
|
|
|
|
if ($pdo instanceof PDO) {
|
|
return $pdo;
|
|
}
|
|
|
|
$host = app_env('DB_HOST', '');
|
|
$database = app_env('DB_NAME', '');
|
|
$user = app_env('DB_USER', '');
|
|
$password = app_env('DB_PASS', '');
|
|
$port = app_env('DB_PORT', '3306');
|
|
|
|
if ($host === '' || $database === '' || $user === '') {
|
|
throw new RuntimeException('Database environment is incomplete.');
|
|
}
|
|
|
|
$dsn = sprintf('mysql:host=%s;port=%s;dbname=%s;charset=utf8mb4', $host, $port, $database);
|
|
$pdo = new PDO($dsn, $user, $password ?? '', [
|
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
|
PDO::ATTR_EMULATE_PREPARES => true,
|
|
]);
|
|
|
|
// DB-Session auf denselben Offset wie die (in bootstrap.php gepinnte)
|
|
// PHP-Zeitzone setzen, damit MySQL NOW() und PHP-Zeitstempel
|
|
// uebereinstimmen. Numerischer Offset, damit keine MySQL-Zeitzonentabellen
|
|
// noetig sind.
|
|
$offset = (new DateTimeImmutable('now'))->format('P');
|
|
$pdo->exec("SET time_zone = '{$offset}'");
|
|
|
|
return $pdo;
|
|
}
|