Overview

Packages

  • PHP
  • Router

Classes

  • Route
  • Router
  • RouterForIncludes
  • SimpleRoute
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * Routa pro práci s URL složenými z parametrů
  5:  * 
  6:  * @author Jakub Kulhan (původní verze routeru), http://bukaj.netuje.cz/blog/jednoduchy-routing-v-php
  7:  * @author Viktorie Halasu, http://projekty.vize.name/router/
  8:  * @package Router
  9:  * @version 1.3
 10:  */
 11: 
 12: class SimpleRoute extends Route     {
 13:     
 14: 
 15:     /**
 16:      * @see Route::__construct()
 17:      * @param string $route
 18:      * @param array $defaults
 19:      * @param int $flags
 20:      * @param mixed $redir 
 21:      */
 22:     public function __construct($route, array $defaults = array(), $flags = 0, $redir = null)   {
 23:         $this->source = trim($route, '?& ');
 24:         if (is_int($flags)) {
 25:             $this->flags = $flags;
 26:         }
 27:         $this->params = array(
 28:             'order'     => array(), /* pořadí parametrů v routě (podle toho se složí výstupní URL): název => pořadí */
 29:             'fromRoute' => array(), /* jen parametry z routy s doplněnými výchozími hodnotami: název => [value => null|hodnota, optional => true|false] */
 30:             'allValues' => array(), /* parametry z routy i výchozí par. */
 31:         );
 32:         $this->regex = '';
 33:         
 34:         $orderIndex = 0;
 35:         foreach ($this->parse($this->source) as $i => $part) {
 36:             $optional = false;
 37:             if ($i % 2 === 0) {
 38:                 list($name, $partRegex) = explode("\037", $part);
 39:                 /* escapování oddělovače, zpětné lomítko je potřeba escapovat dvakrát */
 40:                 $partRegex = preg_replace('#(?<!\\\\)~#', '\\~', $partRegex);
 41:                 /* Je tato část routy nepovinná? */
 42:                 if ($name{0} === '?')   {
 43:                     $optional = true;
 44:                     $name = substr($name, 1);
 45:                 }
 46:                 
 47:                 /* Pokud není definovaný regulár pro tuto část routy, použije se výchozí */
 48:                 $this->regex .= ($optional ? '(?:' : '') . 
 49:                     (empty($this->regex) ? '~^\?' : '&') .
 50:                     preg_quote("$name=", '~'). '(?<' . $name . '>' . 
 51:                     (!empty($partRegex) ? $partRegex : self::DEFAULT_REGEX) .
 52:                     ')' . ($optional ? ')?' : '');
 53:                 
 54:                 /* Uloží se jednotlivé části routy a jejich vlastnosti. */
 55:                 $this->params['order'][$name] = $orderIndex;
 56:                 $this->params['fromRoute'][$name] = array(
 57:                     'value'     => null,
 58:                     'optional'  => $optional,
 59:                 );
 60:                 $this->params['allValues'][$name] = null;
 61:             }
 62:             $orderIndex++;
 63:         }
 64:         
 65:         /* PCRE modif.: Unicode vždy, case-insensitive volitelně */
 66:         $this->regex .= '$~u' . ($this->hasFlag(self::CI) ? 'i' : '');
 67:         
 68:         /* Přidají se výchozí hodnoty nebo parametry, pokud byly zadány. */
 69:         if (!empty($defaults))  {
 70:             foreach ($defaults as $key => $val) {
 71:                 if (!isset($this->params['fromRoute'][$key]))   {
 72:                     $this->params['fromRoute'][$key]['value'] = $val;
 73:                     $this->params['fromRoute'][$key]['optional'] = false;
 74:                 }
 75:                 $this->params['allValues'][$key] = $val;
 76:             }
 77:         }
 78:         
 79:         if ($this->hasFlag(self::REDIR))    {
 80:             $this->resolveRedirection($redir);
 81:         }
 82:     }
 83:     
 84:     
 85:     /**
 86:      * Pokusí se zpracovat zadaný query string podle této routy. Pořadí parametrů ve vstupu je libovolné.
 87:      * @param mixed $url Pole ($_GET) nebo řetězec ($_SERVER['QUERY_STRING'])
 88:      * @return bool
 89:      */
 90:     public function matchUrl($url)  {
 91:         if (!is_array($url))    {
 92:             $queryString = trim($url, '?&');
 93:             parse_str($queryString, $url);
 94:         }
 95:         if ($this->createUrlFromParams(array_intersect_key($url, $this->params['allValues']))) {
 96:             $this->parsedUrl = $this->kmerge($this->params['allValues'], $this->lastUrlParams);
 97:             $this->lastUrlParams = array();
 98:             $this->lastCreatedUrl = '';
 99:             return true;
100:         }
101:         $this->parsedUrl = array();
102:         return false;
103:     }
104:     
105:     
106:     /**
107:      * @see Route::createUrlFromParams()
108:      * @param array $params 
109:      * @return bool
110:      */
111:     public function createUrlFromParams(array $params)  {
112: 
113:         /* Názvy a hodnoty parametrů výstupní URL */
114:         $names = array();
115:         $values = array();
116:         
117:         foreach ($this->params['fromRoute'] as $parName => $parProps)   {
118:             
119:             /* Pokud je v routě víc povinných částí, než bylo zadáno parametrů, máme špatnou routu. */
120:             if (empty($params) && !$parProps['optional'])   {
121:                 return false;
122:             }
123: 
124:             if (isset($params[$parName]))   {
125:                 /* Výchozí parametry musí mít stejnou hodnotu. */
126:                 if ($parProps['value'] !== null && $params[$parName] != $parProps['value']) {
127:                     return false;
128:                 }                   
129:                 /* Pokud parametr patří do routy (= není výchozí), použije se. */
130:                 if (isset($this->params['order'][$parName]))    {
131:                     $names[$this->params['order'][$parName]] = $parName;
132:                     $values[$this->params['order'][$parName]] = $params[$parName];
133:                 }
134:                 unset($params[$parName]);
135:             }
136:             /* Parametr nebyl zadaný, ale je nepovinný - nedělá se nic */
137:             elseif ($parProps['optional'] === false)    {
138:                 /* continue; */
139:             } 
140:         }
141: 
142: 
143:         /* Pokud zbyly parametry, které nejsou v routě, máme špatnou routu. */
144:         if (!empty($params))    {
145:             $this->lastUrlParams = array();
146:             $this->lastCreatedUrl = '';
147:             return false;
148:         }
149:         
150:         /* Názvy i hodnoty se seřadí, aby na výstupu byly ve stejném pořadí jako v routě. */
151:         ksort($names);
152:         ksort($values);
153:         $this->lastUrlParams = array_combine($names, $values);
154:         $this->lastCreatedUrl = '?'.urldecode(http_build_query($this->lastUrlParams, '', '&'));
155:         
156:         if (preg_match($this->regex, $this->lastCreatedUrl))    {
157:             return true;
158:         } else {
159:             $this->lastUrlParams = array();
160:             $this->lastCreatedUrl = '';
161:             return false;
162:         }
163:     }
164:     
165:     
166:     /**
167:      * @see Route::addVariableUrlParts()
168:      * @param array $variables 
169:      * 
170:      * @throws LogicException 
171:      */
172:     public function addVariableUrlParts(array $variables)   {
173:         if (empty($this->lastUrlParams))    {
174:             throw new LogicException("Nelze nastavit proměnné parametry routy. Nejdřív se musí vytvořit URL podle routy.");
175:         }
176:         foreach ($variables as $name => $value) {
177:             if (isset($this->lastUrlParams[$name])) {
178:                 $this->lastUrlParams[$name] = $value;
179:             }
180:         }
181:         $this->lastCreatedUrl = '?'.urldecode(http_build_query($this->lastUrlParams, '', '&'));
182:     }
183:     
184: }
185: 
PHP Router ver.1.3, r02 API documentation generated by ApiGen 2.6.1