b2eb5fbc0690f74af90b67214d37a6ca93b452a1
[m6w6/seekat] / lib / API / ContentType.php
1 <?php
2
3 namespace seekat\API;
4
5 use http\Header;
6 use http\Message\Body;
7
8 class ContentType
9 {
10 static private $version = 3;
11
12 static private $types = [
13 "json" => "self::fromJson",
14 "base64" => "self::fromBase64",
15 "sha" => "self::fromData",
16 "raw" => "self::fromData",
17 "html" => "self::fromData",
18 "diff" => "self::fromData",
19 "patch" => "self::fromData",
20 "text/plain"=> "self::fromData",
21 ];
22
23 private $type;
24
25 static function register(string $type, callable $handler) {
26 self::$types[$type] = $handler;
27 }
28
29 static function registered(string $type) : bool {
30 return isset(self::$types[$type]);
31 }
32
33 static function unregister(string $type) {
34 unset(self::$types[$type]);
35 }
36
37 static function version(int $v = null) : int {
38 $api = self::$version;
39 if (isset($v)) {
40 self::$version = $v;
41 }
42 return $api;
43 }
44
45 private static function fromJson(Body $json) {
46 $decoded = json_decode($json);
47 if (!isset($decoded) && json_last_error()) {
48 throw new \UnexpectedValueException("Could not decode JSON: ".
49 json_last_error_msg());
50 }
51 return $decoded;
52 }
53
54 private static function fromBase64(Body $base64) : string {
55 if (false === ($decoded = base64_decode($base64))) {
56 throw new \UnexpectedValueExcpeption("Could not decode BASE64");
57 }
58 }
59
60 private static function fromData(Body $data) : string {
61 return (string) $data;
62 }
63
64 function __construct(Header $contentType) {
65 if (strcasecmp($contentType->name, "Content-Type")) {
66 throw new \InvalidArgumentException(
67 "Expected Content-Type header, got ". $contentType->name);
68 }
69 $vapi = static::version();
70 $this->type = preg_replace("/
71 (?:application\/(?:vnd\.github(?:\.v$vapi)?)?)
72 (?|
73 \. ([^.+]+)
74 | (?:\.[^.+]+)?\+? (json)
75 )/x", "\\1", current(array_keys($contentType->getParams()->params)));
76 }
77
78 function getType() : string {
79 return $this->type;
80 }
81
82 function parseBody(Body $data) {
83 $type = $this->getType();
84 if (static::registered($type)) {
85 return call_user_func(self::$types[$type], $data, $type);
86 }
87 throw new \UnexpectedValueException("Unhandled content type '$type'");
88 }
89 }