Exemplo n.º 1
0
 /**
  * compile
  *
  * @param string $pattern
  * @param array  $requirements
  *
  * @return  string
  */
 public static function compile($pattern, $requirements = array())
 {
     $pattern = RouteHelper::sanitize($pattern);
     $regex = static::replaceOptionalSegments($pattern);
     $regex = static::replaceWildcards($regex);
     return chr(1) . '^' . static::replaceAllRegex($regex, $requirements) . '$' . chr(1);
 }
Exemplo n.º 2
0
 /**
  * generate
  *
  * @param string $pattern
  * @param array  $queries
  *
  * @return  mixed|string
  */
 public static function generate($pattern, array $queries = array())
 {
     $replace = array();
     $pattern = RouteHelper::sanitize($pattern);
     if (!isset(static::$vars[$pattern])) {
         TrieCompiler::compile($pattern);
         static::$vars[$pattern] = (array) TrieCompiler::$vars;
     }
     foreach (static::$vars[$pattern] as $key) {
         $var = isset($queries[$key]) ? $queries[$key] : 'null';
         if (is_array($var) || is_object($var)) {
             $var = implode('/', (array) $var);
             $key2 = '*' . $key;
             $replace[$key2] = $var;
         } else {
             $key2 = ':' . $key;
             $replace[$key2] = $var;
         }
         if (strpos($pattern, $key2) !== false) {
             unset($queries[$key]);
         }
     }
     $pattern = strtr($pattern, $replace);
     $queries = http_build_query($queries);
     if ($queries) {
         $pattern = rtrim($pattern, '/') . '/?' . $queries;
     }
     return $pattern;
 }
 /**
  * testGetVariables
  *
  * @return  void
  *
  * @covers Windwalker\Router\RouteHelper::getVariables
  */
 public function testGetVariables()
 {
     $array = array(0 => 5, 'id' => 5, 1 => 'foo', 'bar' => 'foo');
     $this->assertEquals(array('id' => 5, 'bar' => 'foo'), RouteHelper::getVariables($array));
     $vars = array('flower' => 'sakura');
     $this->assertEquals(array('flower' => 'sakura', 'id' => 5, 'bar' => 'foo'), RouteHelper::getVariables($array, $vars));
 }
Exemplo n.º 4
0
 /**
  * Method to test compile().
  *
  * @param string $pattern
  * @param string $expected
  * @param int    $line
  *
  * @return void
  *
  * @covers Windwalker\Router\Compiler\BasicCompiler::compile
  *
  * @dataProvider  regexList
  */
 public function testCompile($pattern, $expected, $route, $expectedMatches, $line)
 {
     $regex = TrieCompiler::compile($pattern, array('id' => '\\d+'));
     $this->assertEquals(chr(1) . '^' . $expected . '$' . chr(1), $regex, 'Fail at: ' . $line);
     preg_match($regex, $route, $matches);
     $vars = RouteHelper::getVariables($matches);
     $this->assertNotEmpty($matches);
     $this->assertEquals($expectedMatches, $vars);
 }
Exemplo n.º 5
0
 /**
  * Match routes.
  *
  * @param string $route
  * @param Route  $routeItem
  *
  * @return  Route|false
  */
 public function matchRoute($route, Route $routeItem)
 {
     $regex = $routeItem->getRegex();
     if (!$regex || $this->debug) {
         $regex = BasicCompiler::compile($routeItem->getPattern(), $routeItem->getRequirements());
         $routeItem->setRegex($regex);
     }
     $route = RouteHelper::normalise($route);
     if (preg_match($regex, $route, $matches)) {
         $variables = RouteHelper::getVariables($matches);
         $variables['_rawRoute'] = $route;
     } else {
         return false;
     }
     $routeItem->setVariables(array_merge($routeItem->getVariables(), $variables));
     return $routeItem;
 }
Exemplo n.º 6
0
 /**
  * compile
  *
  * @param string $pattern
  * @param array  $requirements
  *
  * @return  string
  */
 public static function compile($pattern, $requirements = array())
 {
     // Sanitize and explode the pattern.
     $pattern = RouteHelper::sanitize($pattern);
     $vars = array();
     $regex = array();
     // Loop on each segment
     foreach (explode('/', $pattern) as $segment) {
         if ($segment == '') {
             // Match root route.
             $regex[] = '';
         } elseif ($segment == '*') {
             // Match a splat with no variable.
             $regex[] = '.*';
         } elseif ($segment[0] == '*') {
             // Match a splat and capture the data to a named variable.
             $vars[] = $segment = substr($segment, 1);
             $regex[] = '(?P<' . $segment . '>.*)';
         } elseif ($segment[0] == '\\' && $segment[1] == '*') {
             // Match an escaped splat segment.
             $regex[] = '\\*' . preg_quote(substr($segment, 2));
         } elseif ($segment == ':') {
             // Match an unnamed variable without capture.
             $regex[] = '[^/]*';
         } elseif ($segment[0] == ':') {
             // Match a named variable and capture the data.
             $vars[] = $segment = substr($segment, 1);
             $regex[] = static::requirementPattern($segment, $requirements);
         } elseif ($segment[0] == '\\' && $segment[1] == ':') {
             // Match a segment with an escaped variable character prefix.
             $regex[] = preg_quote(substr($segment, 1));
         } else {
             // Match the standard segment.
             $regex[] = preg_quote($segment);
         }
     }
     static::$vars = $vars;
     return chr(1) . '^' . implode('/', $regex) . '$' . chr(1);
 }
Exemplo n.º 7
0
 /**
  * Match routes.
  *
  * @param string $route
  * @param string $method
  * @param array  $options
  *
  * @return  Route|false
  */
 public function match($route, $method = 'GET', $options = array())
 {
     $route = RouteHelper::normalise($route);
     $this->count = 0;
     $this->buildRouteMaps();
     $keys = array_keys($this->routeMaps);
     $left = 0;
     $right = count($this->routeMaps) - 1;
     while ($left <= $right) {
         $middle = round(($left + $right) / 2);
         $key = $keys[$middle];
         $routeItem = $this->routes[$this->routeMaps[$key]];
         $this->count++;
         if ($this->matchOptions($routeItem, $method, $options) && $this->matchRoute($route, $routeItem)) {
             return $routeItem;
         }
         if (strcmp($route, $key) < 0) {
             $right = $middle - 1;
         } else {
             $left = $middle + 1;
         }
     }
     return false;
 }
Exemplo n.º 8
0
 /**
  * buildRoute
  *
  * @param string $name
  * @param array  $queries
  * @param bool   $rootSlash
  *
  * @return string
  */
 public function build($name, $queries = array(), $rootSlash = false)
 {
     if (!array_key_exists($name, $this->routes)) {
         throw new \OutOfRangeException('Route: ' . $name . ' not found.');
     }
     $route = $this->matcher->build($this->routes[$name], (array) $queries);
     if ($rootSlash) {
         return RouteHelper::normalise($route);
     }
     return ltrim($route, '/');
 }
Exemplo n.º 9
0
 /**
  * setPattern
  *
  * @param   string $pattern
  *
  * @return  Route  Return self to support chaining.
  */
 public function setPattern($pattern)
 {
     $this->pattern = RouteHelper::normalise($pattern);
     return $this;
 }
Exemplo n.º 10
0
 /**
  * matchSegment
  *
  * @param array $segments
  * @param array $node
  * @param int   $level
  *
  * @return  bool|Route
  */
 protected function matchSegment($segments, $node, $level = 1)
 {
     $segment = isset($segments[$level - 1]) ? $segments[$level - 1] : false;
     if ($segment === false) {
         return false;
     }
     $segment = $segment ?: '/';
     foreach ($node as $regex => $child) {
         $this->count++;
         // Start with a '(' is a regex
         if ($regex[0] == '(') {
             preg_match(chr(1) . $regex . chr(1), $segment, $match);
             if (!$match) {
                 continue;
             }
             RouteHelper::getVariables($match, $this->vars);
         } else {
             if ($regex != $segment) {
                 continue;
             }
         }
         $result = false;
         // Has child, iterate it.
         if ($child && is_array($child)) {
             $child = $this->matchSegment($segments, $child, $level + 1);
         }
         // If is string, means we get a route index, using this index to find Route from maps.
         if (is_string($child)) {
             $child = $this->routes[$this->routeMaps[$child]];
         }
         // Match this Route
         if ($child instanceof Route) {
             $result = $this->matchOptions($child, $this->method, $this->options);
         }
         // If match fail, continue find next element.
         if (!$result) {
             continue;
         }
         return $child;
     }
     return false;
 }