|
1 <?php |
|
2 /** |
|
3 * Zend Framework |
|
4 * |
|
5 * LICENSE |
|
6 * |
|
7 * This source file is subject to the new BSD license that is bundled |
|
8 * with this package in the file LICENSE.txt. |
|
9 * It is also available through the world-wide-web at this URL: |
|
10 * http://framework.zend.com/license/new-bsd |
|
11 * If you did not receive a copy of the license and are unable to |
|
12 * obtain it through the world-wide-web, please send an email |
|
13 * to license@zend.com so we can send you a copy immediately. |
|
14 * |
|
15 * @category Zend |
|
16 * @package Zend_Uri |
|
17 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
18 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
19 * @version $Id: Http.php 23409 2010-11-19 19:55:25Z bittarman $ |
|
20 */ |
|
21 |
|
22 /** |
|
23 * @see Zend_Uri |
|
24 */ |
|
25 require_once 'Zend/Uri.php'; |
|
26 |
|
27 /** |
|
28 * @see Zend_Validate_Hostname |
|
29 */ |
|
30 require_once 'Zend/Validate/Hostname.php'; |
|
31 |
|
32 /** |
|
33 * HTTP(S) URI handler |
|
34 * |
|
35 * @category Zend |
|
36 * @package Zend_Uri |
|
37 * @uses Zend_Uri |
|
38 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
39 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
40 */ |
|
41 class Zend_Uri_Http extends Zend_Uri |
|
42 { |
|
43 /** |
|
44 * Character classes for validation regular expressions |
|
45 */ |
|
46 const CHAR_ALNUM = 'A-Za-z0-9'; |
|
47 const CHAR_MARK = '-_.!~*\'()\[\]'; |
|
48 const CHAR_RESERVED = ';\/?:@&=+$,'; |
|
49 const CHAR_SEGMENT = ':@&=+$,;'; |
|
50 const CHAR_UNWISE = '{}|\\\\^`'; |
|
51 |
|
52 /** |
|
53 * HTTP username |
|
54 * |
|
55 * @var string |
|
56 */ |
|
57 protected $_username = ''; |
|
58 |
|
59 /** |
|
60 * HTTP password |
|
61 * |
|
62 * @var string |
|
63 */ |
|
64 protected $_password = ''; |
|
65 |
|
66 /** |
|
67 * HTTP host |
|
68 * |
|
69 * @var string |
|
70 */ |
|
71 protected $_host = ''; |
|
72 |
|
73 /** |
|
74 * HTTP post |
|
75 * |
|
76 * @var string |
|
77 */ |
|
78 protected $_port = ''; |
|
79 |
|
80 /** |
|
81 * HTTP part |
|
82 * |
|
83 * @var string |
|
84 */ |
|
85 protected $_path = ''; |
|
86 |
|
87 /** |
|
88 * HTTP query |
|
89 * |
|
90 * @var string |
|
91 */ |
|
92 protected $_query = ''; |
|
93 |
|
94 /** |
|
95 * HTTP fragment |
|
96 * |
|
97 * @var string |
|
98 */ |
|
99 protected $_fragment = ''; |
|
100 |
|
101 /** |
|
102 * Regular expression grammar rules for validation; values added by constructor |
|
103 * |
|
104 * @var array |
|
105 */ |
|
106 protected $_regex = array(); |
|
107 |
|
108 /** |
|
109 * Constructor accepts a string $scheme (e.g., http, https) and a scheme-specific part of the URI |
|
110 * (e.g., example.com/path/to/resource?query=param#fragment) |
|
111 * |
|
112 * @param string $scheme The scheme of the URI |
|
113 * @param string $schemeSpecific The scheme-specific part of the URI |
|
114 * @throws Zend_Uri_Exception When the URI is not valid |
|
115 */ |
|
116 protected function __construct($scheme, $schemeSpecific = '') |
|
117 { |
|
118 // Set the scheme |
|
119 $this->_scheme = $scheme; |
|
120 |
|
121 // Set up grammar rules for validation via regular expressions. These |
|
122 // are to be used with slash-delimited regular expression strings. |
|
123 |
|
124 // Escaped special characters (eg. '%25' for '%') |
|
125 $this->_regex['escaped'] = '%[[:xdigit:]]{2}'; |
|
126 |
|
127 // Unreserved characters |
|
128 $this->_regex['unreserved'] = '[' . self::CHAR_ALNUM . self::CHAR_MARK . ']'; |
|
129 |
|
130 // Segment can use escaped, unreserved or a set of additional chars |
|
131 $this->_regex['segment'] = '(?:' . $this->_regex['escaped'] . '|[' . |
|
132 self::CHAR_ALNUM . self::CHAR_MARK . self::CHAR_SEGMENT . '])*'; |
|
133 |
|
134 // Path can be a series of segmets char strings seperated by '/' |
|
135 $this->_regex['path'] = '(?:\/(?:' . $this->_regex['segment'] . ')?)+'; |
|
136 |
|
137 // URI characters can be escaped, alphanumeric, mark or reserved chars |
|
138 $this->_regex['uric'] = '(?:' . $this->_regex['escaped'] . '|[' . |
|
139 self::CHAR_ALNUM . self::CHAR_MARK . self::CHAR_RESERVED . |
|
140 |
|
141 // If unwise chars are allowed, add them to the URI chars class |
|
142 (self::$_config['allow_unwise'] ? self::CHAR_UNWISE : '') . '])'; |
|
143 |
|
144 // If no scheme-specific part was supplied, the user intends to create |
|
145 // a new URI with this object. No further parsing is required. |
|
146 if (strlen($schemeSpecific) === 0) { |
|
147 return; |
|
148 } |
|
149 |
|
150 // Parse the scheme-specific URI parts into the instance variables. |
|
151 $this->_parseUri($schemeSpecific); |
|
152 |
|
153 // Validate the URI |
|
154 if ($this->valid() === false) { |
|
155 require_once 'Zend/Uri/Exception.php'; |
|
156 throw new Zend_Uri_Exception('Invalid URI supplied'); |
|
157 } |
|
158 } |
|
159 |
|
160 /** |
|
161 * Creates a Zend_Uri_Http from the given string |
|
162 * |
|
163 * @param string $uri String to create URI from, must start with |
|
164 * 'http://' or 'https://' |
|
165 * @throws InvalidArgumentException When the given $uri is not a string or |
|
166 * does not start with http:// or https:// |
|
167 * @throws Zend_Uri_Exception When the given $uri is invalid |
|
168 * @return Zend_Uri_Http |
|
169 */ |
|
170 public static function fromString($uri) |
|
171 { |
|
172 if (is_string($uri) === false) { |
|
173 require_once 'Zend/Uri/Exception.php'; |
|
174 throw new Zend_Uri_Exception('$uri is not a string'); |
|
175 } |
|
176 |
|
177 $uri = explode(':', $uri, 2); |
|
178 $scheme = strtolower($uri[0]); |
|
179 $schemeSpecific = isset($uri[1]) === true ? $uri[1] : ''; |
|
180 |
|
181 if (in_array($scheme, array('http', 'https')) === false) { |
|
182 require_once 'Zend/Uri/Exception.php'; |
|
183 throw new Zend_Uri_Exception("Invalid scheme: '$scheme'"); |
|
184 } |
|
185 |
|
186 $schemeHandler = new Zend_Uri_Http($scheme, $schemeSpecific); |
|
187 return $schemeHandler; |
|
188 } |
|
189 |
|
190 /** |
|
191 * Parse the scheme-specific portion of the URI and place its parts into instance variables. |
|
192 * |
|
193 * @param string $schemeSpecific The scheme-specific portion to parse |
|
194 * @throws Zend_Uri_Exception When scheme-specific decoposition fails |
|
195 * @throws Zend_Uri_Exception When authority decomposition fails |
|
196 * @return void |
|
197 */ |
|
198 protected function _parseUri($schemeSpecific) |
|
199 { |
|
200 // High-level decomposition parser |
|
201 $pattern = '~^((//)([^/?#]*))([^?#]*)(\?([^#]*))?(#(.*))?$~'; |
|
202 $status = @preg_match($pattern, $schemeSpecific, $matches); |
|
203 if ($status === false) { |
|
204 require_once 'Zend/Uri/Exception.php'; |
|
205 throw new Zend_Uri_Exception('Internal error: scheme-specific decomposition failed'); |
|
206 } |
|
207 |
|
208 // Failed decomposition; no further processing needed |
|
209 if ($status === false) { |
|
210 return; |
|
211 } |
|
212 |
|
213 // Save URI components that need no further decomposition |
|
214 $this->_path = isset($matches[4]) === true ? $matches[4] : ''; |
|
215 $this->_query = isset($matches[6]) === true ? $matches[6] : ''; |
|
216 $this->_fragment = isset($matches[8]) === true ? $matches[8] : ''; |
|
217 |
|
218 // Additional decomposition to get username, password, host, and port |
|
219 $combo = isset($matches[3]) === true ? $matches[3] : ''; |
|
220 $pattern = '~^(([^:@]*)(:([^@]*))?@)?([^:]+)(:(.*))?$~'; |
|
221 $status = @preg_match($pattern, $combo, $matches); |
|
222 if ($status === false) { |
|
223 require_once 'Zend/Uri/Exception.php'; |
|
224 throw new Zend_Uri_Exception('Internal error: authority decomposition failed'); |
|
225 } |
|
226 |
|
227 // Failed decomposition; no further processing needed |
|
228 if ($status === false) { |
|
229 return; |
|
230 } |
|
231 |
|
232 // Save remaining URI components |
|
233 $this->_username = isset($matches[2]) === true ? $matches[2] : ''; |
|
234 $this->_password = isset($matches[4]) === true ? $matches[4] : ''; |
|
235 $this->_host = isset($matches[5]) === true ? $matches[5] : ''; |
|
236 $this->_port = isset($matches[7]) === true ? $matches[7] : ''; |
|
237 |
|
238 } |
|
239 |
|
240 /** |
|
241 * Returns a URI based on current values of the instance variables. If any |
|
242 * part of the URI does not pass validation, then an exception is thrown. |
|
243 * |
|
244 * @throws Zend_Uri_Exception When one or more parts of the URI are invalid |
|
245 * @return string |
|
246 */ |
|
247 public function getUri() |
|
248 { |
|
249 if ($this->valid() === false) { |
|
250 require_once 'Zend/Uri/Exception.php'; |
|
251 throw new Zend_Uri_Exception('One or more parts of the URI are invalid'); |
|
252 } |
|
253 |
|
254 $password = strlen($this->_password) > 0 ? ":$this->_password" : ''; |
|
255 $auth = strlen($this->_username) > 0 ? "$this->_username$password@" : ''; |
|
256 $port = strlen($this->_port) > 0 ? ":$this->_port" : ''; |
|
257 $query = strlen($this->_query) > 0 ? "?$this->_query" : ''; |
|
258 $fragment = strlen($this->_fragment) > 0 ? "#$this->_fragment" : ''; |
|
259 |
|
260 return $this->_scheme |
|
261 . '://' |
|
262 . $auth |
|
263 . $this->_host |
|
264 . $port |
|
265 . $this->_path |
|
266 . $query |
|
267 . $fragment; |
|
268 } |
|
269 |
|
270 /** |
|
271 * Validate the current URI from the instance variables. Returns true if and only if all |
|
272 * parts pass validation. |
|
273 * |
|
274 * @return boolean |
|
275 */ |
|
276 public function valid() |
|
277 { |
|
278 // Return true if and only if all parts of the URI have passed validation |
|
279 return $this->validateUsername() |
|
280 and $this->validatePassword() |
|
281 and $this->validateHost() |
|
282 and $this->validatePort() |
|
283 and $this->validatePath() |
|
284 and $this->validateQuery() |
|
285 and $this->validateFragment(); |
|
286 } |
|
287 |
|
288 /** |
|
289 * Returns the username portion of the URL, or FALSE if none. |
|
290 * |
|
291 * @return string |
|
292 */ |
|
293 public function getUsername() |
|
294 { |
|
295 return strlen($this->_username) > 0 ? $this->_username : false; |
|
296 } |
|
297 |
|
298 /** |
|
299 * Returns true if and only if the username passes validation. If no username is passed, |
|
300 * then the username contained in the instance variable is used. |
|
301 * |
|
302 * @param string $username The HTTP username |
|
303 * @throws Zend_Uri_Exception When username validation fails |
|
304 * @return boolean |
|
305 * @link http://www.faqs.org/rfcs/rfc2396.html |
|
306 */ |
|
307 public function validateUsername($username = null) |
|
308 { |
|
309 if ($username === null) { |
|
310 $username = $this->_username; |
|
311 } |
|
312 |
|
313 // If the username is empty, then it is considered valid |
|
314 if (strlen($username) === 0) { |
|
315 return true; |
|
316 } |
|
317 |
|
318 // Check the username against the allowed values |
|
319 $status = @preg_match('/^(?:' . $this->_regex['escaped'] . '|[' . |
|
320 self::CHAR_ALNUM . self::CHAR_MARK . ';:&=+$,' . '])+$/', $username); |
|
321 |
|
322 if ($status === false) { |
|
323 require_once 'Zend/Uri/Exception.php'; |
|
324 throw new Zend_Uri_Exception('Internal error: username validation failed'); |
|
325 } |
|
326 |
|
327 return $status === 1; |
|
328 } |
|
329 |
|
330 /** |
|
331 * Sets the username for the current URI, and returns the old username |
|
332 * |
|
333 * @param string $username The HTTP username |
|
334 * @throws Zend_Uri_Exception When $username is not a valid HTTP username |
|
335 * @return string |
|
336 */ |
|
337 public function setUsername($username) |
|
338 { |
|
339 if ($this->validateUsername($username) === false) { |
|
340 require_once 'Zend/Uri/Exception.php'; |
|
341 throw new Zend_Uri_Exception("Username \"$username\" is not a valid HTTP username"); |
|
342 } |
|
343 |
|
344 $oldUsername = $this->_username; |
|
345 $this->_username = $username; |
|
346 |
|
347 return $oldUsername; |
|
348 } |
|
349 |
|
350 /** |
|
351 * Returns the password portion of the URL, or FALSE if none. |
|
352 * |
|
353 * @return string |
|
354 */ |
|
355 public function getPassword() |
|
356 { |
|
357 return strlen($this->_password) > 0 ? $this->_password : false; |
|
358 } |
|
359 |
|
360 /** |
|
361 * Returns true if and only if the password passes validation. If no password is passed, |
|
362 * then the password contained in the instance variable is used. |
|
363 * |
|
364 * @param string $password The HTTP password |
|
365 * @throws Zend_Uri_Exception When password validation fails |
|
366 * @return boolean |
|
367 * @link http://www.faqs.org/rfcs/rfc2396.html |
|
368 */ |
|
369 public function validatePassword($password = null) |
|
370 { |
|
371 if ($password === null) { |
|
372 $password = $this->_password; |
|
373 } |
|
374 |
|
375 // If the password is empty, then it is considered valid |
|
376 if (strlen($password) === 0) { |
|
377 return true; |
|
378 } |
|
379 |
|
380 // If the password is nonempty, but there is no username, then it is considered invalid |
|
381 if (strlen($password) > 0 and strlen($this->_username) === 0) { |
|
382 return false; |
|
383 } |
|
384 |
|
385 // Check the password against the allowed values |
|
386 $status = @preg_match('/^(?:' . $this->_regex['escaped'] . '|[' . |
|
387 self::CHAR_ALNUM . self::CHAR_MARK . ';:&=+$,' . '])+$/', $password); |
|
388 |
|
389 if ($status === false) { |
|
390 require_once 'Zend/Uri/Exception.php'; |
|
391 throw new Zend_Uri_Exception('Internal error: password validation failed.'); |
|
392 } |
|
393 |
|
394 return $status == 1; |
|
395 } |
|
396 |
|
397 /** |
|
398 * Sets the password for the current URI, and returns the old password |
|
399 * |
|
400 * @param string $password The HTTP password |
|
401 * @throws Zend_Uri_Exception When $password is not a valid HTTP password |
|
402 * @return string |
|
403 */ |
|
404 public function setPassword($password) |
|
405 { |
|
406 if ($this->validatePassword($password) === false) { |
|
407 require_once 'Zend/Uri/Exception.php'; |
|
408 throw new Zend_Uri_Exception("Password \"$password\" is not a valid HTTP password."); |
|
409 } |
|
410 |
|
411 $oldPassword = $this->_password; |
|
412 $this->_password = $password; |
|
413 |
|
414 return $oldPassword; |
|
415 } |
|
416 |
|
417 /** |
|
418 * Returns the domain or host IP portion of the URL, or FALSE if none. |
|
419 * |
|
420 * @return string |
|
421 */ |
|
422 public function getHost() |
|
423 { |
|
424 return strlen($this->_host) > 0 ? $this->_host : false; |
|
425 } |
|
426 |
|
427 /** |
|
428 * Returns true if and only if the host string passes validation. If no host is passed, |
|
429 * then the host contained in the instance variable is used. |
|
430 * |
|
431 * @param string $host The HTTP host |
|
432 * @return boolean |
|
433 * @uses Zend_Filter |
|
434 */ |
|
435 public function validateHost($host = null) |
|
436 { |
|
437 if ($host === null) { |
|
438 $host = $this->_host; |
|
439 } |
|
440 |
|
441 // If the host is empty, then it is considered invalid |
|
442 if (strlen($host) === 0) { |
|
443 return false; |
|
444 } |
|
445 |
|
446 // Check the host against the allowed values; delegated to Zend_Filter. |
|
447 $validate = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL); |
|
448 |
|
449 return $validate->isValid($host); |
|
450 } |
|
451 |
|
452 /** |
|
453 * Sets the host for the current URI, and returns the old host |
|
454 * |
|
455 * @param string $host The HTTP host |
|
456 * @throws Zend_Uri_Exception When $host is nota valid HTTP host |
|
457 * @return string |
|
458 */ |
|
459 public function setHost($host) |
|
460 { |
|
461 if ($this->validateHost($host) === false) { |
|
462 require_once 'Zend/Uri/Exception.php'; |
|
463 throw new Zend_Uri_Exception("Host \"$host\" is not a valid HTTP host"); |
|
464 } |
|
465 |
|
466 $oldHost = $this->_host; |
|
467 $this->_host = $host; |
|
468 |
|
469 return $oldHost; |
|
470 } |
|
471 |
|
472 /** |
|
473 * Returns the TCP port, or FALSE if none. |
|
474 * |
|
475 * @return string |
|
476 */ |
|
477 public function getPort() |
|
478 { |
|
479 return strlen($this->_port) > 0 ? $this->_port : false; |
|
480 } |
|
481 |
|
482 /** |
|
483 * Returns true if and only if the TCP port string passes validation. If no port is passed, |
|
484 * then the port contained in the instance variable is used. |
|
485 * |
|
486 * @param string $port The HTTP port |
|
487 * @return boolean |
|
488 */ |
|
489 public function validatePort($port = null) |
|
490 { |
|
491 if ($port === null) { |
|
492 $port = $this->_port; |
|
493 } |
|
494 |
|
495 // If the port is empty, then it is considered valid |
|
496 if (strlen($port) === 0) { |
|
497 return true; |
|
498 } |
|
499 |
|
500 // Check the port against the allowed values |
|
501 return ctype_digit((string) $port) and 1 <= $port and $port <= 65535; |
|
502 } |
|
503 |
|
504 /** |
|
505 * Sets the port for the current URI, and returns the old port |
|
506 * |
|
507 * @param string $port The HTTP port |
|
508 * @throws Zend_Uri_Exception When $port is not a valid HTTP port |
|
509 * @return string |
|
510 */ |
|
511 public function setPort($port) |
|
512 { |
|
513 if ($this->validatePort($port) === false) { |
|
514 require_once 'Zend/Uri/Exception.php'; |
|
515 throw new Zend_Uri_Exception("Port \"$port\" is not a valid HTTP port."); |
|
516 } |
|
517 |
|
518 $oldPort = $this->_port; |
|
519 $this->_port = $port; |
|
520 |
|
521 return $oldPort; |
|
522 } |
|
523 |
|
524 /** |
|
525 * Returns the path and filename portion of the URL. |
|
526 * |
|
527 * @return string |
|
528 */ |
|
529 public function getPath() |
|
530 { |
|
531 return strlen($this->_path) > 0 ? $this->_path : '/'; |
|
532 } |
|
533 |
|
534 /** |
|
535 * Returns true if and only if the path string passes validation. If no path is passed, |
|
536 * then the path contained in the instance variable is used. |
|
537 * |
|
538 * @param string $path The HTTP path |
|
539 * @throws Zend_Uri_Exception When path validation fails |
|
540 * @return boolean |
|
541 */ |
|
542 public function validatePath($path = null) |
|
543 { |
|
544 if ($path === null) { |
|
545 $path = $this->_path; |
|
546 } |
|
547 |
|
548 // If the path is empty, then it is considered valid |
|
549 if (strlen($path) === 0) { |
|
550 return true; |
|
551 } |
|
552 |
|
553 // Determine whether the path is well-formed |
|
554 $pattern = '/^' . $this->_regex['path'] . '$/'; |
|
555 $status = @preg_match($pattern, $path); |
|
556 if ($status === false) { |
|
557 require_once 'Zend/Uri/Exception.php'; |
|
558 throw new Zend_Uri_Exception('Internal error: path validation failed'); |
|
559 } |
|
560 |
|
561 return (boolean) $status; |
|
562 } |
|
563 |
|
564 /** |
|
565 * Sets the path for the current URI, and returns the old path |
|
566 * |
|
567 * @param string $path The HTTP path |
|
568 * @throws Zend_Uri_Exception When $path is not a valid HTTP path |
|
569 * @return string |
|
570 */ |
|
571 public function setPath($path) |
|
572 { |
|
573 if ($this->validatePath($path) === false) { |
|
574 require_once 'Zend/Uri/Exception.php'; |
|
575 throw new Zend_Uri_Exception("Path \"$path\" is not a valid HTTP path"); |
|
576 } |
|
577 |
|
578 $oldPath = $this->_path; |
|
579 $this->_path = $path; |
|
580 |
|
581 return $oldPath; |
|
582 } |
|
583 |
|
584 /** |
|
585 * Returns the query portion of the URL (after ?), or FALSE if none. |
|
586 * |
|
587 * @return string |
|
588 */ |
|
589 public function getQuery() |
|
590 { |
|
591 return strlen($this->_query) > 0 ? $this->_query : false; |
|
592 } |
|
593 |
|
594 /** |
|
595 * Returns the query portion of the URL (after ?) as a |
|
596 * key-value-array. If the query is empty an empty array |
|
597 * is returned |
|
598 * |
|
599 * @return array |
|
600 */ |
|
601 public function getQueryAsArray() |
|
602 { |
|
603 $query = $this->getQuery(); |
|
604 $querryArray = array(); |
|
605 if ($query !== false) { |
|
606 parse_str($query, $querryArray); |
|
607 } |
|
608 return $querryArray; |
|
609 } |
|
610 |
|
611 /** |
|
612 * Returns true if and only if the query string passes validation. If no query is passed, |
|
613 * then the query string contained in the instance variable is used. |
|
614 * |
|
615 * @param string $query The query to validate |
|
616 * @throws Zend_Uri_Exception When query validation fails |
|
617 * @return boolean |
|
618 * @link http://www.faqs.org/rfcs/rfc2396.html |
|
619 */ |
|
620 public function validateQuery($query = null) |
|
621 { |
|
622 if ($query === null) { |
|
623 $query = $this->_query; |
|
624 } |
|
625 |
|
626 // If query is empty, it is considered to be valid |
|
627 if (strlen($query) === 0) { |
|
628 return true; |
|
629 } |
|
630 |
|
631 // Determine whether the query is well-formed |
|
632 $pattern = '/^' . $this->_regex['uric'] . '*$/'; |
|
633 $status = @preg_match($pattern, $query); |
|
634 if ($status === false) { |
|
635 require_once 'Zend/Uri/Exception.php'; |
|
636 throw new Zend_Uri_Exception('Internal error: query validation failed'); |
|
637 } |
|
638 |
|
639 return $status == 1; |
|
640 } |
|
641 |
|
642 /** |
|
643 * Add or replace params in the query string for the current URI, and |
|
644 * return the old query. |
|
645 * |
|
646 * @param array $queryParams |
|
647 * @return string Old query string |
|
648 */ |
|
649 public function addReplaceQueryParameters(array $queryParams) |
|
650 { |
|
651 $queryParams = array_merge($this->getQueryAsArray(), $queryParams); |
|
652 return $this->setQuery($queryParams); |
|
653 } |
|
654 |
|
655 /** |
|
656 * Remove params in the query string for the current URI, and |
|
657 * return the old query. |
|
658 * |
|
659 * @param array $queryParamKeys |
|
660 * @return string Old query string |
|
661 */ |
|
662 public function removeQueryParameters(array $queryParamKeys) |
|
663 { |
|
664 $queryParams = array_diff_key($this->getQueryAsArray(), array_fill_keys($queryParamKeys, 0)); |
|
665 return $this->setQuery($queryParams); |
|
666 } |
|
667 |
|
668 /** |
|
669 * Set the query string for the current URI, and return the old query |
|
670 * string This method accepts both strings and arrays. |
|
671 * |
|
672 * @param string|array $query The query string or array |
|
673 * @throws Zend_Uri_Exception When $query is not a valid query string |
|
674 * @return string Old query string |
|
675 */ |
|
676 public function setQuery($query) |
|
677 { |
|
678 $oldQuery = $this->_query; |
|
679 |
|
680 // If query is empty, set an empty string |
|
681 if (empty($query) === true) { |
|
682 $this->_query = ''; |
|
683 return $oldQuery; |
|
684 } |
|
685 |
|
686 // If query is an array, make a string out of it |
|
687 if (is_array($query) === true) { |
|
688 $query = http_build_query($query, '', '&'); |
|
689 } else { |
|
690 // If it is a string, make sure it is valid. If not parse and encode it |
|
691 $query = (string) $query; |
|
692 if ($this->validateQuery($query) === false) { |
|
693 parse_str($query, $queryArray); |
|
694 $query = http_build_query($queryArray, '', '&'); |
|
695 } |
|
696 } |
|
697 |
|
698 // Make sure the query is valid, and set it |
|
699 if ($this->validateQuery($query) === false) { |
|
700 require_once 'Zend/Uri/Exception.php'; |
|
701 throw new Zend_Uri_Exception("'$query' is not a valid query string"); |
|
702 } |
|
703 |
|
704 $this->_query = $query; |
|
705 |
|
706 return $oldQuery; |
|
707 } |
|
708 |
|
709 /** |
|
710 * Returns the fragment portion of the URL (after #), or FALSE if none. |
|
711 * |
|
712 * @return string|false |
|
713 */ |
|
714 public function getFragment() |
|
715 { |
|
716 return strlen($this->_fragment) > 0 ? $this->_fragment : false; |
|
717 } |
|
718 |
|
719 /** |
|
720 * Returns true if and only if the fragment passes validation. If no fragment is passed, |
|
721 * then the fragment contained in the instance variable is used. |
|
722 * |
|
723 * @param string $fragment Fragment of an URI |
|
724 * @throws Zend_Uri_Exception When fragment validation fails |
|
725 * @return boolean |
|
726 * @link http://www.faqs.org/rfcs/rfc2396.html |
|
727 */ |
|
728 public function validateFragment($fragment = null) |
|
729 { |
|
730 if ($fragment === null) { |
|
731 $fragment = $this->_fragment; |
|
732 } |
|
733 |
|
734 // If fragment is empty, it is considered to be valid |
|
735 if (strlen($fragment) === 0) { |
|
736 return true; |
|
737 } |
|
738 |
|
739 // Determine whether the fragment is well-formed |
|
740 $pattern = '/^' . $this->_regex['uric'] . '*$/'; |
|
741 $status = @preg_match($pattern, $fragment); |
|
742 if ($status === false) { |
|
743 require_once 'Zend/Uri/Exception.php'; |
|
744 throw new Zend_Uri_Exception('Internal error: fragment validation failed'); |
|
745 } |
|
746 |
|
747 return (boolean) $status; |
|
748 } |
|
749 |
|
750 /** |
|
751 * Sets the fragment for the current URI, and returns the old fragment |
|
752 * |
|
753 * @param string $fragment Fragment of the current URI |
|
754 * @throws Zend_Uri_Exception When $fragment is not a valid HTTP fragment |
|
755 * @return string |
|
756 */ |
|
757 public function setFragment($fragment) |
|
758 { |
|
759 if ($this->validateFragment($fragment) === false) { |
|
760 require_once 'Zend/Uri/Exception.php'; |
|
761 throw new Zend_Uri_Exception("Fragment \"$fragment\" is not a valid HTTP fragment"); |
|
762 } |
|
763 |
|
764 $oldFragment = $this->_fragment; |
|
765 $this->_fragment = $fragment; |
|
766 |
|
767 return $oldFragment; |
|
768 } |
|
769 } |