main • app/helpers.php
<?php
function now(): string { return date('Y-m-d H:i:s'); }
function e(string $s): string { return htmlspecialchars($s, ENT_QUOTES, 'UTF-8'); }
function redirect(string $to): void {
header("Location: $to");
exit;
}
function require_int($v, $name='id'): int {
if (!is_numeric($v) || (int)$v <= 0) throw new RuntimeException("Invalid $name");
return (int)$v;
}
function safe_slug(string $s): string {
$s = strtolower(trim($s));
$s = preg_replace('/[^a-z0-9._-]+/', '-', $s);
$s = trim($s, '-');
if ($s === '') throw new RuntimeException("Invalid name");
return $s;
}
function safe_branch(string $b): string {
$b = trim($b);
if ($b === '') throw new RuntimeException("Invalid branch");
if (!preg_match('/^[a-zA-Z0-9._\/-]+$/', $b)) throw new RuntimeException("Invalid branch");
if (str_contains($b, '..')) throw new RuntimeException("Invalid branch");
return $b;
}
function safe_path(string $p): string {
$p = str_replace('\\', '/', (string)$p);
$p = ltrim($p, '/');
if ($p === '') return '';
if (str_contains($p, "\0") || str_contains($p, '..')) throw new RuntimeException("Invalid path");
if (!preg_match('/^[a-zA-Z0-9._\/-]+$/', $p)) throw new RuntimeException("Invalid path");
return $p;
}
function flash_set(string $key, string $msg): void {
start_session();
$_SESSION['_flash'][$key] = $msg;
}
function flash_get(string $key): ?string {
start_session();
if (!isset($_SESSION['_flash'][$key])) return null;
$m = $_SESSION['_flash'][$key];
unset($_SESSION['_flash'][$key]);
return $m;
}