Go to the documentation of this file.00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 final class RouterHostnameRule extends RouterBaseRule
00013 {
00014 const SCHEME_HTTP = 'http';
00015 const SCHEME_HTTPS = 'https';
00016
00017 protected $hostVariable = ':';
00018 protected $regexDelimiter = '#';
00019
00020 protected $scheme = null;
00021 protected $defaultRegex = null;
00022 protected $route = null;
00023 protected $routeProcessed = false;
00024 protected $variables = array();
00025 protected $parts = array();
00026 protected $requirements = array();
00027 protected $values = array();
00028
00029 protected $staticCount = 0;
00030
00034 public static function create($route)
00035 {
00036 return new self($route);
00037 }
00038
00039 public function __construct($route)
00040 {
00041 $this->route = trim($route, '.');
00042 $this->scheme = self::SCHEME_HTTP;
00043 }
00044
00048 public function setRequirements(array $reqirements)
00049 {
00050 $this->requirements = $reqirements;
00051
00052 return $this;
00053 }
00054
00055 public function getRequirements()
00056 {
00057 return $this->requirements;
00058 }
00059
00063 public function setSecure()
00064 {
00065 $this->scheme = self::SCHEME_HTTPS;
00066
00067 return $this;
00068 }
00069
00070 public function isSecure()
00071 {
00072 return $this->scheme == self::SCHEME_HTTPS;
00073 }
00074
00078 public function setScheme($schema)
00079 {
00080 $this->scheme = $schema;
00081
00082 return $this;
00083 }
00084
00085 public function getScheme()
00086 {
00087 return $this->scheme;
00088 }
00089
00090 public function match(HttpRequest $request)
00091 {
00092 $this->processRoute();
00093
00094 if (
00095 $this->isSecureRequest($request)
00096 && !$this->isSecure()
00097 )
00098 return array();
00099
00100 if ($request->hasServerVar('HTTP_HOST'))
00101 $host = $request->getServerVar('HTTP_HOST');
00102 else
00103 throw new RouterException('Can not find host');
00104
00105 $result = array();
00106
00107 if (preg_match('#:\d+$#', $host, $result) === 1)
00108 $host = substr($host, 0, -strlen($result[0]));
00109
00110 $hostStaticCount = 0;
00111 $values = array();
00112
00113 $host = trim($host, '.');
00114
00115
00116 if ($host) {
00117 $host = explode('.', $host);
00118
00119 foreach ($host as $pos => $hostPart) {
00120 if (!array_key_exists($pos, $this->parts)) {
00121 return array();
00122 }
00123
00124 $name =
00125 isset($this->variables[$pos])
00126 ? $this->variables[$pos]
00127 : null;
00128
00129 $hostPart = urldecode($hostPart);
00130
00131 if (
00132 ($name === null)
00133 && ($this->parts[$pos] != $hostPart)
00134 ) {
00135 return array();
00136 }
00137
00138 if (
00139 ($this->parts[$pos] !== null)
00140 && !preg_match(
00141 $this->regexDelimiter
00142 .'^'.$this->parts[$pos].'$'
00143 .$this->regexDelimiter.'iu',
00144
00145 $hostPart
00146 )
00147 ) {
00148 return array();
00149 }
00150
00151 if ($name !== null) {
00152 $values[$name] = $hostPart;
00153 } else {
00154 ++$hostStaticCount;
00155 }
00156 }
00157 }
00158
00159 if ($this->staticCount != $hostStaticCount)
00160 return array();
00161
00162 $return = $values + $this->defaults;
00163
00164 foreach ($this->variables as $var) {
00165 if (!array_key_exists($var, $return))
00166 return array();
00167 }
00168
00169 $this->values = $values;
00170
00171 return $return;
00172 }
00173
00174 public function assembly(
00175 array $data = array(),
00176 $reset = false,
00177 $encode = false
00178 )
00179 {
00180 $this->processRoute();
00181
00182 $host = array();
00183 $flag = false;
00184
00185 foreach ($this->parts as $key => $part) {
00186 $name =
00187 isset($this->variables[$key])
00188 ? $this->variables[$key]
00189 : null;
00190
00191 $useDefault = false;
00192
00193 if (
00194 isset($name)
00195 && array_key_exists($name, $data)
00196 && ($data[$name] === null)
00197 ) {
00198 $useDefault = true;
00199 }
00200
00201 if ($name) {
00202 if (isset($data[$name]) && !$useDefault) {
00203 $host[$key] = $data[$name];
00204 unset($data[$name]);
00205 } elseif (
00206 !$reset
00207 && !$useDefault
00208 && isset($this->values[$name])
00209 ) {
00210 $host[$key] = $this->values[$name];
00211 } elseif (isset($this->defaults[$name])) {
00212 $host[$key] = $this->defaults[$name];
00213 } else {
00214
00215 throw new RouterException($name . ' is not specified');
00216 }
00217 } else {
00218 $host[$key] = $part;
00219 }
00220 }
00221
00222 $return = null;
00223
00224 foreach (array_reverse($host, true) as $key => $value) {
00225 if (
00226 $flag
00227 || !isset($this->variables[$key])
00228 || ($value !== $this->getDefault($this->variables[$key]))
00229 ) {
00230 if ($encode)
00231 $value = urlencode($value);
00232
00233 $return = '.'.$value.$return;
00234 $flag = true;
00235 }
00236 }
00237
00238
00239 $host = trim($return, '.');
00240
00241 return $this->resolveSchema() . '://' . $host . $this->resolvePath();
00242
00243 }
00244
00248 protected function processRoute()
00249 {
00250 if ($this->routeProcessed)
00251 return $this;
00252
00253
00254 if ($this->route) {
00255 foreach (explode('.', $this->route) as $pos => $part) {
00256 if (substr($part, 0, 1) == $this->hostVariable) {
00257 $name = substr($part, 1);
00258
00259 $this->parts[$pos] = (
00260 isset($this->requirements[$name])
00261 ? $this->requirements[$name]
00262 : $this->defaultRegex
00263 );
00264
00265 $this->variables[$pos] = $name;
00266 } else {
00267 $this->parts[$pos] = $part;
00268 ++$this->staticCount;
00269 }
00270 }
00271 }
00272
00273 $this->routeProcessed = true;
00274
00275 return $this;
00276 }
00277
00278 protected function isSecureRequest(HttpRequest $request)
00279 {
00280 return (
00281 $request->hasServerVar('HTTPS')
00282 && $request->getServerVar('HTTPS') == 'on'
00283 ) || (
00284 $request->hasServerVar('SERVER_PORT')
00285 && (int) $request->getServerVar('SERVER_PORT') === 443
00286 );
00287 }
00288
00289 protected function resolveSchema()
00290 {
00291 $base = RouterRewrite::me()->getBaseUrl();
00292
00293 if ($this->scheme) {
00294 return $this->scheme;
00295 } elseif (
00296 ($base instanceof HttpUrl)
00297 && $base->getScheme()
00298 ) {
00299 return $base->getScheme();
00300 } else {
00301 throw new RouterException('Cannot resolve scheme');
00302 }
00303 }
00304
00305 protected function resolvePath()
00306 {
00307 if (
00308 ($base = RouterRewrite::me()->getBaseUrl())
00309 && ($this->scheme == $base->getScheme())
00310 ) {
00311 return rtrim($base->getPath(), '/');
00312 } else {
00313 return '';
00314 }
00315 }
00316 }
00317 ?>