/** * 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; }
/** * 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); }
/** * buildTree * * @param bool $refresh * * @return static */ protected function buildTree($refresh = false) { if ($this->tree && $this->debug && $refresh) { return $this; } // Build Tree foreach ($this->routes as $routeItem) { $pattern = $routeItem->getPattern(); // Compile this route $regex = TrieCompiler::compile($pattern, $routeItem->getRequirements()); $regex = trim($regex, chr(1) . '^$'); // Make sure no other '/' is the path separator $regex = str_replace('[^/]', '{:PLACEHOLDER:}', $regex); // Split it $regex = explode('/', $regex); // Start build tree $node =& $this->tree; $length = count($regex); foreach ((array) $regex as $k => $segment) { // Fallback the placeholder to / $segment = str_replace('{:PLACEHOLDER:}', '[^/]', $segment); $segment = $segment ?: '/'; if (!isset($node[$segment])) { $node[$segment] = array(); } // If is last segment, set it as Route name, // that we can search it later or cache this map. if ($k + 1 == $length) { $node[$segment] = $routeItem->getName(); } $node =& $node[$segment]; } } return $this; }