64 lines
1.5 KiB
PHP
64 lines
1.5 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../config.php';
|
|
|
|
/**
|
|
* Returns a shared PDO connection for the current request.
|
|
*/
|
|
function db(): PDO
|
|
{
|
|
static $pdo = null;
|
|
if ($pdo !== null) {
|
|
return $pdo;
|
|
}
|
|
|
|
$pdo = new PDO(
|
|
sprintf('mysql:host=%s;dbname=%s;charset=utf8mb4', DB_HOST, DB_NAME),
|
|
DB_USER,
|
|
DB_PASS,
|
|
[
|
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
|
PDO::ATTR_EMULATE_PREPARES => false,
|
|
]
|
|
);
|
|
|
|
// Idempotent migrations — safe to run on every boot
|
|
$pdo->exec('ALTER TABLE delivery_log ADD COLUMN IF NOT EXISTS is_sandbox TINYINT(1) NOT NULL DEFAULT 0');
|
|
$pdo->exec("INSERT IGNORE INTO `system` (setting_name, setting_value) VALUES ('sandbox_mode', '0')");
|
|
|
|
return $pdo;
|
|
}
|
|
|
|
/**
|
|
* Sends a JSON response and exits.
|
|
*/
|
|
function json_out(mixed $data, int $status = 200): never
|
|
{
|
|
http_response_code($status);
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Decodes the request body as JSON and returns an array.
|
|
*/
|
|
function json_body(): array
|
|
{
|
|
$raw = file_get_contents('php://input');
|
|
if ($raw === false || $raw === '') {
|
|
return [];
|
|
}
|
|
return json_decode($raw, true) ?? [];
|
|
}
|
|
|
|
/**
|
|
* Sends a JSON error response and exits.
|
|
*/
|
|
function error_out(string $message, int $status = 400): never
|
|
{
|
|
json_out(['error' => $message], $status);
|
|
}
|