# RouterTransparentRule.class.php

Go to the documentation of this file.

    00001 <?php
    00002 /***************************************************************************
    00003  *   Copyright (C) 2008 by Sergey S. Sergeev                               *
    00004  *                                                                         *
    00005  *   This program is free software; you can redistribute it and/or modify  *
    00006  *   it under the terms of the GNU Lesser General Public License as        *
    00007  *   published by the Free Software Foundation; either version 3 of the    *
    00008  *   License, or (at your option) any later version.                       *
    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                         // FIXME: bogus message
    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             // FIXME: rtrim, probably?
    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 ?>