Find a matching route according to the request

@param boolean $alternative
@return Route
491316
public function findFirstMatchingRoute($alternative=false) {
		/* @var ControllerRoute $route */
		foreach( $this->getRoutes() as $route ) {
			/* @var $route HTTPRoute */
			if( $route->isMatchingRequest($this, $alternative) ) {
				return $route;
			}
		}
		return null;
	}
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;
    }
220192
public function getRoute(): RouteInterface
    {
        // Find route by regexp and URI
        $matches = $this->getMatches();

        // Cleanup the array of matches, then reindex array
        $matches = array_values(array_filter($matches));

        // If we have some classes in result of regexp
        $result = !empty($matches)
            // Take first from matches
            ? $matches[0] // Here the Route() object
            // Create new object with error inside
            : $this->getError();

        return $result;
    }
670542
public function get($key, $alternative=null, $lang=null){

        if (!$lang) {
            $lang = $this->locale;
        }

        if (!$alternative){
            $alternative = $key;
        }

        return isset($this->_languages[$lang][$key]) ? $this->_languages[$lang][$key]:$alternative;
    }
491459
public function getPath($absolute = false)
	{
		if(!$absolute)
		    return $this->properties['path'];

		$routes = $this->getFullRoutes();

		$paths = array();

		foreach($routes as $route)
		{
			$path = $route->getProperty('path');

			if($path == '')
				continue;

			$paths[] = $path;
		}

		return trim(implode('/', $paths), '/');
	}
561906
protected function findRouteRecursively($routeName)
    {
        // alias check
        if(is_string($routeName)) {
            if(isset($this->aliasIndices[$routeName])) {
                $routeName = $this->aliasIndices[$routeName];
            } else {
                foreach($this->groupAliasIndices as $alias => $name) {
                    if(strpos($routeName, $alias) === 0) {
                        $routeName = substr_replace($routeName, $name, 0, strlen($alias));
                        break;
                    }
                }
            }
        }

        $routeNames = !is_array($routeName) ? explode('.', $routeName) : $routeName;
        $routeName = array_shift($routeNames);
        $isTag = strpos($routeName, '#') === 0;

        // search by route name
        if(!$isTag)
        {
            // loop this group, and find the route.
            foreach($this->storage as $route)
            {
                if($route->getName() === $routeName)
                {
                    // still has depth
                    if(count($routeNames) > 0)
                        if($route->hasSubroutes())
                            return $route->getSubroutes()->findRouteRecursively($routeNames);
                        else
                            return false;

                    return $route;
                }
            }
        }
        // search by route tag under this group.
        else
        {
            $route = $this->findRouteByTag(substr($routeName, 1));

            if($route)
            {
                if(count($routeNames) > 0)
                    if($route->hasSubroutes())
                        return $route->getSubroutes()->findRouteRecursively($routeNames);
                    else
                        return false;

                return $route;
            }
        }

        return false;
    }
520023
public function match(Request $request, $route = false)
    {
        if (count($this->_childs)) {
            $route = $this->_match($request, $route);
        }

        if (!$route) {
            $route = $this->_default($request)->merge($route);
        }


        if (!$route) {
            throw new RuntimeException("Missing route...");
        }

        return $route;
    }
400057
public function getRoute() {
        if ($this->route === null && $this->isIgnoredRoute() === false) {
            $this->route = $this->routes->matchRoute($this);
        }

        return $this->route;
    }
543860
protected function doMatch($actual)
    {
        if ($actual instanceof Traversable) {
            return $this->matchTraversable($actual);
        }

        if (is_array($actual)) {
            return array_search($this->expected, $actual, true) !== false;
        }

        if (is_string($actual)) {
            return strpos($actual, $this->expected) !== false;
        }

        throw new InvalidArgumentException('Inclusion matcher requires a string or array');
    }
277861
public function isMatchingRequest(InputRequest $request, &$values=array(), $alternative=false) {
		// CLI does not use alternative
		return $request->getPath() === $this->getPath();
	}
399480
protected function findRoute($request)
    {
        $this->current = $route = $this->routes->match($request);

        $this->container->instance(Route::class, $route);

        return $route;
    }
944206
public static function route() {
		if(defined('DACHI_CLI'))
			return false;

		$uri = Request::getFullUri();
		$route = self::findRoute($uri);
		self::performRoute($route);

		return Template::render();
	}
1172936
public function getRequestCurrent($optional = false)
    {
        $requestStack = $this->getRequestStack($optional);

        if (null === $requestStack) {
            return null;
        }

        return $this->getRequestStack($optional)->getCurrentRequest();
    }
510864
public function getUriRouteFor(string $method): ?Route
    {
        if (!$this->isMethodAllowed($method)) {
            return null;
        }

        return $this->uriRoutes[$method];
    }
349847
public function get($match = [], $except = [])
    {
        return $this->routes->filterMatch($match)
            ->filterExcept($except)
            ->values();
    }
38208
protected function compareRoute($route, RequestAbstract $request)
    {
        // Replace the normal route delimiter with the request route delimiter
        $route = str_replace('|', $request->getRouteDelimiter(), $route);
        
        // Split the two routes into parts
        $routeParts = explode($request->getRouteDelimiter(), $route);
        $targetRouteParts = explode($request->getRouteDelimiter(), trim($request->getRoute(), $request->getRouteDelimiter()));
        $numberOfTargetRouteParts = count($targetRouteParts);
        
        // If we have different number of parts between the two routes
        // there are not equal so we have no equal route.
        if (count($routeParts) != $numberOfTargetRouteParts) {
            return false;
        }
        
        // Define the data types
        $routeParams = array();
        $routeIndex = 0;
        
        // Loop through the route parts and compare each part
        for ($pos = 0; $pos < $numberOfTargetRouteParts; $pos++) {
            $part = $routeParts[$pos];
            $targetPart = $targetRouteParts[$pos];

            if ($targetPart != '' && preg_match('/\[(d|s)(?:\:([0-9a-zA-Z]*))?\]/', $part)) {
                list($key, $value) = $this->parseRouteParam($part, $targetPart);
                
                $routeParams[$routeIndex] = $value;
                $routeIndex++;
                
                if ($key !== '') {
                    $routeParams[$key] = $value;
                }
            } else if ($part !== $targetPart) {
                // The part isn't equal == the route can't be equal
                return false;
            }
        }

        // Save the route parameters in the request
        $request->setRouteParams($routeParams);
        
        return true;
    }
1043117
public function match(MainRouter $router, $route = null)
    {
        $route = $route ?: $this->app->uri->route;
        $route = $route ?: '/';

        $input   = $this->app->input;
        $request = $this->app->request;

        if ($request->hasHeader('X-HTTP-Method-Override')) {
            $method = $request->getHeaderLine('X-HTTP-Method-Override');
        } else {
            $method = $input->get('_method') ?: $input->getMethod();
        }

        // Pass variables to custom method
        if ($input->$method) {
            $httpMethod = $input->getMethod();

            $input->$method->setData($input->$httpMethod->toArray());
        }

        // Prepare option data
        $uri = $request->getUri();

        $options = [
            'scheme' => $uri->getScheme(),
            'host' => $uri->getHost(),
            'port' => $uri->getPort(),
        ];

        try {
            return $router->match($route, $method, $options);
        } catch (RouteNotFoundException $e) {
            // If simple_route is disabled, just continue throw the exception.
            if (!$this->app->get('routing.simple_route', false)) {
                throw $e;
            }

            // Simple routing
            $matched = $this->matchSimpleRouting($route, $method, $router);

            if ($matched === false) {
                throw new RouteNotFoundException($e->getMessage(), $e->getCode(), $e);
            }

            return $matched;
        }
    }