1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
<?php
namespace RESTAPI;
/**
* @author Jan-Hendrik Willms <tleilax+studip@gmail.com>
* @author <mlunzena@uos.de>
* @license GPL 2 or later
* @since Stud.IP 3.0
* @deprecated Since Stud.IP 5.0. Will be removed in Stud.IP 5.2.
*/
class UriTemplate
{
public $uri_template;
public $conditions;
public function __construct($uri_template, $conditions = [])
{
$this->uri_template = $uri_template;
$this->conditions = $conditions;
}
/**
* Tests whether an uri matches a template.
*
* The template may contain placeholders by prefixing an appropriate,
* unique placeholder name with a colon (:).
*
* <code>$template = '/hello/:name';</code>
*
* If the uri matches the template, all evaluated placeholders will
* be stored in the parameters array.
*
* @param String $uri The uri to test
* @param array $parameters Stores evaluated parameters on match (optional)
*
* @return bool Returns true if the uri matches the template
*/
public function match($uri, &$parameters = null)
{
// Initialize parameters array
$parameters = [];
// Split and normalize uri and template
$given = array_filter(explode('/', $uri), 'mb_strlen');
$rules = array_filter(explode('/', $this->uri_template));
// Leave if uri and template do not contain the same number of
// elements
if (count($given) !== count($rules)) {
return false;
}
// Combine uri and template element-wise (simplifies iteration)
$combined = array_combine($rules, $given);
// Iterate over uri and template and compare element by element
foreach ($combined as $rule => $actual) {
if ($rule[0] === ':') {
// Rule is a placeholder
$parameter_name = mb_substr($rule, 1);
if (isset($this->conditions[$parameter_name])
&& !preg_match($this->conditions[$parameter_name], $actual)) {
return false;
}
$parameters[$parameter_name] = $actual;
} elseif ($actual !== $rule) {
// Elements do not match
$parameters = [];
return false;
}
}
return true;
}
public function inject($params)
{
// Initialize parameters array
$parameters = [];
// Split and normalize template
$rules = array_filter(explode('/', $this->uri_template));
foreach ($rules as &$rule) {
// Rule is a placeholder
if ($rule[0] === ':') {
$parameter_name = mb_substr($rule, 1);
if (!isset($params[$parameter_name])) {
$reason = sprintf('UriTemplate parameter :%s missing.',
htmlReady($parameter_name));
throw new \RuntimeException($reason);
}
$actual = $params[$parameter_name];
if (isset($this->conditions[$parameter_name])
&& !preg_match($this->conditions[$parameter_name], $actual)) {
$reason = sprintf('UriTemplate parameter :%s did not satisfy its condition.',
htmlReady($parameter_name));
throw new \RuntimeException($reason);
}
$rule = htmlReady($actual);
}
}
return join('/', $rules);
}
}
|