- Contactos: nova página no backoffice (fitme3070_info) e 964 201 137 como telefone principal; o telefone secundário só aparece quando existe. - Equipa: título, aptidões/funções e formações; o cartão mostra foto, nome e título e abre um cartão horizontal de detalhe (hover no desktop, toque no telemóvel) sem mexer na grelha. - Mensalidades: cartões editáveis com um destaque, modal de inscrição que guarda o pedido (RGPD + estado + campos reservados para o CRM) e avisa o ginásio por e-mail; lista de pedidos com estados, notas e CSV. - Reviews Google via Places API (New), filtradas por classificação mínima e em cache configurável; página de configuração com pesquisa do Place ID. - Assets com ?v=<mtime>: site/assets é servido com cache imutável de 1 ano. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
87 lines
4.2 KiB
PHP
87 lines
4.2 KiB
PHP
<?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).
|
|
// site/assets is served with a one-year immutable Cache-Control, so local files
|
|
// carry their mtime as ?v= — an edited style.css/main.js gets a new URL instead
|
|
// of staying stuck in returning visitors' caches.
|
|
function _asset_versioned(string $path): string {
|
|
$file = dirname(__DIR__) . '/' . ltrim($path, '/');
|
|
if (strpos($path, '?') !== false || preg_match('~^https?://~', $path) || !is_file($file)) return base_url($path);
|
|
return base_url($path) . '?v=' . filemtime($file);
|
|
}
|
|
function script_tag(string $src): string {
|
|
return '<script src="' . htmlspecialchars(_asset_versioned($src), ENT_QUOTES) . '"></script>' . "\n";
|
|
}
|
|
function link_tag(string $href, string $rel = 'stylesheet'): string {
|
|
return '<link rel="' . $rel . '" href="' . htmlspecialchars(_asset_versioned($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; }
|
|
}
|