Go to the documentation of this file.00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 final class RouterTransparentRule extends RouterBaseRule
00013 {
00014 protected $urlVariable = ':';
00015 protected $urlDelimiter = '/';
00016 protected $regexDelimiter = '#';
00017
00018 protected $defaultRegex = null;
00019 protected $route = null;
00020 protected $routeProcessed = false;
00021 protected $variables = array();
00022 protected $parts = array();
00023 protected $requirements = array();
00024 protected $values = array();
00025 protected $wildcardData = array();
00026
00027 protected $staticCount = 0;
00028
00032 public static function create($route)
00033 {
00034 return new self($route);
00035 }
00036
00037 public function __construct($route)
00038 {
00039 $this->route = trim($route, $this->urlDelimiter);
00040 }
00041
00045 public function setRequirements(array $reqirements)
00046 {
00047 $this->requirements = $reqirements;
00048
00049 return $this;
00050 }
00051
00052 public function getRequirements()
00053 {
00054 return $this->requirements;
00055 }
00056
00057 public function match(HttpRequest $request)
00058 {
00059 $this->processRoute();
00060
00061 $path = $this->processPath($request)->toString();
00062
00063 $pathStaticCount = 0;
00064 $values = array();
00065
00066 $path = trim($path, $this->urlDelimiter);
00067
00068 if ($path !== '') {
00069 $path = explode($this->urlDelimiter, $path);
00070
00071 foreach ($path as $pos => $pathPart) {
00072 if (!array_key_exists($pos, $this->parts)) {
00073 return array();
00074 }
00075
00076 if ($this->parts[$pos] === '*') {
00077 $count = count($path);
00078
00079 for ($i = $pos; $i < $count; $i += 2) {
00080 $var = urldecode($path[$i]);
00081
00082 if (
00083 !isset($this->wildcardData[$var])
00084 && !isset($this->defaults[$var])
00085 && !isset($values[$var])
00086 ) {
00087 $this->wildcardData[$var] =
00088 (isset($path[$i+1]))
00089 ? urldecode($path[$i+1])
00090 : null;
00091 }
00092 }
00093
00094 break;
00095 }
00096
00097 $name =
00098 isset($this->variables[$pos])
00099 ? $this->variables[$pos]
00100 : null;
00101
00102 $pathPart = urldecode($pathPart);
00103
00104 if (
00105 ($name === null)
00106 && ($this->parts[$pos] != $pathPart)
00107 ) {
00108 return array();
00109 }
00110
00111 if (
00112 $this->parts[$pos] !== null
00113 && !preg_match(
00114 $this->regexDelimiter
00115 .'^'.$this->parts[$pos].'$'
00116 .$this->regexDelimiter.'iu',
00117 $pathPart
00118 )
00119 ) {
00120 return array();
00121 }
00122
00123 if ($name !== null) {
00124 $values[$name] = $pathPart;
00125 } else {
00126 ++$pathStaticCount;
00127 }
00128 }
00129 }
00130
00131 if ($this->staticCount != $pathStaticCount)
00132 return array();
00133
00134 $return = $values + $this->wildcardData + $this->defaults;
00135
00136 foreach ($this->variables as $var) {
00137 if (!array_key_exists($var, $return))
00138 return array();
00139 }
00140
00141 $this->values = $values;
00142
00143 return $return;
00144 }
00145
00156 public function assembly(
00157 array $data = array(),
00158 $reset = false,
00159 $encode = false
00160 )
00161 {
00162 $this->processRoute();
00163
00164 $url = array();
00165 $flag = false;
00166
00167 foreach ($this->parts as $key => $part) {
00168 $name =
00169 isset($this->variables[$key])
00170 ? $this->variables[$key]
00171 : null;
00172
00173 $useDefault = false;
00174
00175 if (
00176 $name
00177 && array_key_exists($name, $data)
00178 && ($data[$name] === null)
00179 ) {
00180 $useDefault = true;
00181 }
00182
00183 if ($name) {
00184 if (
00185 isset($data[$name])
00186 && !$useDefault
00187 ) {
00188 $url[$key] = $data[$name];
00189 unset($data[$name]);
00190 } elseif (
00191 !$reset
00192 && !$useDefault
00193 && isset($this->values[$name])
00194 ) {
00195 $url[$key] = $this->values[$name];
00196 } elseif (
00197 !$reset
00198 && !$useDefault
00199 && isset($this->wildcardData[$name])
00200 ) {
00201 $url[$key] = $this->wildcardData[$name];
00202 } elseif (isset($this->defaults[$name])) {
00203 $url[$key] = $this->defaults[$name];
00204 } else {
00205
00206 throw new RouterException("{$name} is not specified");
00207 }
00208 } elseif ($part !== '*') {
00209 $url[$key] = $part;
00210 } else {
00211 if (!$reset)
00212 $data += $this->wildcardData;
00213
00214 foreach ($data as $var => $value) {
00215 if ($value !== null) {
00216 if (
00217 isset($this->defaults[$var])
00218 && ($this->defaults[$var] === $value)
00219 ) {
00220 continue;
00221 }
00222
00223 $url[$key++] = $var;
00224 $url[$key++] = $value;
00225 $flag = true;
00226 }
00227 }
00228 }
00229 }
00230
00231 $return = null;
00232
00233 foreach (array_reverse($url, true) as $key => $value) {
00234 if (
00235 $flag
00236 || !isset($this->variables[$key])
00237 || ($value !== $this->getDefault($this->variables[$key]))
00238 ) {
00239 if ($encode)
00240 $value = urlencode($value);
00241
00242 $return =
00243 $this->urlDelimiter
00244 .$value
00245 .$return;
00246
00247 $flag = true;
00248 }
00249 }
00250
00251
00252 return trim($return, $this->urlDelimiter);
00253 }
00254
00258 protected function processRoute()
00259 {
00260 if ($this->routeProcessed)
00261 return $this;
00262
00263 if ($this->route !== '') {
00264 foreach (explode($this->urlDelimiter, $this->route) as $pos => $part) {
00265 if (substr($part, 0, 1) == $this->urlVariable) {
00266 $name = substr($part, 1);
00267
00268 $this->parts[$pos] = (
00269 isset($this->requirements[$name])
00270 ? $this->requirements[$name]
00271 : $this->defaultRegex
00272 );
00273
00274 $this->variables[$pos] = $name;
00275 } else {
00276 $this->parts[$pos] = $part;
00277
00278 if ($part !== '*')
00279 $this->staticCount++;
00280 }
00281 }
00282 }
00283
00284 $this->routeProcessed = true;
00285
00286 return $this;
00287 }
00288 }
00289 ?>