Http.php
00001 <?php
00012 class Dsao_Uri_Http extends Dsao_DataHandler_Abstract
00013 {
00017 protected static $_baseUri = null;
00018
00022 protected $_fragment = null;
00023
00027 protected static $_host = null;
00028
00032 protected $_data = array();
00033
00037 protected $_propertiesMandatory = array('module', 'controller', 'action');
00038
00042 protected $_propertiesProtected = array('module', 'controller', 'action');
00043
00047 protected static $_scheme = 'http';
00048
00052 protected static $_token = null;
00053
00062 public function __construct($uri = null, array $parameters = array(), $readOnly = false)
00063 {
00064 $this->setUri($uri);
00065
00066 parent::__construct($parameters, $readOnly);
00067 }
00068
00074 public function __toString()
00075 {
00076 return $this->toString();
00077 }
00078
00088 protected function _getParametersString($parameters)
00089 {
00090
00091 $parametersString = '';
00092
00093
00094 if (null === $this->_data || false === $parameters)
00095 {
00096 return $parametersString;
00097 }
00098
00099
00100 ksort($this->_data);
00101
00102
00103 $parameters = (array) $parameters;
00104
00105
00106 $parametersNames = array();
00107
00108
00109 foreach ($parameters as $parameter)
00110 {
00111
00112 if (is_bool($parameter))
00113 {
00114 $parametersNames =
00115 (true === $parameter ? $this->_data : array());
00116
00117 continue;
00118 }
00119
00120
00121 if (isset($this->_data[$parameter]))
00122 {
00123
00124 if (isset($parametersNames[$parameter]))
00125 {
00126 unset($parametersNames[$parameter]);
00127 }
00128
00129 else
00130 {
00131 $parametersNames[$parameter] = true;
00132 }
00133 }
00134 }
00135
00136
00137 foreach ($parametersNames as $parameter => $value)
00138 {
00139
00140 if (in_array($parameter,
00141 array('action', 'controller', 'module', 'token', 'error_handler')))
00142 {
00143 continue;
00144 }
00145
00146 $parametersString .= '/'.$parameter.'/'. urlencode((string) $this->_data[$parameter]);
00147 }
00148
00149 return $parametersString;
00150 }
00151
00160 protected function _parsePath($module, $controller, $action)
00161 {
00162
00163 $adress = array(
00164 'module' => $module,
00165 'controller' => $controller,
00166 'action' => $action
00167 );
00168
00169
00170 foreach ($adress as $part => $value)
00171 {
00172
00173 if (!$value)
00174 {
00175 continue;
00176 }
00177
00178 $this->_data[$part] = $value;
00179 }
00180 }
00181
00188 protected function _parseQuery($query)
00189 {
00190
00191 if (!$query)
00192 {
00193 return;
00194 }
00195
00196
00197 foreach (explode('&', $query) as $parameter)
00198 {
00199 $parts = explode('=', $parameter);
00200
00201 $this->_data[$parts[0]] = (isset($parts[1]) ? $parts[1] : true);
00202 }
00203 }
00204
00212 protected function _parseUri($uri)
00213 {
00214
00215 $pattern =
00216 '~^((?<protocol>https?|ftp)://(?<host>[^/?#]*))?/'.
00217 '(?<baseUri>'.self::$_baseUri.'/)?((?<module>[^/?#]*)/)?'.
00218 '((?<controller>[^/?#]*)/)?(?<action>[^/?#]*)?'.
00219 '(?<userParameters>[^?#]*)?\??((?<query>[^#]*))?#?(?<fragment>.*)?$~';
00220
00221 preg_match($pattern, $uri, $matches);
00222
00223
00224 if (empty($matches))
00225 {
00226 return;
00227 }
00228
00229
00230 if ($matches['host'] && $matches['host'] != self::$_host)
00231 {
00232 throw new Dsao_Exception(array(
00233 'message' => 'dsao_uri_http_unknown_host',
00234 'variables' => array('host' => $matches['host']),
00235 ));
00236 }
00237
00238
00239 $this->_fragment = $matches['fragment'];
00240
00241
00242
00243
00244 $this->_parseQuery($matches['query']);
00245
00246
00247 $this->_parseUserParameters($matches['userParameters']);
00248
00249
00250 $this->_parsePath
00251 ($matches['module'], $matches['controller'], $matches['action']);
00252
00253 }
00254
00261 protected function _parseUserParameters($parameters)
00262 {
00263
00264 if (!$parameters)
00265 {
00266 return;
00267 }
00268
00269
00270 $partsParameters = explode('/', $parameters);
00271
00272
00273 $countPartsParameters = count($partsParameters);
00274
00275
00276 for ($i = 0; $i < $countPartsParameters; $i += 2)
00277 {
00278
00279
00280 if (!$partsParameters[$i])
00281 {
00282 $i--;
00283 continue;
00284 }
00285
00286
00287
00288 if ($i == ($countPartsParameters-1) || !$partsParameters[($i+1)])
00289 {
00290 $partsParameters[($i+1)] = true;
00291 }
00292
00293
00294 $this->_data[$partsParameters[$i]] =
00295 urldecode($partsParameters[($i+1)]);
00296 }
00297 }
00298
00313 public function createUriString($uri, $appendToken = true, $absolute = false)
00314 {
00315
00316 $uriResult = '';
00317
00318
00319 if ($absolute)
00320 {
00321 $uriResult .= self::$_scheme.'://'.self::$_host;
00322 }
00323
00324
00325 $uri = '/'. ltrim($uri, '/');
00326
00327
00328 $uriResult .= (self::$_baseUri ? self::$_baseUri.$uri : $uri);
00329
00330
00331 if ($appendToken)
00332 {
00333 $uriResult .= '/token/'.self::getToken();
00334 }
00335
00336 return $uriResult.($this->_fragment ? '#'.$this->_fragment : '');
00337 }
00338
00344 public function getAclResourceId()
00345 {
00346 return $this->_data['module'].'_'.
00347 $this->_data['controller'].'_'.$this->_data['action'];
00348 }
00349
00355 public function getFragment()
00356 {
00357 return $this->_fragment;
00358 }
00359
00367 public function getParameters($parameters = null, $default = null)
00368 {
00369 return parent::getData($parameters, $default);
00370 }
00371
00377 public static function getToken()
00378 {
00379 return self::$_token;
00380 }
00381
00392 public function getUriString($parameters = true, $appendToken = false, $absolute = false)
00393 {
00394 return $this->toString($parameters, $appendToken, $absolute);
00395 }
00396
00406 public function hasParameters(array $parametersNames = array(), $or = false)
00407 {
00408 return parent::hasData($parametersNames, $or, array('token'));
00409 }
00410
00417 public static function setBaseUri($baseUri)
00418 {
00419 self::$_baseUri = $baseUri;
00420 }
00421
00428 public function setFragment($fragment)
00429 {
00430 $this->_fragment = (string) $fragment;
00431
00432 return $this;
00433 }
00434
00441 public static function setHost($host)
00442 {
00443 self::$_host = $host;
00444 }
00445
00453 public function setParameters(array $parameters = array(), $overwrite = true)
00454 {
00455 return parent::setData($parameters, $overwrite);
00456 }
00457
00464 public static function setScheme($scheme = 'http')
00465 {
00466 self::$_scheme = $scheme;
00467 }
00468
00475 public static function setToken($token = null)
00476 {
00477
00478 if (null === $token)
00479 {
00480 $token = Dsao_Hash::factory()->getHash(4);
00481 }
00482
00483 self::$_token = $token;
00484
00485 return $token;
00486 }
00487
00494 public function setUri($uri = false)
00495 {
00496
00497 if (false === $uri)
00498 {
00499 $this->setParameters(array(
00500 'module' => null,
00501 'controller' => null,
00502 'action' => null));
00503 }
00504 else
00505 {
00506 $this->_parseUri($uri);
00507 }
00508
00509 return $this;
00510 }
00511
00521 public function toString($parameters = true, $appendToken = false, $absolute = false)
00522 {
00523
00524 $this->isValid(true);
00525
00526
00527 $parametersString = $this->_getParametersString($parameters);
00528
00529
00530 $uri = '/'.$this->_data['module'].'/'.
00531 $this->_data['controller'].'/'.$this->_data['action'].
00532 $parametersString;
00533
00534
00535 return $this->createUriString($uri, $appendToken, $absolute);
00536 }
00537 }