/** * Tries to match a URL with a set of routes. * Will always return the first route that matches. * * @param string $pathinfo The path info to be parsed * @param RouteCollection $routes The set of routes * * @return array An array of parameters * * @throws ResourceNotFoundException If the resource could not be found * @throws MethodNotAllowedException method is not allowed */ protected function matchCollection($pathinfo, RouteCollection $routes) { /** * @var $route \Symfony\Component\Routing\Route */ foreach ($routes as $name => $route) { $compiledRoute = $route->compile(); // check the static prefix of the URL first. // Only use the more expensive preg_match when it matches if ('' !== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) { continue; } if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { continue; } $hostMatches = array(); if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) { continue; } // check HTTP method requirement if ($req = $route->getRequirement('_method')) { // HEAD and GET are equivalent as per RFC if ('HEAD' === ($method = $this->context->getMethod())) { $method = 'GET'; } if (!in_array($method, $req = explode('|', strtoupper($req)))) { $this->allow = array_merge($this->allow, $req); continue; } } // check device if (class_exists('\\Mobile_Detect') && $this->context->getDevice() instanceof \Mobile_Detect) { /** * @var $device \Mobile_Detect */ $device = $this->context->getDevice(); $deviceType = $device->isMobile() ? $device->isTablet() ? 'tablet' : 'mobile' : 'computer'; if ($route->getOption('device') && $route->getOption('device') != $deviceType) { continue; } /** * Test for a specific mobile OS */ if ($routeOS = $route->getOption('os')) { $deviceOS = $this->matchDeviceOS($routeOS, $device); if ($deviceOS) { Logger::info("Matched RouteOS: " . $deviceOS); } else { continue; } } /** * Test for a specific mobile/tablet type (brand) * eg iPhone, BlackBerry, HTC, Dell, etc */ if ($device->isMobile() && !$device->isTablet() && ($routeType = $route->getOption('type'))) { $phoneType = $this->matchPhoneType($routeType, $device); if ($phoneType) { Logger::info("Matched RouteType: " . $phoneType); } else { continue; } } elseif ($device->isTablet() && ($routeType = $route->getOption('type'))) { $tabletType = $this->matchTabletType($routeType, $device); if ($tabletType) { Logger::info("Matched RouteType: " . $tabletType); } else { continue; } } } $status = $this->handleRouteRequirements($pathinfo, $name, $route); if (self::ROUTE_MATCH === $status[0]) { return $status[1]; } if (self::REQUIREMENT_MISMATCH === $status[0]) { continue; } return $this->getAttributes($route, $name, array_replace($matches, $hostMatches)); } return false; }