false, 'error' => $message ], $extra), $status); } function ensure_dirs() { foreach ([UPLOAD_DIR, RECEIPT_DIR, GENERATED_DIR, DMG_DIR] as $dir) { if (!is_dir($dir)) { mkdir($dir, 0775, true); } } } function safe_id() { return bin2hex(random_bytes(8)); } function shell_arg($s) { return escapeshellarg($s); } function read_json_file($path) { if (!file_exists($path)) return null; $raw = file_get_contents($path); return json_decode($raw, true); } function write_json_file($path, $data) { file_put_contents($path, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); }