update to PHP-8.1
[m6w6/seekat] / lib / API / Links.php
1 <?php
2
3 namespace seekat\API;
4
5 use http\{Header, Params, QueryString, Url};
6 use seekat\Exception\UnexpectedValueException;
7
8 final class Links {
9 /**
10 * Parsed "Link" relations
11 * @var array<string, Url>
12 */
13 private $relations = [];
14
15 /**
16 * Parse the hypermedia link header
17 *
18 * @param ?Header $links The Link header
19 * @throws UnexpectedValueException
20 */
21 function __construct(Header $links = null) {
22 if ($links) {
23 if (strcasecmp($links->name, "Link")) {
24 throw new UnexpectedValueException("Expected 'Link' header, got: '{$links->name}'");
25 }
26 $params = new Params($links->value, ",", ";", "=",
27 Params::PARSE_RFC5988 | Params::PARSE_ESCAPED);
28 if ($params->params) {
29 foreach ($params->params as $link => $param) {
30 $this->relations[$param["arguments"]["rel"]] = new Url($link);
31 }
32 }
33 }
34 }
35
36 /**
37 * Receive the link header's parsed relations
38 *
39 * @return array<string, Url>
40 */
41 function getRelations() : array {
42 return $this->relations;
43 }
44
45 /**
46 * Get the URL of the link's "next" relation
47 *
48 * Returns the link's "last" relation if it exists and "next" is not set.
49 */
50 function getNext() : ?Url {
51 if (isset($this->relations["next"])) {
52 return $this->relations["next"];
53 }
54 if (isset($this->relations["last"])) {
55 return $this->relations["last"];
56 }
57 return null;
58 }
59
60 /**
61 * Get the URL of the link's "prev" relation
62 *
63 * Returns the link's "first" relation if it exists and "prev" is not set.
64 */
65 function getPrev() : ?Url {
66 if (isset($this->relations["prev"])) {
67 return $this->relations["prev"];
68 }
69 if (isset($this->relations["first"])) {
70 return $this->relations["first"];
71 }
72 return null;
73 }
74
75 /**
76 * Get the URL of the link's "last" relation
77 */
78 function getLast() : ?Url {
79 if (isset($this->relations["last"])) {
80 return $this->relations["last"];
81 }
82 return null;
83 }
84
85 /**
86 * Get the URL of the link's "first" relation
87 */
88 function getFirst() : ?Url {
89 if (isset($this->relations["first"])) {
90 return $this->relations["first"];
91 }
92 return null;
93 }
94
95 /**
96 * Get the page sequence of the current link's relation
97 *
98 * @param string $which The relation of which to extract the page
99 * @return int The current page sequence
100 */
101 function getPage($which) : int {
102 if (($link = $this->{"get$which"}())) {
103 $url = new Url($link, null, 0);
104 $qry = new QueryString($url->query);
105 return $qry->getInt("page", 1);
106 }
107 return 1;
108 }
109 }