mirror of
https://github.com/wavelog/wavelog
synced 2026-08-13 18:41:16 -04:00
101 lines
3.3 KiB
PHP
101 lines
3.3 KiB
PHP
<?php
|
|
|
|
if (!defined('BASEPATH')) exit('No direct script access allowed');
|
|
|
|
/**
|
|
* API v2 - Response & Error helper
|
|
*
|
|
* Centralises the JSON envelope and HTTP status handling for the REST API v2
|
|
* so individual resource handlers never call json_encode/http_response_code
|
|
* directly. This keeps the wire format consistent across every endpoint.
|
|
*
|
|
* Envelope conventions (slim envelope, the HTTP status carries the semantics):
|
|
* success: { "data": <object|array>, "meta"?: { ... } }
|
|
* error: { "error": { "code": "<machine_code>", "message": "<human>", "details"?: ... } }
|
|
* no body: 204 No Content (e.g. after DELETE)
|
|
*/
|
|
class Api_v2_response {
|
|
|
|
protected $CI;
|
|
|
|
public function __construct() {
|
|
$this->CI =& get_instance();
|
|
}
|
|
|
|
/**
|
|
* Emit a success response wrapping $data in a "data" envelope.
|
|
*
|
|
* @param mixed $data The resource object or array to return.
|
|
* @param int $status HTTP status code (200, 201, ...).
|
|
* @param array $meta Optional top-level meta block (e.g. pagination).
|
|
* @param array $headers Optional extra response headers, name => value.
|
|
*/
|
|
public function respond($data, $status = 200, $meta = null, $headers = []) {
|
|
$default_meta = $this->build_meta();
|
|
$meta = is_array($meta) ? array_merge($default_meta, $meta) : $default_meta;
|
|
|
|
$payload = ['data' => $data];
|
|
$payload['meta'] = $meta;
|
|
$this->emit($payload, $status, $headers);
|
|
}
|
|
|
|
/**
|
|
* Build default top-level metadata for API v2 responses.
|
|
*/
|
|
protected function build_meta() {
|
|
$resource = trim((string) $this->CI->uri->segment(3));
|
|
|
|
return [
|
|
'timestamp' => gmdate('c'),
|
|
'resource' => $resource !== '' ? $resource : 'status', // if no resource is in the URL, the response is the same as the /api/v2/status endpoint
|
|
'method' => strtoupper((string) $this->CI->input->method(true)),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Emit an error response in the { "error": { ... } } envelope.
|
|
*
|
|
* @param string $code Machine-readable error code (e.g. "not_found").
|
|
* @param string $message Human-readable message.
|
|
* @param int $status HTTP status code (4xx/5xx).
|
|
* @param mixed $details Optional structured details (e.g. field errors).
|
|
* @param array $headers Optional extra response headers.
|
|
*/
|
|
public function error($code, $message, $status, $details = null, $headers = []) {
|
|
$error = ['code' => $code, 'message' => $message];
|
|
if ($details !== null) {
|
|
$error['details'] = $details;
|
|
}
|
|
$this->emit(['error' => $error], $status, $headers);
|
|
}
|
|
|
|
/**
|
|
* Emit a 204 No Content response with an empty body.
|
|
*
|
|
* @param array $headers Optional extra response headers.
|
|
*/
|
|
public function no_content($headers = []) {
|
|
$this->CI->output
|
|
->set_status_header(204)
|
|
->set_header('Access-Control-Allow-Origin: *');
|
|
foreach ($headers as $name => $value) {
|
|
$this->CI->output->set_header($name . ': ' . $value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Serialise a payload as JSON with the given status and headers.
|
|
*/
|
|
protected function emit($payload, $status, $headers) {
|
|
$this->CI->output
|
|
->set_status_header($status)
|
|
->set_content_type('application/json', 'utf-8')
|
|
->set_header('Access-Control-Allow-Origin: *');
|
|
|
|
foreach ($headers as $name => $value) {
|
|
$this->CI->output->set_header($name . ': ' . $value);
|
|
}
|
|
|
|
$this->CI->output->set_output(json_encode($payload));
|
|
}
|
|
}
|