1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* TUrlMapping, TUrlMappingPattern and TUrlMappingPatternSecureConnection class file. |
5
|
|
|
* |
6
|
|
|
* @author Wei Zhuo <weizhuo[at]gamil[dot]com> |
7
|
|
|
* @link https://github.com/pradosoft/prado |
8
|
|
|
* @license https://github.com/pradosoft/prado/blob/master/LICENSE |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace Prado\Web; |
12
|
|
|
|
13
|
|
|
use Prado\Collections\TAttributeCollection; |
14
|
|
|
use Prado\Exceptions\TConfigurationException; |
15
|
|
|
use Prado\Exceptions\TInvalidDataValueException; |
16
|
|
|
use Prado\Prado; |
17
|
|
|
use Prado\TPropertyValue; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* TUrlMappingPattern class. |
21
|
|
|
* |
22
|
|
|
* TUrlMappingPattern represents a pattern used to parse and construct URLs. |
23
|
|
|
* If the currently requested URL matches the pattern, it will alter |
24
|
|
|
* the THttpRequest parameters. If a constructUrl() call matches the pattern |
25
|
|
|
* parameters, the pattern will generate a valid URL. In both case, only the PATH_INFO |
26
|
|
|
* part of a URL is parsed/constructed using the pattern. |
27
|
|
|
* |
28
|
|
|
* To specify the pattern, set the {@see setPattern Pattern} property. |
29
|
|
|
* {@see setPattern Pattern} takes a string expression with |
30
|
|
|
* parameter names enclosed between a left brace '{' and a right brace '}'. |
31
|
|
|
* The patterns for each parameter can be set using {@see getParameters Parameters} |
32
|
|
|
* attribute collection. For example |
33
|
|
|
* ```php |
34
|
|
|
* <url ... pattern="articles/{year}/{month}/{day}" |
35
|
|
|
* parameters.year="\d{4}" parameters.month="\d{2}" parameters.day="\d+" /> |
36
|
|
|
* ``` |
37
|
|
|
* |
38
|
|
|
* In the above example, the pattern contains 3 parameters named "year", |
39
|
|
|
* "month" and "day". The pattern for these parameters are, respectively, |
40
|
|
|
* "\d{4}" (4 digits), "\d{2}" (2 digits) and "\d+" (1 or more digits). |
41
|
|
|
* Essentially, the <tt>Parameters</tt> attribute name and values are used |
42
|
|
|
* as substrings in replacing the placeholders in the <tt>Pattern</tt> string |
43
|
|
|
* to form a complete regular expression string. |
44
|
|
|
* |
45
|
|
|
* For more complicated patterns, one may specify the pattern using a regular expression |
46
|
|
|
* by {@see setRegularExpression RegularExpression}. For example, the above pattern |
47
|
|
|
* is equivalent to the following regular expression-based pattern: |
48
|
|
|
* ``` |
49
|
|
|
* #^articles/(?P<year>\d{4})/(?P<month>\d{2})\/(?P<day>\d+)$#u |
50
|
|
|
* ``` |
51
|
|
|
* The above regular expression used the "named group" feature available in PHP. |
52
|
|
|
* If you intended to use the <tt>RegularExpression</tt> property or |
53
|
|
|
* regular expressions in CDATA sections, notice that you need to escape the slash, |
54
|
|
|
* if you are using the slash as regular expressions delimiter. |
55
|
|
|
* |
56
|
|
|
* Thus, only an url that matches the pattern will be valid. For example, |
57
|
|
|
* a URL <tt>http://example.com/index.php/articles/2006/07/21</tt> will match the above pattern, |
58
|
|
|
* while <tt>http://example.com/index.php/articles/2006/07/hello</tt> will not |
59
|
|
|
* since the "day" parameter pattern is not satisfied. |
60
|
|
|
* |
61
|
|
|
* The parameter values are available through the <tt>THttpRequest</tt> instance (e.g. |
62
|
|
|
* <tt>$this->Request['year']</tt>). |
63
|
|
|
* |
64
|
|
|
* The {@see setServiceParameter ServiceParameter} and {@see setServiceID ServiceID} |
65
|
|
|
* (the default ID is 'page') set the service parameter and service id respectively. |
66
|
|
|
* |
67
|
|
|
* Since 3.1.4 you can also use simplyfied wildcard patterns to match multiple |
68
|
|
|
* ServiceParameters with a single rule. The pattern must contain the placeholder |
69
|
|
|
* {*} for the ServiceParameter. For example |
70
|
|
|
* |
71
|
|
|
* <url ServiceParameter="adminpages.*" pattern="admin/{*}" /> |
72
|
|
|
* |
73
|
|
|
* This rule will match an URL like <tt>http://example.com/index.php/admin/edituser</tt> |
74
|
|
|
* and resolve it to the page Application.pages.admin.edituser. The wildcard matching |
75
|
|
|
* is non-recursive. That means you have to add a rule for every subdirectory you |
76
|
|
|
* want to access pages in: |
77
|
|
|
* |
78
|
|
|
* <url ServiceParameter="adminpages.users.*" pattern="useradmin/{*}" /> |
79
|
|
|
* |
80
|
|
|
* It is still possible to define an explicit rule for a page in the wildcard path. |
81
|
|
|
* This rule has to preceed the wildcard rule. |
82
|
|
|
* |
83
|
|
|
* You can also use parameters with wildcard patterns. The parameters are then |
84
|
|
|
* available with every matching page: |
85
|
|
|
* |
86
|
|
|
* <url ServiceParameter="adminpages.*" pattern="admin/{*}/{id}" parameters.id="\d+" /> |
87
|
|
|
* |
88
|
|
|
* To enable automatic parameter encoding in a path format from wildcard patterns you can set |
89
|
|
|
* {@setUrlFormat UrlFormat} to 'Path': |
90
|
|
|
* |
91
|
|
|
* <url ServiceParameter="adminpages.*" pattern="admin/{*}" UrlFormat="Path" /> |
92
|
|
|
* |
93
|
|
|
* This will create and parse URLs of the form |
94
|
|
|
* <tt>.../index.php/admin/listuser/param1/value1/param2/value2</tt>. |
95
|
|
|
* |
96
|
|
|
* Use {@setUrlParamSeparator} to define another separator character between parameter |
97
|
|
|
* name and value. Parameter/value pairs are always separated by a '/'. |
98
|
|
|
* |
99
|
|
|
* <url ServiceParameter="adminpages.*" pattern="admin/{*}" UrlFormat="Path" UrlParamSeparator="-" /> |
100
|
|
|
* |
101
|
|
|
* <tt>.../index.php/admin/listuser/param1-value1/param2-value2</tt>. |
102
|
|
|
* |
103
|
|
|
* Since 3.2.2 you can also add a list of "constants" parameters that can be used just |
104
|
|
|
* like the original "parameters" parameters, except that the supplied value will be treated |
105
|
|
|
* as a simple string constant instead of a regular expression. For example |
106
|
|
|
* |
107
|
|
|
* <url ServiceParameter="MyPage" pattern="/mypage/mypath/list/detail/{pageidx}" parameters.pageidx="\d+" constants.listtype="detailed"/> |
108
|
|
|
* <url ServiceParameter="MyPage" pattern="/mypage/mypath/list/summary/{pageidx}" parameters.pageidx="\d+" constants.listtype="summarized"/> |
109
|
|
|
* |
110
|
|
|
* These rules, when matched by the actual request, will make the application see a "lisstype" parameter present |
111
|
|
|
* (even through not supplied in the request) and equal to "detailed" or "summarized", depending on the friendly url matched. |
112
|
|
|
* The constants is practically a table-based validation and translation of specified, fixed-set parameter values. |
113
|
|
|
* |
114
|
|
|
* @author Wei Zhuo <weizhuo[at]gmail[dot]com> |
115
|
|
|
* @since 3.0.5 |
116
|
|
|
*/ |
117
|
|
|
class TUrlMappingPattern extends \Prado\TComponent |
118
|
|
|
{ |
119
|
|
|
/** |
120
|
|
|
* @var string service parameter such as Page class name. |
121
|
|
|
*/ |
122
|
|
|
private $_serviceParameter; |
123
|
|
|
/** |
124
|
|
|
* @var string service ID, default is 'page'. |
125
|
|
|
*/ |
126
|
|
|
private $_serviceID = 'page'; |
127
|
|
|
/** |
128
|
|
|
* @var string url pattern to match. |
129
|
|
|
*/ |
130
|
|
|
private $_pattern; |
131
|
|
|
/** |
132
|
|
|
* @var TAttributeCollection parameter regular expressions. |
133
|
|
|
*/ |
134
|
|
|
private $_parameters; |
135
|
|
|
/** |
136
|
|
|
* @var TAttributeCollection of constant parameters. |
137
|
|
|
*/ |
138
|
|
|
protected $_constants; |
139
|
|
|
/** |
140
|
|
|
* @var string regular expression pattern. |
141
|
|
|
*/ |
142
|
|
|
private $_regexp = ''; |
143
|
|
|
|
144
|
|
|
private $_customUrl = true; |
145
|
|
|
|
146
|
|
|
private $_manager; |
147
|
|
|
|
148
|
|
|
private $_caseSensitive = true; |
149
|
|
|
|
150
|
|
|
private $_isWildCardPattern = false; |
151
|
|
|
|
152
|
|
|
private $_urlFormat = THttpRequestUrlFormat::Get; |
153
|
|
|
|
154
|
|
|
private $_separator = '/'; |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* @var TUrlMappingPatternSecureConnection |
158
|
|
|
* @since 3.2 |
159
|
|
|
*/ |
160
|
|
|
private $_secureConnection = TUrlMappingPatternSecureConnection::Automatic; |
161
|
|
|
|
162
|
|
|
/** |
163
|
|
|
* Constructor. |
164
|
|
|
* @param TUrlManager $manager the URL manager instance |
165
|
|
|
*/ |
166
|
|
|
public function __construct(TUrlManager $manager) |
167
|
1 |
|
{ |
168
|
|
|
$this->_manager = $manager; |
169
|
1 |
|
parent::__construct(); |
170
|
1 |
|
} |
171
|
|
|
|
172
|
|
|
/** |
173
|
|
|
* @return TUrlManager the URL manager instance |
174
|
|
|
*/ |
175
|
|
|
public function getManager() |
176
|
|
|
{ |
177
|
|
|
return $this->_manager; |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
/** |
181
|
|
|
* Initializes the pattern. |
182
|
|
|
* @param \Prado\Xml\TXmlElement $config configuration for this module. |
183
|
|
|
* @throws TConfigurationException if service parameter is not specified |
184
|
|
|
*/ |
185
|
1 |
|
public function init($config) |
|
|
|
|
186
|
|
|
{ |
187
|
1 |
|
if ($this->_serviceParameter === null) { |
188
|
|
|
throw new TConfigurationException('urlmappingpattern_serviceparameter_required', $this->getPattern()); |
189
|
|
|
} |
190
|
1 |
|
if (strpos($this->_serviceParameter, '*') !== false) { |
191
|
|
|
$this->_isWildCardPattern = true; |
192
|
|
|
} |
193
|
1 |
|
} |
194
|
|
|
|
195
|
|
|
/** |
196
|
|
|
* Substitute the parameter key value pairs as named groupings |
197
|
|
|
* in the regular expression matching pattern. |
198
|
|
|
* @return string regular expression pattern with parameter subsitution |
199
|
|
|
*/ |
200
|
1 |
|
protected function getParameterizedPattern() |
201
|
|
|
{ |
202
|
1 |
|
$params = []; |
203
|
1 |
|
$values = []; |
204
|
1 |
|
if ($this->_parameters) { |
205
|
1 |
|
foreach ($this->_parameters as $key => $value) { |
206
|
1 |
|
$params[] = '{' . $key . '}'; |
207
|
1 |
|
$values[] = '(?P<' . $key . '>' . $value . ')'; |
208
|
|
|
} |
209
|
|
|
} |
210
|
1 |
|
if ($this->getIsWildCardPattern()) { |
211
|
|
|
$params[] = '{*}'; |
212
|
|
|
// service parameter must not contain '=' and '/' |
213
|
|
|
$values[] = '(?P<' . $this->getServiceID() . '>[^=/]+)'; |
214
|
|
|
} |
215
|
1 |
|
$params[] = '/'; |
216
|
1 |
|
$values[] = '\\/'; |
217
|
1 |
|
$regexp = str_replace($params, $values, trim($this->getPattern(), '/') . '/'); |
218
|
1 |
|
if ($this->_urlFormat === THttpRequestUrlFormat::Get) { |
219
|
1 |
|
$regexp = '/^' . $regexp . '$/u'; |
220
|
|
|
} else { |
221
|
|
|
$regexp = '/^' . $regexp . '(?P<urlparams>.*)$/u'; |
222
|
|
|
} |
223
|
|
|
|
224
|
1 |
|
if (!$this->getCaseSensitive()) { |
225
|
|
|
$regexp .= 'i'; |
226
|
|
|
} |
227
|
1 |
|
return $regexp; |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
/** |
231
|
|
|
* @return string full regular expression mapping pattern |
232
|
|
|
*/ |
233
|
1 |
|
public function getRegularExpression() |
234
|
|
|
{ |
235
|
1 |
|
return $this->_regexp; |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
/** |
239
|
|
|
* @param string $value full regular expression mapping pattern. |
240
|
|
|
*/ |
241
|
|
|
public function setRegularExpression($value) |
242
|
|
|
{ |
243
|
|
|
$this->_regexp = $value; |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
/** |
247
|
|
|
* @return bool whether the {@see getPattern Pattern} should be treated as case sensititve. Defaults to true. |
248
|
|
|
*/ |
249
|
1 |
|
public function getCaseSensitive() |
250
|
|
|
{ |
251
|
1 |
|
return $this->_caseSensitive; |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
/** |
255
|
|
|
* @param bool $value whether the {@see getPattern Pattern} should be treated as case sensititve. |
256
|
|
|
*/ |
257
|
|
|
public function setCaseSensitive($value) |
258
|
|
|
{ |
259
|
|
|
$this->_caseSensitive = TPropertyValue::ensureBoolean($value); |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
/** |
263
|
|
|
* @param string $value service parameter, such as page class name. |
264
|
|
|
*/ |
265
|
1 |
|
public function setServiceParameter($value) |
266
|
|
|
{ |
267
|
1 |
|
$this->_serviceParameter = $value; |
268
|
1 |
|
} |
269
|
|
|
|
270
|
|
|
/** |
271
|
|
|
* @return string service parameter, such as page class name. |
272
|
|
|
*/ |
273
|
1 |
|
public function getServiceParameter() |
274
|
|
|
{ |
275
|
1 |
|
return $this->_serviceParameter; |
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
/** |
279
|
|
|
* @param string $value service id to handle. |
280
|
|
|
*/ |
281
|
1 |
|
public function setServiceID($value) |
282
|
|
|
{ |
283
|
1 |
|
$this->_serviceID = $value; |
284
|
1 |
|
} |
285
|
|
|
|
286
|
|
|
/** |
287
|
|
|
* @return string service id. |
288
|
|
|
*/ |
289
|
1 |
|
public function getServiceID() |
290
|
|
|
{ |
291
|
1 |
|
return $this->_serviceID; |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
/** |
295
|
|
|
* @return string url pattern to match. Defaults to ''. |
296
|
|
|
*/ |
297
|
1 |
|
public function getPattern() |
298
|
|
|
{ |
299
|
1 |
|
return $this->_pattern; |
300
|
|
|
} |
301
|
|
|
|
302
|
|
|
/** |
303
|
|
|
* @param string $value url pattern to match. |
304
|
|
|
*/ |
305
|
1 |
|
public function setPattern($value) |
306
|
|
|
{ |
307
|
1 |
|
$this->_pattern = $value; |
308
|
1 |
|
} |
309
|
|
|
|
310
|
|
|
/** |
311
|
|
|
* @return TAttributeCollection parameter key value pairs. |
312
|
|
|
*/ |
313
|
1 |
|
public function getParameters() |
314
|
|
|
{ |
315
|
1 |
|
if (!$this->_parameters) { |
316
|
1 |
|
$this->_parameters = new TAttributeCollection(); |
317
|
1 |
|
$this->_parameters->setCaseSensitive(true); |
318
|
|
|
} |
319
|
1 |
|
return $this->_parameters; |
320
|
|
|
} |
321
|
|
|
|
322
|
|
|
/** |
323
|
|
|
* @param TAttributeCollection $value new parameter key value pairs. |
324
|
|
|
*/ |
325
|
|
|
public function setParameters($value) |
326
|
|
|
{ |
327
|
|
|
$this->_parameters = $value; |
328
|
|
|
} |
329
|
|
|
|
330
|
|
|
/** |
331
|
|
|
* @return TAttributeCollection constanst parameter key value pairs. |
332
|
|
|
* @since 3.2.2 |
333
|
|
|
*/ |
334
|
|
|
public function getConstants() |
335
|
|
|
{ |
336
|
|
|
if (!$this->_constants) { |
337
|
|
|
$this->_constants = new TAttributeCollection(); |
338
|
|
|
$this->_constants->setCaseSensitive(true); |
339
|
|
|
} |
340
|
|
|
return $this->_constants; |
341
|
|
|
} |
342
|
|
|
|
343
|
|
|
/** |
344
|
|
|
* Uses URL pattern (or full regular expression if available) to |
345
|
|
|
* match the given url path. |
346
|
|
|
* @param THttpRequest $request the request module |
347
|
|
|
* @return array matched parameters, empty if no matches. |
348
|
|
|
*/ |
349
|
1 |
|
public function getPatternMatches($request) |
350
|
|
|
{ |
351
|
1 |
|
$matches = []; |
352
|
1 |
|
if (($pattern = $this->getRegularExpression()) !== '') { |
353
|
|
|
preg_match($pattern, $request->getPathInfo(), $matches); |
354
|
|
|
} else { |
355
|
1 |
|
preg_match($this->getParameterizedPattern(), trim($request->getPathInfo(), '/') . '/', $matches); |
356
|
|
|
} |
357
|
|
|
|
358
|
1 |
|
if ($this->getIsWildCardPattern() && isset($matches[$this->_serviceID])) { |
359
|
|
|
$matches[$this->_serviceID] = str_replace('*', $matches[$this->_serviceID], $this->_serviceParameter); |
360
|
|
|
} |
361
|
|
|
|
362
|
1 |
|
if (isset($matches['urlparams'])) { |
363
|
|
|
$params = explode('/', $matches['urlparams']); |
364
|
|
|
if ($this->_separator === '/') { |
365
|
|
|
while ($key = array_shift($params)) { |
366
|
|
|
$matches[$key] = ($value = array_shift($params)) ? $value : ''; |
367
|
|
|
} |
368
|
|
|
} else { |
369
|
|
|
array_pop($params); |
370
|
|
|
foreach ($params as $param) { |
371
|
|
|
[$key, $value] = explode($this->_separator, $param, 2); |
372
|
|
|
$matches[$key] = $value; |
373
|
|
|
} |
374
|
|
|
} |
375
|
|
|
unset($matches['urlparams']); |
376
|
|
|
} |
377
|
|
|
|
378
|
1 |
|
if (count($matches) > 0 && $this->_constants) { |
379
|
|
|
foreach ($this->_constants->toArray() as $key => $value) { |
380
|
|
|
$matches[$key] = $value; |
381
|
|
|
} |
382
|
|
|
} |
383
|
|
|
|
384
|
1 |
|
return $matches; |
385
|
|
|
} |
386
|
|
|
|
387
|
|
|
/** |
388
|
|
|
* Returns a value indicating whether to use this pattern to construct URL. |
389
|
|
|
* @return bool whether to enable custom constructUrl. Defaults to true. |
390
|
|
|
* @since 3.1.1 |
391
|
|
|
*/ |
392
|
|
|
public function getEnableCustomUrl() |
393
|
|
|
{ |
394
|
|
|
return $this->_customUrl; |
395
|
|
|
} |
396
|
|
|
|
397
|
|
|
/** |
398
|
|
|
* Sets a value indicating whether to enable custom constructUrl using this pattern |
399
|
|
|
* @param bool $value whether to enable custom constructUrl. |
400
|
|
|
*/ |
401
|
|
|
public function setEnableCustomUrl($value) |
402
|
|
|
{ |
403
|
|
|
$this->_customUrl = TPropertyValue::ensureBoolean($value); |
404
|
|
|
} |
405
|
|
|
|
406
|
|
|
/** |
407
|
|
|
* @return bool whether this pattern is a wildcard pattern |
408
|
|
|
* @since 3.1.4 |
409
|
|
|
*/ |
410
|
1 |
|
public function getIsWildCardPattern() |
411
|
|
|
{ |
412
|
1 |
|
return $this->_isWildCardPattern; |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
/** |
416
|
|
|
* @return THttpRequestUrlFormat the format of URLs. Defaults to THttpRequestUrlFormat::Get. |
417
|
|
|
*/ |
418
|
|
|
public function getUrlFormat() |
419
|
|
|
{ |
420
|
|
|
return $this->_urlFormat; |
|
|
|
|
421
|
|
|
} |
422
|
|
|
|
423
|
|
|
/** |
424
|
|
|
* Sets the format of URLs constructed and interpreted by this pattern. |
425
|
|
|
* A Get URL format is like index.php?name1=value1&name2=value2 |
426
|
|
|
* while a Path URL format is like index.php/name1/value1/name2/value. |
427
|
|
|
* The separating character between name and value can be configured with |
428
|
|
|
* {@see setUrlParamSeparator} and defaults to '/'. |
429
|
|
|
* Changing the UrlFormat will affect {@see constructUrl} and how GET variables |
430
|
|
|
* are parsed. |
431
|
|
|
* @param THttpRequestUrlFormat $value the format of URLs. |
432
|
|
|
* @since 3.1.4 |
433
|
|
|
*/ |
434
|
|
|
public function setUrlFormat($value) |
435
|
|
|
{ |
436
|
|
|
$this->_urlFormat = TPropertyValue::ensureEnum($value, THttpRequestUrlFormat::class); |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
/** |
440
|
|
|
* @return string separator used to separate GET variable name and value when URL format is Path. Defaults to slash '/'. |
441
|
|
|
*/ |
442
|
|
|
public function getUrlParamSeparator() |
443
|
|
|
{ |
444
|
|
|
return $this->_separator; |
445
|
|
|
} |
446
|
|
|
|
447
|
|
|
/** |
448
|
|
|
* @param string $value separator used to separate GET variable name and value when URL format is Path. |
449
|
|
|
* @throws TInvalidDataValueException if the separator is not a single character |
450
|
|
|
*/ |
451
|
|
|
public function setUrlParamSeparator($value) |
452
|
|
|
{ |
453
|
|
|
if (strlen($value) === 1) { |
454
|
|
|
$this->_separator = $value; |
455
|
|
|
} else { |
456
|
|
|
throw new TInvalidDataValueException('httprequest_separator_invalid'); |
457
|
|
|
} |
458
|
|
|
} |
459
|
|
|
|
460
|
|
|
/** |
461
|
|
|
* @return TUrlMappingPatternSecureConnection the SecureConnection behavior. Defaults to {@see \Prado\Web\TUrlMappingPatternSecureConnection::Automatic Automatic} |
462
|
|
|
* @since 3.2 |
463
|
|
|
*/ |
464
|
|
|
public function getSecureConnection() |
465
|
|
|
{ |
466
|
|
|
return $this->_secureConnection; |
467
|
|
|
} |
468
|
|
|
|
469
|
|
|
/** |
470
|
|
|
* @param TUrlMappingPatternSecureConnection $value the SecureConnection behavior. |
471
|
|
|
* @since 3.2 |
472
|
|
|
*/ |
473
|
|
|
public function setSecureConnection($value) |
474
|
|
|
{ |
475
|
|
|
$this->_secureConnection = TPropertyValue::ensureEnum($value, TUrlMappingPatternSecureConnection::class); |
|
|
|
|
476
|
|
|
} |
477
|
|
|
|
478
|
|
|
/** |
479
|
|
|
* @param array $getItems list of GET items to be put in the constructed URL |
480
|
|
|
* @return bool whether this pattern IS the one for constructing the URL with the specified GET items. |
481
|
|
|
* @since 3.1.1 |
482
|
|
|
*/ |
483
|
|
|
public function supportCustomUrl($getItems) |
484
|
|
|
{ |
485
|
|
|
if (!$this->_customUrl || $this->getPattern() === null) { |
486
|
|
|
return false; |
487
|
|
|
} |
488
|
|
|
if ($this->_parameters) { |
489
|
|
|
foreach ($this->_parameters as $key => $value) { |
490
|
|
|
if (!isset($getItems[$key])) { |
491
|
|
|
return false; |
492
|
|
|
} |
493
|
|
|
} |
494
|
|
|
} |
495
|
|
|
|
496
|
|
|
if ($this->_constants) { |
497
|
|
|
foreach ($this->_constants->toArray() as $key => $value) { |
498
|
|
|
if (!isset($getItems[$key])) { |
499
|
|
|
return false; |
500
|
|
|
} |
501
|
|
|
if ($getItems[$key] != $value) { |
502
|
|
|
return false; |
503
|
|
|
} |
504
|
|
|
} |
505
|
|
|
} |
506
|
|
|
return true; |
507
|
|
|
} |
508
|
|
|
|
509
|
|
|
/** |
510
|
|
|
* Constructs a URL using this pattern. |
511
|
|
|
* @param array $getItems list of GET variables |
512
|
|
|
* @param bool $encodeAmpersand whether the ampersand should be encoded in the constructed URL |
513
|
|
|
* @param bool $encodeGetItems whether the GET variables should be encoded in the constructed URL |
514
|
|
|
* @return string the constructed URL |
515
|
|
|
* @since 3.1.1 |
516
|
|
|
*/ |
517
|
|
|
public function constructUrl($getItems, $encodeAmpersand, $encodeGetItems) |
518
|
|
|
{ |
519
|
|
|
if ($this->_constants) { |
520
|
|
|
foreach ($this->_constants->toArray() as $key => $value) { |
521
|
|
|
unset($getItems[$key]); |
522
|
|
|
} |
523
|
|
|
} |
524
|
|
|
|
525
|
|
|
$extra = []; |
526
|
|
|
$replace = []; |
527
|
|
|
// for the GET variables matching the pattern, put them in the URL path |
528
|
|
|
foreach ($getItems as $key => $value) { |
529
|
|
|
if (($this->_parameters && $this->_parameters->contains($key)) || ($key === '*' && $this->getIsWildCardPattern())) { |
530
|
|
|
$replace['{' . $key . '}'] = $encodeGetItems ? rawurlencode($value) : $value; |
531
|
|
|
} else { |
532
|
|
|
$extra[$key] = $value; |
533
|
|
|
} |
534
|
|
|
} |
535
|
|
|
|
536
|
|
|
$url = $this->_manager->getUrlPrefix() . '/' . ltrim(strtr($this->getPattern(), $replace), '/'); |
|
|
|
|
537
|
|
|
|
538
|
|
|
// for the rest of the GET variables, put them in the query string |
539
|
|
|
if (count($extra) > 0) { |
540
|
|
|
if ($this->_urlFormat === THttpRequestUrlFormat::Path && $this->getIsWildCardPattern()) { |
541
|
|
|
foreach ($extra as $name => $value) { |
542
|
|
|
$url .= '/' . $name . $this->_separator . ($encodeGetItems ? rawurlencode($value) : $value); |
543
|
|
|
} |
544
|
|
|
return $url; |
545
|
|
|
} |
546
|
|
|
|
547
|
|
|
$url2 = ''; |
548
|
|
|
$amp = $encodeAmpersand ? '&' : '&'; |
549
|
|
|
if ($encodeGetItems) { |
550
|
|
|
foreach ($extra as $name => $value) { |
551
|
|
|
if (is_array($value)) { |
552
|
|
|
$name = rawurlencode($name . '[]'); |
553
|
|
|
foreach ($value as $v) { |
554
|
|
|
$url2 .= $amp . $name . '=' . rawurlencode($v); |
555
|
|
|
} |
556
|
|
|
} else { |
557
|
|
|
$url2 .= $amp . rawurlencode($name) . '=' . rawurlencode($value); |
558
|
|
|
} |
559
|
|
|
} |
560
|
|
|
} else { |
561
|
|
|
foreach ($extra as $name => $value) { |
562
|
|
|
if (is_array($value)) { |
563
|
|
|
foreach ($value as $v) { |
564
|
|
|
$url2 .= $amp . $name . '[]=' . $v; |
565
|
|
|
} |
566
|
|
|
} else { |
567
|
|
|
$url2 .= $amp . $name . '=' . $value; |
568
|
|
|
} |
569
|
|
|
} |
570
|
|
|
} |
571
|
|
|
$url = $url . '?' . substr($url2, strlen($amp)); |
572
|
|
|
} |
573
|
|
|
return $this -> applySecureConnectionPrefix($url); |
574
|
|
|
} |
575
|
|
|
|
576
|
|
|
/** |
577
|
|
|
* Apply behavior of {@see SecureConnection} property by conditionaly prefixing |
578
|
|
|
* URL with {@see \Prado\Web\THttpRequest::getBaseUrl()} |
579
|
|
|
* |
580
|
|
|
* @param string $url |
581
|
|
|
* @return string |
582
|
|
|
* @since 3.2 |
583
|
|
|
*/ |
584
|
|
|
protected function applySecureConnectionPrefix($url) |
585
|
|
|
{ |
586
|
|
|
static $request; |
587
|
|
|
if ($request === null) { |
588
|
|
|
$request = Prado::getApplication() -> getRequest(); |
589
|
|
|
} |
590
|
|
|
|
591
|
|
|
static $isSecureConnection; |
592
|
|
|
if ($isSecureConnection === null) { |
593
|
|
|
$isSecureConnection = $request -> getIsSecureConnection(); |
594
|
|
|
} |
595
|
|
|
|
596
|
|
|
switch ($this -> getSecureConnection()) { |
597
|
|
|
case TUrlMappingPatternSecureConnection::EnableIfNotSecure: |
598
|
|
|
if ($isSecureConnection) { |
599
|
|
|
return $url; |
600
|
|
|
} |
601
|
|
|
return $request -> getBaseUrl(true) . $url; |
602
|
|
|
break; |
|
|
|
|
603
|
|
|
case TUrlMappingPatternSecureConnection::DisableIfSecure: |
604
|
|
|
if (!$isSecureConnection) { |
605
|
|
|
return $url; |
606
|
|
|
} |
607
|
|
|
return $request -> getBaseUrl(false) . $url; |
608
|
|
|
break; |
609
|
|
|
case TUrlMappingPatternSecureConnection::Enable: |
610
|
|
|
return $request -> getBaseUrl(true) . $url; |
611
|
|
|
break; |
612
|
|
|
case TUrlMappingPatternSecureConnection::Disable: |
613
|
|
|
return $request -> getBaseUrl(false) . $url; |
614
|
|
|
break; |
615
|
|
|
case TUrlMappingPatternSecureConnection::Automatic: |
616
|
|
|
default: |
617
|
|
|
return $url; |
618
|
|
|
break; |
619
|
|
|
} |
620
|
|
|
} |
621
|
|
|
} |
622
|
|
|
|
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.