Initial import of fitme3070.pt platform

Plain-PHP fleet platform with id.andmore.pt SSO. Wires shared/platform-tools
as a submodule (platform_update, backups, git/migration tools) like the other
platforms.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
andreandClaude Opus 4.8 committed 2026-06-12 10:44:58 +01:00
commit e68d357177
2330 files changed
+215968

No files matched your search

+78
View File
@@ -0,0 +1,78 @@
<?php
// ─── CodeIgniter 4 view-helper compatibility shim ────────────────────────────
// Lets the original fitme3070 view partials (site/partials/*) run byte-for-byte
// under the new plain-PHP structure. Only the helpers the ported templates
// actually use are implemented. base_url() comes from config/functions.php.
if (!defined('SITE_INCLUDES')) {
define('SITE_INCLUDES', dirname(__DIR__) . '/site/includes');
}
// <script src> / <link rel=stylesheet> tag builders (CI4 html helper).
function script_tag(string $src): string {
return '<script src="' . htmlspecialchars(base_url($src), ENT_QUOTES) . '"></script>' . "\n";
}
function link_tag(string $href, string $rel = 'stylesheet'): string {
return '<link rel="' . $rel . '" href="' . htmlspecialchars(base_url($href), ENT_QUOTES) . '">' . "\n";
}
function site_url(string $path = ''): string { return base_url($path); }
function esc($value, string $context = 'html'): string {
return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
}
// Render a partial like CI4's view(): extract $data + the shared page vars
// (info / navbar / current_uri_2 via $GLOBALS['_view_shared']) and return the
// buffered HTML. Lets partials read $info without threading it through callers.
function view(string $name, array $data = []): string {
$shared = $GLOBALS['_view_shared'] ?? [];
extract($shared);
extract($data);
ob_start();
include SITE_INCLUDES . '/' . $name . '.php';
return ob_get_clean();
}
// Minimal session() shim — the templates only read getFlashdata().
// Per-request singleton: the constructor's flash sweep therefore runs once per
// request, which is what makes flashdata actually "flash".
function session(): _FitSession {
static $s = null;
if ($s === null) $s = new _FitSession();
return $s;
}
class _FitSession {
// CI4-style flashdata lifecycle. A value set with setFlashdata() in request N
// (the POST handler, just before its redirect) must be readable in request
// N+1 (the redirect target) and then disappear — otherwise the banner sticks
// around forever, surviving reloads, because nothing ever clears it.
//
// We track an age marker per key: setFlashdata() marks it 'new'; on the next
// request the sweep ages 'new' → 'old' (still readable), and on the request
// after that it deletes anything 'old'. The sweep runs once, here, before any
// read or write this request (setFlashdata() is itself the first session()
// call in a POST handler, so the constructor always precedes it).
public function __construct() {
foreach ($_SESSION['_flash_age'] ?? [] as $k => $age) {
if ($age === 'old') {
unset($_SESSION['_flash'][$k], $_SESSION['_flash_age'][$k]);
} else {
$_SESSION['_flash_age'][$k] = 'old';
}
}
// Sweep orphans left by the previous (never-expiring) shim: any flash
// value with no age marker is stale and would otherwise stick forever.
foreach (array_keys($_SESSION['_flash'] ?? []) as $k) {
if (!isset($_SESSION['_flash_age'][$k])) unset($_SESSION['_flash'][$k]);
}
if (empty($_SESSION['_flash'])) unset($_SESSION['_flash']);
if (empty($_SESSION['_flash_age'])) unset($_SESSION['_flash_age']);
}
public function getFlashdata(string $key) { return $_SESSION['_flash'][$key] ?? null; }
public function setFlashdata(string $key, $val): void {
$_SESSION['_flash'][$key] = $val;
$_SESSION['_flash_age'][$key] = 'new';
}
public function get(string $key) { return $_SESSION[$key] ?? null; }
public function set(string $key, $val): void { $_SESSION[$key] = $val; }
}