parent
e20d695fc3
commit
e4cdba842c
@ -0,0 +1,13 @@ |
|||||||
|
<?php |
||||||
|
// SPDX-License-Identifier: EUPL-1.2 |
||||||
|
// Authors: see README.md |
||||||
|
|
||||||
|
namespace SeaCMS\Api; |
||||||
|
|
||||||
|
use Exception; |
||||||
|
|
||||||
|
/** |
||||||
|
* Exception for bad http method |
||||||
|
*/ |
||||||
|
class BadMethodException extends Exception |
||||||
|
{} |
@ -0,0 +1,206 @@ |
|||||||
|
<?php |
||||||
|
// SPDX-License-Identifier: EUPL-1.2 |
||||||
|
// Authors: see README.md |
||||||
|
|
||||||
|
namespace SeaCMS\Api; |
||||||
|
|
||||||
|
use JsonSerializable; |
||||||
|
use Throwable; |
||||||
|
|
||||||
|
/** |
||||||
|
* Response for http response |
||||||
|
*/ |
||||||
|
class JsonResponse implements JsonSerializable |
||||||
|
{ |
||||||
|
|
||||||
|
/** |
||||||
|
* HTTP Codes |
||||||
|
* @var array |
||||||
|
*/ |
||||||
|
const HTTP_CODES = [ |
||||||
|
200 => 'OK', |
||||||
|
301 => 'Moved Permanently', |
||||||
|
302 => 'Found', |
||||||
|
304 => 'Not Modified', |
||||||
|
307 => 'Temporary Redirect', |
||||||
|
308 => 'Permanent Redirect', |
||||||
|
400 => 'Bad Request', |
||||||
|
401 => 'Unauthorized', |
||||||
|
403 => 'Forbidden', |
||||||
|
404 => 'Not Found', |
||||||
|
405 => 'Method Not Allowed', |
||||||
|
406 => 'Not Acceptable', |
||||||
|
408 => 'Request Timeout', |
||||||
|
500 => 'Internal Server Error', |
||||||
|
501 => 'Not Implemented', |
||||||
|
503 => 'Service Unavailable', |
||||||
|
]; |
||||||
|
|
||||||
|
/** |
||||||
|
* HTTP CODE |
||||||
|
* @var int |
||||||
|
*/ |
||||||
|
protected $code; |
||||||
|
/** |
||||||
|
* content as array |
||||||
|
* @var array |
||||||
|
*/ |
||||||
|
protected $content; |
||||||
|
/** |
||||||
|
* headers |
||||||
|
* @var array |
||||||
|
*/ |
||||||
|
protected $headers; |
||||||
|
|
||||||
|
|
||||||
|
public function __construct(int $code, array $content, array $headers = []){ |
||||||
|
$this->code = array_key_exists($code, self::HTTP_CODES) ? $code : 501; // default |
||||||
|
$this->content = $content; |
||||||
|
$this->headers = array_merge([ |
||||||
|
'Content-Type' => 'application/json', |
||||||
|
'Access-Control-Allow-Origin' => '*', |
||||||
|
'Access-Control-Allow-Credentials' => 'true', |
||||||
|
'Access-Control-Allow-Headers' => 'X-Requested-With, Location, Slug, Accept, Content-Type', |
||||||
|
'Access-Control-Expose-Headers' => 'Location, Slug, Accept, Content-Type', |
||||||
|
'Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, DELETE, PUT, PATCH', |
||||||
|
'Access-Control-Max-Age' => '86400' |
||||||
|
], $headers); |
||||||
|
$this->preparedOutput = ''; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* merge in content |
||||||
|
* @param array $newContent |
||||||
|
* @return $this |
||||||
|
*/ |
||||||
|
public function mergeInContent(array $newContent){ |
||||||
|
$this->content = array_merge( |
||||||
|
$this->content, |
||||||
|
$newContent |
||||||
|
); |
||||||
|
} |
||||||
|
/** |
||||||
|
* prepend in content |
||||||
|
* @param array $newContent |
||||||
|
* @return $this |
||||||
|
*/ |
||||||
|
protected function prependInContent(array $newContent){ |
||||||
|
$this->content = array_merge( |
||||||
|
$newContent, |
||||||
|
$this->content |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* set code |
||||||
|
* @param int |
||||||
|
*/ |
||||||
|
public function setCode(int $code) |
||||||
|
{ |
||||||
|
$this->code = $code; |
||||||
|
} |
||||||
|
|
||||||
|
/* === Getters === */ |
||||||
|
/** |
||||||
|
* return code |
||||||
|
* @return int |
||||||
|
*/ |
||||||
|
public function getCode(): int |
||||||
|
{ |
||||||
|
return $this->code; |
||||||
|
} |
||||||
|
/** |
||||||
|
* return content |
||||||
|
* @return array |
||||||
|
*/ |
||||||
|
public function getContent(): array |
||||||
|
{ |
||||||
|
return $this->content; |
||||||
|
} |
||||||
|
|
||||||
|
/* === === */ |
||||||
|
|
||||||
|
/** |
||||||
|
* Sends HTTP headers. |
||||||
|
* |
||||||
|
* @return $this |
||||||
|
*/ |
||||||
|
public function sendHeaders(): JsonResponse |
||||||
|
{ |
||||||
|
// headers have already been sent by the developer |
||||||
|
if (!headers_sent()) { |
||||||
|
|
||||||
|
// headers |
||||||
|
foreach ($this->headers as $name => $value) { |
||||||
|
header($name.': '.$value); |
||||||
|
} |
||||||
|
|
||||||
|
// status |
||||||
|
$statusText = self::HTTP_CODES[$this->code]; |
||||||
|
header("HTTP/1.0 {$this->code} $statusText"); |
||||||
|
} |
||||||
|
|
||||||
|
return $this; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* send headers and return output |
||||||
|
* @return string |
||||||
|
*/ |
||||||
|
public function send(): string |
||||||
|
{ |
||||||
|
return $this->preparedOutput()->prepareStatusText()->sendHeaders()->returnContent(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* check if output is JSONSerializable |
||||||
|
* @return JsonResponse $this |
||||||
|
*/ |
||||||
|
protected function preparedOutput(): JsonResponse |
||||||
|
{ |
||||||
|
try { |
||||||
|
json_encode($this->content); |
||||||
|
} catch (Throwable $th) { |
||||||
|
$this->code = 500; |
||||||
|
$this->content = ['code' => 500, 'reason' =>"Not possible to JSONSerialize content"]; |
||||||
|
} |
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* prepare statusText |
||||||
|
* @return JsonResponse $this |
||||||
|
*/ |
||||||
|
protected function prepareStatusText(): JsonResponse |
||||||
|
{ |
||||||
|
if (!array_key_exists($this->code,self::HTTP_CODES)){ |
||||||
|
$previousCode = intval($this->code); |
||||||
|
$this->code = 501; |
||||||
|
$this->prependInContent(['code' => 501, 'reason' =>"Wanted code ($previousCode) is not implemented !"]); |
||||||
|
} |
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* return content as String |
||||||
|
* @return string |
||||||
|
*/ |
||||||
|
protected function returnContent(): string |
||||||
|
{ |
||||||
|
return json_encode($this->getContent()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* export class as array |
||||||
|
* @return array |
||||||
|
*/ |
||||||
|
public function jsonSerialize(): mixed |
||||||
|
{ |
||||||
|
return [ |
||||||
|
'code' => $this->getCode(), |
||||||
|
'content' => $this->getContent(), |
||||||
|
'headers' => $this->headers, |
||||||
|
]; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
<?php |
||||||
|
// SPDX-License-Identifier: EUPL-1.2 |
||||||
|
// Authors: see README.md |
||||||
|
|
||||||
|
namespace SeaCMS\Api; |
||||||
|
|
||||||
|
use Exception; |
||||||
|
|
||||||
|
/** |
||||||
|
* Exception when route not found |
||||||
|
*/ |
||||||
|
class NotFoundRouteException extends Exception |
||||||
|
{} |
Loading…
Reference in new issue