注册重定向路由
@access public
@param  string|array $rule 路由规则
@param  string $route 路由地址
@param  array $status 状态码
@param  array $option 路由参数
@param  array $pattern 变量规则
@return RuleItem
186014
public function redirect($rule, $route = '', $status = 301, array $option = [], array $pattern = [])
    {
        return $this->rule($rule, $route, '*', $option, $pattern)->redirect()->status($status);
    }
536364
public static function i18n($pattern, array $options = array())
		{

			// Trim the pattern
			$pattern = rtrim($pattern, '/ ');

			// Do the default options
			$options = array_merge(array(
				"controller" => "\\ChickenWire\\I18n\\I18nController"
			), $options);

			// Create basic route for all
			Route::match($pattern, array_merge(array(
				"action" => "all"
			), $options));

			// Get current language
			Route::match($pattern . '/current', array_merge(array(
				"action" => "current"
			), $options));

			// All sub requests
			Route::match($pattern . '/current/{*path}', array_merge(array(
				"action" => "current"
			), $options));

			// All sub requests with a language
			Route::match($pattern . '/{*path}', array_merge(array(
				"action" => "all"
			), $options));

		}
271569
private function call(string $method, string $pattern, string $className, string $function, array $options = []): void
    {
        if (empty($className) || empty($function)) {
            throw new Exception('Missing params, we need 2 parameters');
        }

        $route = [
            'method' => $method,
            'pattern' => $pattern,
            'className' => $className,
            'function' => $function,
        ];
        $this->collections[] = $route;

        if (array_key_exists('options', $options)) {
            $this->setOptions($route, $options);
        }

        return;
    }
429628
function rule_match_page_template( $match, $rule, $options )
	{
		$page_template = $options['page_template'];
		if( ! $page_template )
		{
			$page_template = get_post_meta( $options['post_id'], '_wp_page_template', true );
		}
		
		
		if( ! $page_template )
		{
			$post_type = $options['post_type'];

			if( !$post_type )
			{
				$post_type = get_post_type( $options['post_id'] );
			}
			
			if( $post_type == 'page' )
			{
				$page_template = "default";
			}
		}
		
		
		
        if($rule['operator'] == "==")
        {
        	$match = ( $page_template === $rule['value'] );
        }
        elseif($rule['operator'] == "!=")
        {
        	$match = ( $page_template !== $rule['value'] );
        }
                
        return $match;

	}
556846
public function match($route, $method = 'GET', $options = [])
    {
        $this->count = 0;

        foreach ($this->routes as $routeItem) {
            $this->count++;

            if (!$this->matchOptions($routeItem, $method, $options)) {
                continue;
            }

            if ($this->matchRoute($route, $routeItem)) {
                return $routeItem;
            }
        }

        return false;
    }
634044
public function rules($rules, $method = '*', array $option = [], array $pattern = [])
    {
        $this->group->addRules($rules, $method, $option, $pattern);
    }
726347
private function patternToPath($pattern, $params)
    {
        // Inspired by https://github.com/nikic/FastRoute/issues/66
        // but uses named params, don't care param order and size
        $routeParser = new RouteParserStd;
        $routes = $routeParser->parse($pattern);

        // check from the longest route to the shortest route
        // first (longest) full match is the route we need
        for ($i = count($routes) - 1; $i >= 0; $i--) {
            $url = '';
            foreach ($routes[$i] as $part) {
                // replace placeholder to actual value
                if (is_array($part)) {
                    $part = @$params[$part[0]];
                }

                // if route contains part not defined in $params, abandan this route
                if (null === $part) {
                    continue 2;
                }
                $url .= $part;
            }

            // first full match, this is our hero url
            return $url;
        }

        // no full match, throw Exception
        throw new \Exception(sprintf("Can't make path for '%s' with param: %s.", $pattern, json_encode($params)));
    }
1081011
public function options($pattern, $action)
    {
        self::$rules[self::REQUEST_METHOD_OPTIONS . self::patternFactory($pattern)] = $action;
        return $this;
    }
1155224
public function get(string $name, ?string $pattern = null, array $options = []): RouteData
    {
        return $this->any($name, $pattern, $options)->methods('GET');
    }
55322
public function delete($rule, $route = '', array $option = [], array $pattern = [])
    {
        return $this->rule($rule, $route, 'DELETE', $option, $pattern);
    }
890970
public function options(string $pattern, array $param) : void
    {
        $this->call('options', $pattern, $param[0], $param[1], $param);
    }
917974
public function post($pattern, $action)
    {
        self::$rules[self::REQUEST_METHOD_POST . self::patternFactory($pattern)] = $action;
        return $this;
    }
582404
function redirect($pattern,$url,$permanent=TRUE) {
		if (is_array($pattern)) {
			foreach ($pattern as $item)
				$this->redirect($item,$url,$permanent);
			return;
		}
		$this->route($pattern,function($fw) use($url,$permanent) {
			$fw->reroute($url,$permanent);
		});
	}
901083
public function isPatternMatches($pattern, $routePattern = false)
    {
        $uri = $this->removeIndexDotPhpAndTrillingSlash($this->getCurrentUri());
        $hasPattern = $this->hasNamedPattern($pattern);
        $pattern = ($hasPattern == false) ? $pattern : $hasPattern;
        if (preg_match_all(
            '#^' . $pattern . '$#',
            $uri,
            $matches,
            PREG_SET_ORDER
        )) {
            return $matches;
        }
    }
283148
private function processRule(Item $item, $ruleName, $options)
    {
        if ($item->stopRules()) {
            return;
        }

        $ruleName = '\NickStuer\EasyValidator\Rules\\' . $ruleName;

        if (!class_exists($ruleName)) {
            throw new RuleNotFoundException;
        }

        /**
         * @var \NickStuer\EasyValidator\RuleInterface $rule
         */
        $rule = new $ruleName;
        if (!$rule->validate($item->getItemValue(), $options)) {
            $this->setValidationStatus(false);
            $item->setValidationStatus(false);

            $message = $rule->getMessage();
            $message = str_replace('{label}', $item->getItemLabel(), $message);
            $message = str_replace('{option1}', $options, $message);
            $item->setMessage($message);
        }

        $item->incrementRuleCount();
    }
992293
public function domain($name, $rule = '', $option = [], $pattern = [])
    {
        // 支持多个域名使用相同路由规则
        $domainName = is_array($name) ? array_shift($name) : $name;

        if ('*' != $domainName && false === strpos($domainName, '.')) {
            $domainName .= '.' . $this->request->rootDomain();
        }

        if (!isset($this->domains[$domainName])) {
            $domain = (new Domain($this, $domainName, $rule, $option, $pattern))
                ->lazy($this->lazy)
                ->mergeRuleRegex($this->mergeRuleRegex);

            $this->domains[$domainName] = $domain;
        } else {
            $domain = $this->domains[$domainName];
            $domain->parseGroupRule($rule);
        }

        if (is_array($name) && !empty($name)) {
            $root = $this->request->rootDomain();
            foreach ($name as $item) {
                if (false === strpos($item, '.')) {
                    $item .= '.' . $root;
                }

                $this->domains[$item] = $domainName;
            }
        }

        // 返回域名对象
        return $domain;
    }
1260926
public function dispatch(int $status, string $path, string $method, $route)
    {
        // not found
        if ($status === RouterInterface::NOT_FOUND) {
            return $this->handleNotFound($path, $method);
        }

        // method not allowed
        if ($status === RouterInterface::METHOD_NOT_ALLOWED) {
            return $this->handleNotAllowed($path, $method, $route);
        }

        // trigger route found event
        $this->fire(self::ON_FOUND, [$path, $route]);

        $result = null;
        $options = $route->getOptions();

        // fire enter event
        // schema,domains ... metadata validate
        if (isset($options['enter']) && false === RouteHelper::call($options['enter'], [$options, $path])) {
            return $result;
        }

        $handler = $route->getHandler();
        $args = $route->getParams();

        try {
            // trigger route exec_start event
            $this->fire(self::ON_EXEC_START, [$path, $route]);

            $globChains = $this->getRouter()->getChains();
            $chains = $route->getChains();

            $result = $this->callHandler($path, $method, $handler, $args);

            // fire leave event
            if (isset($options['leave'])) {
                RouteHelper::call($options['leave'], [$options, $path]);
            }

            // trigger route exec_end event
            $this->fire(self::ON_EXEC_END, [$path, $route, $result]);
        } catch (\Throwable $e) {
            // trigger route exec_error event
            if ($cb = $this->getOption(self::ON_EXEC_ERROR)) {
                return RouteHelper::call($cb, [$e, $path, $route]);
            }

            throw $e;
        }

        return $result;
    }