Go to the documentation of this file.00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 final class RouterRegexpRule extends RouterBaseRule
00013 {
00014 protected $regexp = null;
00015 protected $reverse = null;
00016 protected $route = null;
00017
00018 protected $map = array();
00019 protected $values = array();
00020
00024 public static function create($route)
00025 {
00026 return new self($route);
00027 }
00028
00029 public function __construct($route)
00030 {
00031 $this->route = $route;
00032 $this->regexp = '#^' . $this->route . '$#i';
00033 }
00034
00038 public function setMap(array $map)
00039 {
00040 $this->map = $map;
00041
00042 return $this;
00043 }
00044
00045 public function getMap()
00046 {
00047 return $this->map;
00048 }
00049
00053 public function setReverse($reverse)
00054 {
00055 Assert::isString($reverse);
00056
00057 $this->reverse = $reverse;
00058
00059 return $this;
00060 }
00061
00062 public function getReverse()
00063 {
00064 return $this->reverse;
00065 }
00066
00067 public function match(HttpRequest $request)
00068 {
00069 $path = $this->processPath($request)->toString();
00070
00071
00072 $path = trim(urldecode($path), '/');
00073 $res = preg_match($this->regexp, $path, $values);
00074
00075 if ($res === 0)
00076 return array();
00077
00081 foreach ($values as $i => $value) {
00082 if (!is_int($i) || $i === 0) {
00083 unset($values[$i]);
00084 }
00085 }
00086
00087 $this->values = $values;
00088
00089 $values = $this->getMappedValues($values);
00090 $defaults = $this->getMappedValues($this->defaults, false, true);
00091
00092 $return = $values + $defaults;
00093
00094 return $return;
00095 }
00096
00097 public function assembly(
00098 array $data = array(),
00099 $reset = false,
00100 $encode = false
00101 )
00102 {
00103 if ($this->reverse === null)
00104 throw new RouterException(
00105 'Can not assembly. Reversed route is not specified.'
00106 );
00107
00108 $defaultValuesMapped = $this->getMappedValues($this->defaults, true, false);
00109 $matchedValuesMapped = $this->getMappedValues($this->values, true, false);
00110 $dataValuesMapped = $this->getMappedValues($data, true, false);
00111
00112 if (($resetKeys = array_search(null, $dataValuesMapped, true)) !== false) {
00113 foreach ((array) $resetKeys as $resetKey) {
00114 if (isset($matchedValuesMapped[$resetKey])) {
00115 unset($matchedValuesMapped[$resetKey]);
00116 unset($dataValuesMapped[$resetKey]);
00117 }
00118 }
00119 }
00120
00121 $mergedData = $defaultValuesMapped;
00122 $mergedData = $this->arrayMergeNumericKeys($mergedData, $matchedValuesMapped);
00123 $mergedData = $this->arrayMergeNumericKeys($mergedData, $dataValuesMapped);
00124
00125 ksort($mergedData);
00126
00127 try {
00128 $return = vsprintf($this->reverse, $mergedData);
00129 } catch (BaseException $e) {
00130 throw new RouterException(
00131 'Can not assembly. Too few arguments? Error was: '
00132 .$e->getMessage()
00133 );
00134 }
00135
00136 return $return;
00137 }
00138
00142 protected function arrayMergeNumericKeys(array $array1, array $array2)
00143 {
00144 $returnArray = $array1;
00145
00146 foreach ($array2 as $array2Index => $array2Value)
00147 $returnArray[$array2Index] = $array2Value;
00148
00149 return $returnArray;
00150 }
00151
00163 protected function getMappedValues($values, $reversed = false, $preserve = false)
00164 {
00165 if (!count($this->map))
00166 return $values;
00167
00168 $return = array();
00169
00170 foreach ($values as $key => $value) {
00171 if (is_int($key) && !$reversed) {
00172 if (array_key_exists($key, $this->map)) {
00173 $index = $this->map[$key];
00174 } elseif (($index = array_search($key, $this->map)) === false) {
00175 $index = $key;
00176 }
00177
00178 $return[$index] = $values[$key];
00179 } elseif ($reversed) {
00180 $index =
00181 (!is_int($key))
00182 ? array_search($key, $this->map, true)
00183 : $key;
00184
00185 if (false !== $index) {
00186 $return[$index] = $values[$key];
00187 }
00188 } elseif ($preserve) {
00189 $return[$key] = $value;
00190 }
00191 }
00192
00193 return $return;
00194 }
00195 }
00196 ?>