X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=lib%2FAPI%2FContentType.php;h=929dc0c2c80907eea6ab59aba6dc489b98e1647b;hb=3958595e9ff27162ae918db1453ddecd4840d481;hp=e8f75dca1abbc03f343f1d507691fb34c67aef3e;hpb=8ef054b51c681e7822133b38f7c5ed9dd2a0f29c;p=m6w6%2Fseekat diff --git a/lib/API/ContentType.php b/lib/API/ContentType.php index e8f75dc..929dc0c 100644 --- a/lib/API/ContentType.php +++ b/lib/API/ContentType.php @@ -2,13 +2,26 @@ namespace seekat\API; -use http\Header; -use http\Message\Body; +use http\{ + Header, + Message\Body +}; + +use InvalidArgumentException; +use UnexpectedValueException; class ContentType { + /** + * API version + * @var int + */ static private $version = 3; - + + /** + * Content type handler map + * @var array + */ static private $types = [ "json" => "self::fromJson", "base64" => "self::fromBase64", @@ -17,22 +30,46 @@ class ContentType "html" => "self::fromData", "diff" => "self::fromData", "patch" => "self::fromData", + "text/plain"=> "self::fromData", ]; + /** + * Content type abbreviation + * @var string + */ private $type; + /** + * Register a content type handler + * @param string $type The content type (abbreviation) + * @param callable $handler The handler as function(Body $body):mixed; + */ static function register(string $type, callable $handler) { self::$types[$type] = $handler; } + /** + * Check whether a handler is registered for a particular content type + * @param string $type The (abbreviated) content type + * @return bool + */ static function registered(string $type) : bool { return isset(self::$types[$type]); } + /** + * Unregister a content type handler + * @param string $type + */ static function unregister(string $type) { unset(self::$types[$type]); } + /** + * Get/set the API version to use + * @param int $v if not null, update the API version + * @return int the previously set version + */ static function version(int $v = null) : int { $api = self::$version; if (isset($v)) { @@ -40,29 +77,48 @@ class ContentType } return $api; } - + + /** + * @param Body $json + * @return mixed + * @throws UnexpectedValueException + */ private static function fromJson(Body $json) { $decoded = json_decode($json); if (!isset($decoded) && json_last_error()) { - throw new \UnexpectedValueException("Could not decode JSON: ". + throw new UnexpectedValueException("Could not decode JSON: ". json_last_error_msg()); } return $decoded; } + /** + * @param Body $base64 + * @return string + * @throws UnexpectedValueException + */ private static function fromBase64(Body $base64) : string { if (false === ($decoded = base64_decode($base64))) { - throw new \UnexpectedValueExcpeption("Could not decode BASE64"); + throw new UnexpectedValueException("Could not decode BASE64"); } + return $decoded; } + /** + * @param Body $data + * @return string + */ private static function fromData(Body $data) : string { return (string) $data; } + /** + * @param Header $contentType + * @throws InvalidArgumentException + */ function __construct(Header $contentType) { if (strcasecmp($contentType->name, "Content-Type")) { - throw new \InvalidArgumentException( + throw new InvalidArgumentException( "Expected Content-Type header, got ". $contentType->name); } $vapi = static::version(); @@ -74,15 +130,25 @@ class ContentType )/x", "\\1", current(array_keys($contentType->getParams()->params))); } + /** + * Get the (abbreviated) content type name + * @return string + */ function getType() : string { return $this->type; } + /** + * Parse a response message's body according to its content type + * @param Body $data + * @return mixed + * @throws UnexpectedValueException + */ function parseBody(Body $data) { $type = $this->getType(); if (static::registered($type)) { return call_user_func(self::$types[$type], $data, $type); } - throw new \UnexpectedValueException("Unhandled content type '$type'"); + throw new UnexpectedValueException("Unhandled content type '$type'"); } }