File Manager

Current Directory: /home/astoriaah/www/plugins/system/shlib/shl_packages/api
Viewing File: /home/astoriaah/www/plugins/system/shlib/shl_packages/api/response.php
<?php /** * Shlib - programming library * * @author Yannick Gaultier * @copyright (c) Yannick Gaultier 2020 * @package shlib * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL * @version 0.4.0.716 * @date 2020-12-07 */ defined('_JEXEC') or die; /** * HTTP response as enveloped json. * **/ class ShlApi_Response extends \ShlBase { /** * @var array Version of this API. */ private $apiVersion = '@build_api_version_build@'; /** * @var string The version of the handling route. */ private $version; /** * @var string Holds the request id. */ private $requestId; /** * @var string Holds the response HTTP status code. */ private $status; /** * @var array Data to be sent in the "data" field of the response. */ private $data; /** * @var array Meta data to be sent in the response. */ private $meta; /** * @var array Stores error descriptors. */ private $errors; /** * @var array Stores links. */ private $links; /** * @var array Associative array of headers to be sent with the response. */ private $headers = array(); /** * @var int A unix timestamp of last modification of the resource. */ private $lastModified; /** * @var array The raw assembled response, before being output. */ private $response = array(); /** * @var string The response body, as enveloped json. */ private $responseBody = ''; /** * \ShlApi_Response constructor. * * @param string Id of the request we are responding to. * @param string Handler api version; */ public function __construct($requestId, $version) { $this->requestId = $requestId; $this->version = $version; } /** * Setter for the response HTTP status code. * * @param int $status The status code to use. * @param int $status The status code to use. */ public function withStatus($status) { $this->status = $status; return $this; } /** * @param array $data Data to use in response */ public function withData($data) { $this->data = $data; return $this; } /** * Set arbitrary meta data about the response. * * @param array $meta Associative array of arbitrary meta data. * * @return $this */ public function withMeta($meta) { $this->meta = wbArrayMerge( $this->meta, $meta ); return $this; } /** * Set links related to the response. * * @param array $links Array of links. * * @return $this */ public function withLinks($links) { $this->links = wbArrayMerge( $this->links, $links ); return $this; } /** * Set the list of headers to output. * * @param arary $headers Associate array of headers name => headers value * * @return $this */ public function withHeaders($headers) { $this->headers = wbArrayMerge( $this->headers, $headers ); return $this; } /** * Set the date/time at which the resource was last modified * * @param int $lastModified A unix timestamp. */ public function withLastModified($lastModified) { $this->lastModified = $lastModified; return $this; } /** * Set the list of errors to output. * * @param array $errors Array of errors descriptors. * array( * 'code' => 123, * 'message' => 'Some error message' * ) * * @return $this */ public function withErrors($errors) { $this->errors = wbArrayMerge( $this->errors, $errors ); return $this; } /** * Output the response and exit. */ public function render() { $this->build(); // and prepare output $this->responseBody = $this->envelope( $this->response ); $this->responseBody = $this->encode( $this->responseBody ); \ShlSystem_Http::render( $this->status, $this->responseBody, 'application/json', $this->headers ); } /** * Return response data only, without exiting. */ public function renderData() { $this->build(); $responseData = array( 'status' => $this->status, 'data' => $this->response, 'headers' => $this->headers ); return $responseData; } /** * Merge default response values with provided values to build a full response. * * @param array $response * @param array $parsedRequests * * @return array */ public function build() { if (empty($this->status)) { $this->status = \ShlSystem_Http::RETURN_OK; } // errors or data, but not both if (!empty($this->errors)) { $this->data = null; } else { $this->errors = null; } $this->response = array( 'data' => $this->data, 'links' => $this->links, 'errors' => $this->errors, 'meta' => $this->meta, ); // finally insert version info and nosniff $this->withHeaders( array( 'x-wbl-api-version' => $this->apiVersion, 'x-wbl-api-id' => $this->requestId, 'X-Content-Type-Options' => 'nosniff' ) ); // Return the response data, can be used directly // from php, without an HTTP response. foreach ($this->response as $key => $value) { if ('data' != $key && empty($value)) { unset($this->response[$key]); } } // Etag the response if (\ShlSystem_Http::isSuccess($this->status)) { $this->withHeaders( array('ETag' => '"' . $this->hash($this->response) . '"') ); $lastModified = $this->getLastModified(); if (!empty($lastModified)) { $this->withHeaders( array('Last-Modified' => $lastModified) ); } } return $this->response; } /** * Wraps content in an envelope for json security purpose. * * @param array $content * * @return string */ protected function envelope($content) { $envelopedContent = new stdClass; foreach ($content as $key => $value) { $envelopedContent->{$key} = $value; } return $envelopedContent; } /** * Json encode an input string, without escaping slashed, if PHP version allows. * * @param string $content * * @return string| null */ private function encode($content) { if (is_null($content)) { return $content; } $options = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : null; $options = defined('JSON_UNESCAPED_SLASHES') ? JSON_UNESCAPED_SLASHES | $options : $options; return json_encode( $content, $options ); } /** * Builds a date time string suitable for use in Last-modified header. * * @return string */ private function getLastModified() { $date = new DateTime( 'now', new DateTimeZone('UTC') ); if (!empty($this->lastModified)) { $date->setTimestamp( $this->lastModified ); } return $date->format(' D, d M Y H:i:s e'); } /** * Produces a unique hash of a piece of data. * * @param mixed $content * * @return string */ private function hash($content) { return sha1( serialize($content) ); } }