Advertisement
Tori

SimpleRoute (v.1.3)

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