TeamSpeak 3 PHP Framework  1.1.16
Copyright © Planet TeamSpeak. All rights reserved.
 All Classes Namespaces Files Functions Variables Pages
Uri.php
Go to the documentation of this file.
1 <?php
2 
3 /**
4  * @file
5  * TeamSpeak 3 PHP Framework
6  *
7  * $Id: Uri.php 8/31/2012 11:06:09 scp@orilla $
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  *
22  * @package TeamSpeak3
23  * @version 1.1.16
24  * @author Sven 'ScP' Paulsen
25  * @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
26  */
27 
28 /**
29  * @class TeamSpeak3_Helper_Uri
30  * @brief Helper class for URI handling.
31  */
33 {
34  /**
35  * Stores the URI scheme.
36  *
37  * @var string
38  */
39  protected $scheme = null;
40 
41  /**
42  * Stores the URI username
43  *
44  * @var string
45  */
46  protected $user = null;
47 
48  /**
49  * Stores the URI password.
50  *
51  * @var string
52  */
53  protected $pass = null;
54 
55  /**
56  * Stores the URI host.
57  *
58  * @var string
59  */
60  protected $host = null;
61 
62  /**
63  * Stores the URI port.
64  *
65  * @var string
66  */
67  protected $port = null;
68 
69  /**
70  * Stores the URI path.
71  *
72  * @var string
73  */
74  protected $path = null;
75 
76  /**
77  * Stores the URI query string.
78  *
79  * @var string
80  */
81  protected $query = null;
82 
83  /**
84  * Stores the URI fragment string.
85  *
86  * @var string
87  */
88  protected $fragment = null;
89 
90  /**
91  * Stores grammar rules for validation via regex.
92  *
93  * @var array
94  */
95  protected $regex = array();
96 
97  /**
98  * The TeamSpeak3_Helper_Uri constructor.
99  *
100  * @param string $uri
101  * @throws TeamSpeak3_Helper_Exception
102  * @return TeamSpeak3_Helper_Uri
103  */
104  public function __construct($uri)
105  {
106  $uri = explode(":", strval($uri), 2);
107 
108  $this->scheme = strtolower($uri[0]);
109  $uriString = isset($uri[1]) ? $uri[1] : "";
110 
111  if(!ctype_alnum($this->scheme))
112  {
113  throw new TeamSpeak3_Helper_Exception("invalid URI scheme '" . $this->scheme . "' supplied");
114  }
115 
116  /* grammar rules for validation */
117  $this->regex["alphanum"] = "[^\W_]";
118  $this->regex["escaped"] = "(?:%[\da-fA-F]{2})";
119  $this->regex["mark"] = "[-_.!~*'()\[\]]";
120  $this->regex["reserved"] = "[;\/?:@&=+$,]";
121  $this->regex["unreserved"] = "(?:" . $this->regex["alphanum"] . "|" . $this->regex["mark"] . ")";
122  $this->regex["segment"] = "(?:(?:" . $this->regex["unreserved"] . "|" . $this->regex["escaped"] . "|[:@&=+$,;])*)";
123  $this->regex["path"] = "(?:\/" . $this->regex["segment"] . "?)+";
124  $this->regex["uric"] = "(?:" . $this->regex["reserved"] . "|" . $this->regex["unreserved"] . "|" . $this->regex["escaped"] . ")";
125 
126  if(strlen($uriString) > 0)
127  {
128  $this->parseUri($uriString);
129  }
130 
131  if(!$this->isValid())
132  {
133  throw new TeamSpeak3_Helper_Exception("invalid URI supplied");
134  }
135  }
136 
137  /**
138  * Parses the scheme-specific portion of the URI and place its parts into instance variables.
139  *
140  * @throws TeamSpeak3_Helper_Exception
141  * @return void
142  */
143  protected function parseUri($uriString = '')
144  {
145  $status = @preg_match("~^((//)([^/?#]*))([^?#]*)(\?([^#]*))?(#(.*))?$~", $uriString, $matches);
146 
147  if($status === FALSE)
148  {
149  throw new TeamSpeak3_Helper_Exception("URI scheme-specific decomposition failed");
150  }
151 
152  if(!$status) return;
153 
154  $this->path = (isset($matches[4])) ? $matches[4] : '';
155  $this->query = (isset($matches[6])) ? $matches[6] : '';
156  $this->fragment = (isset($matches[8])) ? $matches[8] : '';
157 
158  $status = @preg_match("~^(([^:@]*)(:([^@]*))?@)?([^:]+)(:(.*))?$~", (isset($matches[3])) ? $matches[3] : "", $matches);
159 
160  if($status === FALSE)
161  {
162  throw new TeamSpeak3_Helper_Exception("URI scheme-specific authority decomposition failed");
163  }
164 
165  if(!$status) return;
166 
167  $this->user = isset($matches[2]) ? $matches[2] : "";
168  $this->pass = isset($matches[4]) ? $matches[4] : "";
169  $this->host = isset($matches[5]) ? $matches[5] : "";
170  $this->port = isset($matches[7]) ? $matches[7] : "";
171  }
172 
173  /**
174  * Validate the current URI from the instance variables.
175  *
176  * @return boolean
177  */
178  public function isValid()
179  {
180  return ($this->checkUser() && $this->checkPass() && $this->checkHost() && $this->checkPort() && $this->checkPath() && $this->checkQuery() && $this->checkFragment());
181  }
182 
183  /**
184  * Returns TRUE if a given URI is valid.
185  *
186  * @param string $uri
187  * @return boolean
188  */
189  public static function check($uri)
190  {
191  try
192  {
193  $uri = new self(strval($uri));
194  }
195  catch(Exception $e)
196  {
197  return FALSE;
198  }
199 
200  return $uri->valid();
201  }
202 
203  /**
204  * Returns TRUE if the URI has a scheme.
205  *
206  * @return boolean
207  */
208  public function hasScheme()
209  {
210  return strlen($this->scheme) ? TRUE : FALSE;
211  }
212 
213  /**
214  * Returns the scheme.
215  *
216  * @param mixed default
217  * @return TeamSpeak3_Helper_String
218  */
219  public function getScheme($default = null)
220  {
221  return ($this->hasScheme()) ? new TeamSpeak3_Helper_String($this->scheme) : $default;
222  }
223 
224  /**
225  * Returns TRUE if the username is valid.
226  *
227  * @param string $username
228  * @throws TeamSpeak3_Helper_Exception
229  * @return boolean
230  */
231  public function checkUser($username = null)
232  {
233  if($username === null)
234  {
235  $username = $this->user;
236  }
237 
238  if(strlen($username) == 0)
239  {
240  return TRUE;
241  }
242 
243  $pattern = "/^(" . $this->regex["alphanum"] . "|" . $this->regex["mark"] . "|" . $this->regex["escaped"] . "|[;:&=+$,])+$/";
244  $status = @preg_match($pattern, $username);
245 
246  if($status === FALSE)
247  {
248  throw new TeamSpeak3_Helper_Exception("URI username validation failed");
249  }
250 
251  return ($status == 1);
252  }
253 
254  /**
255  * Returns TRUE if the URI has a username.
256  *
257  * @return boolean
258  */
259  public function hasUser()
260  {
261  return strlen($this->user) ? TRUE : FALSE;
262  }
263 
264  /**
265  * Returns the username.
266  *
267  * @param mixed default
268  * @return TeamSpeak3_Helper_String
269  */
270  public function getUser($default = null)
271  {
272  return ($this->hasUser()) ? new TeamSpeak3_Helper_String($this->user) : $default;
273  }
274 
275  /**
276  * Returns TRUE if the password is valid.
277  *
278  * @param string $password
279  * @throws TeamSpeak3_Helper_Exception
280  * @return boolean
281  */
282  public function checkPass($password = null)
283  {
284  if($password === null) {
285  $password = $this->pass;
286  }
287 
288  if(strlen($password) == 0)
289  {
290  return TRUE;
291  }
292 
293  $pattern = "/^(" . $this->regex["alphanum"] . "|" . $this->regex["mark"] . "|" . $this->regex["escaped"] . "|[;:&=+$,])+$/";
294  $status = @preg_match($pattern, $password);
295 
296  if($status === FALSE)
297  {
298  throw new TeamSpeak3_Helper_Exception("URI password validation failed");
299  }
300 
301  return ($status == 1);
302  }
303 
304  /**
305  * Returns TRUE if the URI has a password.
306  *
307  * @return boolean
308  */
309  public function hasPass()
310  {
311  return strlen($this->pass) ? TRUE : FALSE;
312  }
313 
314  /**
315  * Returns the password.
316  *
317  * @param mixed default
318  * @return TeamSpeak3_Helper_String
319  */
320  public function getPass($default = null)
321  {
322  return ($this->hasPass()) ? new TeamSpeak3_Helper_String($this->pass) : $default;
323  }
324 
325  /**
326  * Returns TRUE if the host is valid.
327  *
328  * @param string $host
329  * @return boolean
330  */
331  public function checkHost($host = null)
332  {
333  if($host === null)
334  {
335  $host = $this->host;
336  }
337 
338  return TRUE;
339  }
340 
341  /**
342  * Returns TRUE if the URI has a host.
343  *
344  * @return boolean
345  */
346  public function hasHost()
347  {
348  return strlen($this->host) ? TRUE : FALSE;
349  }
350 
351  /**
352  * Returns the host.
353  *
354  * @param mixed default
355  * @return TeamSpeak3_Helper_String
356  */
357  public function getHost($default = null)
358  {
359  return ($this->hasHost()) ? new TeamSpeak3_Helper_String($this->host) : $default;
360  }
361 
362  /**
363  * Returns TRUE if the port is valid.
364  *
365  * @param integer $port
366  * @return boolean
367  */
368  public function checkPort($port = null)
369  {
370  if($port === null)
371  {
372  $port = $this->port;
373  }
374 
375  return TRUE;
376  }
377 
378  /**
379  * Returns TRUE if the URI has a port.
380  *
381  * @return boolean
382  */
383  public function hasPort()
384  {
385  return strlen($this->port) ? TRUE : FALSE;
386  }
387 
388  /**
389  * Returns the port.
390  *
391  * @param mixed default
392  * @return integer
393  */
394  public function getPort($default = null)
395  {
396  return ($this->hasPort()) ? intval($this->port) : $default;
397  }
398 
399  /**
400  * Returns TRUE if the path is valid.
401  *
402  * @param string $path
403  * @throws TeamSpeak3_Helper_Exception
404  * @return boolean
405  */
406  public function checkPath($path = null)
407  {
408  if($path === null)
409  {
410  $path = $this->path;
411  }
412 
413  if(strlen($path) == 0)
414  {
415  return TRUE;
416  }
417 
418  $pattern = "/^" . $this->regex["path"] . "$/";
419  $status = @preg_match($pattern, $path);
420 
421  if($status === FALSE)
422  {
423  throw new TeamSpeak3_Helper_Exception("URI path validation failed");
424  }
425 
426  return ($status == 1);
427  }
428 
429  /**
430  * Returns TRUE if the URI has a path.
431  *
432  * @return boolean
433  */
434  public function hasPath()
435  {
436  return strlen($this->path) ? TRUE : FALSE;
437  }
438 
439  /**
440  * Returns the path.
441  *
442  * @param mixed default
443  * @return TeamSpeak3_Helper_String
444  */
445  public function getPath($default = null)
446  {
447  return ($this->hasPath()) ? new TeamSpeak3_Helper_String($this->path) : $default;
448  }
449 
450  /**
451  * Returns TRUE if the query string is valid.
452  *
453  * @param string $query
454  * @throws TeamSpeak3_Helper_Exception
455  * @return boolean
456  */
457  public function checkQuery($query = null)
458  {
459  if($query === null)
460  {
461  $query = $this->query;
462  }
463 
464  if(strlen($query) == 0)
465  {
466  return TRUE;
467  }
468 
469  $pattern = "/^" . $this->regex["uric"] . "*$/";
470  $status = @preg_match($pattern, $query);
471 
472  if($status === FALSE)
473  {
474  throw new TeamSpeak3_Helper_Exception("URI query string validation failed");
475  }
476 
477  return ($status == 1);
478  }
479 
480  /**
481  * Returns TRUE if the URI has a query string.
482  *
483  * @return boolean
484  */
485  public function hasQuery()
486  {
487  return strlen($this->query) ? TRUE : FALSE;
488  }
489 
490  /**
491  * Returns an array containing the query string elements.
492  *
493  * @param mixed $default
494  * @return array
495  */
496  public function getQuery($default = array())
497  {
498  if(!$this->hasQuery())
499  {
500  return $default;
501  }
502 
503  parse_str($this->query, $queryArray);
504 
505  return $queryArray;
506  }
507 
508  /**
509  * Returns TRUE if the URI has a query variable.
510  *
511  * @return boolean
512  */
513  public function hasQueryVar($key)
514  {
515  if(!$this->hasQuery()) return FALSE;
516 
517  parse_str($this->query, $queryArray);
518 
519  return array_key_exists($key, $queryArray) ? TRUE : FALSE;
520  }
521 
522  /**
523  * Returns a single variable from the query string.
524  *
525  * @param string $key
526  * @param mixed $default
527  * @return mixed
528  */
529  public function getQueryVar($key, $default = null)
530  {
531  if(!$this->hasQuery()) return $default;
532 
533  parse_str($this->query, $queryArray);
534 
535  if(array_key_exists($key, $queryArray))
536  {
537  $val = $queryArray[$key];
538 
539  if(ctype_digit($val))
540  {
541  return intval($val);
542  }
543  elseif(is_string($val))
544  {
545  return new TeamSpeak3_Helper_String($val);
546  }
547  else
548  {
549  return $val;
550  }
551  }
552 
553  return $default;
554  }
555 
556  /**
557  * Returns TRUE if the fragment string is valid.
558  *
559  * @param string $fragment
560  * @throws TeamSpeak3_Helper_Exception
561  * @return boolean
562  */
563  public function checkFragment($fragment = null)
564  {
565  if($fragment === null)
566  {
567  $fragment = $this->fragment;
568  }
569 
570  if(strlen($fragment) == 0)
571  {
572  return TRUE;
573  }
574 
575  $pattern = "/^" . $this->regex["uric"] . "*$/";
576  $status = @preg_match($pattern, $fragment);
577 
578  if($status === FALSE)
579  {
580  throw new TeamSpeak3_Helper_Exception("URI fragment validation failed");
581  }
582 
583  return ($status == 1);
584  }
585 
586  /**
587  * Returns TRUE if the URI has a fragment string.
588  *
589  * @return boolean
590  */
591  public function hasFragment()
592  {
593  return strlen($this->fragment) ? TRUE : FALSE;
594  }
595 
596  /**
597  * Returns the fragment.
598  *
599  * @param mixed default
600  * @return TeamSpeak3_Helper_String
601  */
602  public function getFragment($default = null)
603  {
604  return ($this->hasFragment()) ? new TeamSpeak3_Helper_String($this->fragment) : $default;
605  }
606 
607  /**
608  * Returns a specified instance parameter from the $_REQUEST array.
609  *
610  * @param string $key
611  * @param mixed $default
612  * @return mixed
613  */
614  public static function getUserParam($key, $default = null)
615  {
616  return (array_key_exists($key, $_REQUEST) && !empty($_REQUEST[$key])) ? self::stripslashesRecursive($_REQUEST[$key]) : $default;
617  }
618 
619  /**
620  * Returns a specified environment parameter from the $_SERVER array.
621  *
622  * @param string $key
623  * @param mixed $default
624  * @return mixed
625  */
626  public static function getHostParam($key, $default = null)
627  {
628  return (array_key_exists($key, $_SERVER) && !empty($_SERVER[$key])) ? $_SERVER[$key] : $default;
629  }
630 
631  /**
632  * Returns a specified session parameter from the $_SESSION array.
633  *
634  * @param string $key
635  * @param mixed $default
636  * @return mixed
637  */
638  public static function getSessParam($key, $default = null)
639  {
640  return (array_key_exists($key, $_SESSION) && !empty($_SESSION[$key])) ? $_SESSION[$key] : $default;
641  }
642 
643  /**
644  * Returns an array containing the three main parts of a FQDN (Fully Qualified Domain Name), including the
645  * top-level domain, the second-level domains or hostname and the third-level domain.
646  *
647  * @param string $hostname
648  * @return array
649  */
650  public static function getFQDNParts($hostname)
651  {
652  if(!preg_match("/^([a-z0-9][a-z0-9-]{0,62}\.)*([a-z0-9][a-z0-9-]{0,62}\.)+([a-z]{2,6})$/i", $hostname, $matches))
653  {
654  return array();
655  }
656 
657  $parts["tld"] = $matches[3];
658  $parts["2nd"] = $matches[2];
659  $parts["3rd"] = $matches[1];
660 
661  return $parts;
662  }
663 
664  /**
665  * Returns the applications host address.
666  *
667  * @return TeamSpeak3_Helper_String
668  */
669  public static function getHostUri()
670  {
671  $sheme = (self::getHostParam("HTTPS") == "on") ? "https" : "http";
672 
673  $serverName = new TeamSpeak3_Helper_String(self::getHostParam("HTTP_HOST"));
674  $serverPort = self::getHostParam("SERVER_PORT");
675  $serverPort = ($serverPort != 80 && $serverPort != 443) ? ":" . $serverPort : "";
676 
677  if($serverName->endsWith($serverPort))
678  {
679  $serverName = $serverName->replace($serverPort, "");
680  }
681 
682  return new TeamSpeak3_Helper_String($sheme . "://" . $serverName . $serverPort);
683  }
684 
685  /**
686  * Returns the applications base address.
687  *
688  * @return string
689  */
690  public static function getBaseUri()
691  {
692  $scriptPath = new TeamSpeak3_Helper_String(dirname(self::getHostParam("SCRIPT_NAME")));
693 
694  return self::getHostUri()->append(($scriptPath == DIRECTORY_SEPARATOR ? "" : $scriptPath) . "/");
695  }
696 
697  /**
698  * Strips slashes from each element of an array using stripslashes().
699  *
700  * @param mixed $var
701  * @return mixed
702  */
703  protected static function stripslashesRecursive($var)
704  {
705  if(!is_array($var))
706  {
707  return stripslashes(strval($var));
708  }
709 
710  foreach($var as $key => $val)
711  {
712  $var[$key] = (is_array($val)) ? stripslashesRecursive($val) : stripslashes(strval($val));
713  }
714 
715  return $var;
716  }
717 }