Commit | Line | Data |
---|---|---|
44d399bc S |
1 | <?php |
2 | /** | |
3 | * Zend Framework (http://framework.zend.com/) | |
4 | * | |
5 | * @link http://github.com/zendframework/zf2 for the canonical source repository | |
6 | * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) | |
7 | * @license http://framework.zend.com/license/new-bsd New BSD License | |
8 | */ | |
9 | ||
10 | namespace Zend\Mvc\Router\Http; | |
11 | ||
12 | use Traversable; | |
13 | use Zend\Mvc\Router\Exception; | |
14 | use Zend\Stdlib\ArrayUtils; | |
15 | use Zend\Stdlib\RequestInterface as Request; | |
16 | ||
17 | /** | |
18 | * Wildcard route. | |
19 | */ | |
20 | class Wildcard implements RouteInterface | |
21 | { | |
22 | /** | |
23 | * Delimiter between keys and values. | |
24 | * | |
25 | * @var string | |
26 | */ | |
27 | protected $keyValueDelimiter; | |
28 | ||
29 | /** | |
30 | * Delimiter before parameters. | |
31 | * | |
32 | * @var array | |
33 | */ | |
34 | protected $paramDelimiter; | |
35 | ||
36 | /** | |
37 | * Default values. | |
38 | * | |
39 | * @var array | |
40 | */ | |
41 | protected $defaults; | |
42 | ||
43 | /** | |
44 | * List of assembled parameters. | |
45 | * | |
46 | * @var array | |
47 | */ | |
48 | protected $assembledParams = []; | |
49 | ||
50 | /** | |
51 | * Create a new wildcard route. | |
52 | * | |
53 | * @param string $keyValueDelimiter | |
54 | * @param string $paramDelimiter | |
55 | * @param array $defaults | |
56 | */ | |
57 | public function __construct($keyValueDelimiter = '/', $paramDelimiter = '/', array $defaults = []) | |
58 | { | |
59 | $this->keyValueDelimiter = $keyValueDelimiter; | |
60 | $this->paramDelimiter = $paramDelimiter; | |
61 | $this->defaults = $defaults; | |
62 | } | |
63 | ||
64 | /** | |
65 | * factory(): defined by RouteInterface interface. | |
66 | * | |
67 | * @see \Zend\Mvc\Router\RouteInterface::factory() | |
68 | * @param array|Traversable $options | |
69 | * @return Wildcard | |
70 | * @throws Exception\InvalidArgumentException | |
71 | */ | |
72 | public static function factory($options = []) | |
73 | { | |
74 | if ($options instanceof Traversable) { | |
75 | $options = ArrayUtils::iteratorToArray($options); | |
76 | } elseif (!is_array($options)) { | |
77 | throw new Exception\InvalidArgumentException(sprintf( | |
78 | '%s expects an array or Traversable set of options', | |
79 | __METHOD__ | |
80 | )); | |
81 | } | |
82 | ||
83 | if (!isset($options['key_value_delimiter'])) { | |
84 | $options['key_value_delimiter'] = '/'; | |
85 | } | |
86 | ||
87 | if (!isset($options['param_delimiter'])) { | |
88 | $options['param_delimiter'] = '/'; | |
89 | } | |
90 | ||
91 | if (!isset($options['defaults'])) { | |
92 | $options['defaults'] = []; | |
93 | } | |
94 | ||
95 | return new static($options['key_value_delimiter'], $options['param_delimiter'], $options['defaults']); | |
96 | } | |
97 | ||
98 | /** | |
99 | * match(): defined by RouteInterface interface. | |
100 | * | |
101 | * @see \Zend\Mvc\Router\RouteInterface::match() | |
102 | * @param Request $request | |
103 | * @param integer|null $pathOffset | |
104 | * @return RouteMatch|null | |
105 | */ | |
106 | public function match(Request $request, $pathOffset = null) | |
107 | { | |
108 | if (!method_exists($request, 'getUri')) { | |
109 | return; | |
110 | } | |
111 | ||
112 | $uri = $request->getUri(); | |
113 | $path = $uri->getPath() ?: ''; | |
114 | ||
115 | if ($path === '/') { | |
116 | $path = ''; | |
117 | } | |
118 | ||
119 | if ($pathOffset !== null) { | |
120 | $path = substr($path, $pathOffset) ?: ''; | |
121 | } | |
122 | ||
123 | $matches = []; | |
124 | $params = explode($this->paramDelimiter, $path); | |
125 | ||
126 | if (count($params) > 1 && ($params[0] !== '' || end($params) === '')) { | |
127 | return; | |
128 | } | |
129 | ||
130 | if ($this->keyValueDelimiter === $this->paramDelimiter) { | |
131 | $count = count($params); | |
132 | ||
133 | for ($i = 1; $i < $count; $i += 2) { | |
134 | if (isset($params[$i + 1])) { | |
135 | $matches[rawurldecode($params[$i])] = rawurldecode($params[$i + 1]); | |
136 | } | |
137 | } | |
138 | } else { | |
139 | array_shift($params); | |
140 | ||
141 | foreach ($params as $param) { | |
142 | $param = explode($this->keyValueDelimiter, $param, 2); | |
143 | ||
144 | if (isset($param[1])) { | |
145 | $matches[rawurldecode($param[0])] = rawurldecode($param[1]); | |
146 | } | |
147 | } | |
148 | } | |
149 | ||
150 | return new RouteMatch(array_merge($this->defaults, $matches), strlen($path)); | |
151 | } | |
152 | ||
153 | /** | |
154 | * assemble(): Defined by RouteInterface interface. | |
155 | * | |
156 | * @see \Zend\Mvc\Router\RouteInterface::assemble() | |
157 | * @param array $params | |
158 | * @param array $options | |
159 | * @return mixed | |
160 | */ | |
161 | public function assemble(array $params = [], array $options = []) | |
162 | { | |
163 | $elements = []; | |
164 | $mergedParams = array_merge($this->defaults, $params); | |
165 | $this->assembledParams = []; | |
166 | ||
167 | if ($mergedParams) { | |
168 | foreach ($mergedParams as $key => $value) { | |
169 | $elements[] = rawurlencode($key) . $this->keyValueDelimiter . rawurlencode($value); | |
170 | ||
171 | $this->assembledParams[] = $key; | |
172 | } | |
173 | ||
174 | return $this->paramDelimiter . implode($this->paramDelimiter, $elements); | |
175 | } | |
176 | ||
177 | return ''; | |
178 | } | |
179 | ||
180 | /** | |
181 | * getAssembledParams(): defined by RouteInterface interface. | |
182 | * | |
183 | * @see RouteInterface::getAssembledParams | |
184 | * @return array | |
185 | */ | |
186 | public function getAssembledParams() | |
187 | { | |
188 | return $this->assembledParams; | |
189 | } | |
190 | } |