Ejemplo n.º 1
0
 /**
  * Matches a request against a route collection.
  *
  * @param  RouteCollectionInterface $routeCollection
  * @param  ServerRequestInterface   $request
  * @param  int                      $pathOffset
  * @param  array                    $parentParams
  * @return MatchResult|null
  * @throws UnexpectedValueException
  */
 public static function matchRouteCollection(RouteCollectionInterface $routeCollection, ServerRequestInterface $request, $pathOffset, array $parentParams)
 {
     $methodFailureResult = null;
     $schemeFailureResult = null;
     foreach ($routeCollection as $name => $route) {
         if (null === ($matchResult = $route->match($request, $pathOffset))) {
             continue;
         }
         if ($matchResult->isSuccess()) {
             return MatchResult::fromChildMatch($matchResult, $parentParams, $name);
         }
         if ($matchResult->isMethodFailure()) {
             if (null === $methodFailureResult) {
                 $methodFailureResult = $matchResult;
             } else {
                 $methodFailureResult = MatchResult::mergeMethodFailures($methodFailureResult, $matchResult);
             }
             continue;
         }
         if ($matchResult->isSchemeFailure()) {
             $schemeFailureResult = $schemeFailureResult ?: $matchResult;
             continue;
         }
         return $matchResult;
     }
     if (null !== $schemeFailureResult) {
         return $schemeFailureResult;
     }
     if (null !== $methodFailureResult) {
         return $methodFailureResult;
     }
     return null;
 }
Ejemplo n.º 2
0
 public function testMethodNotAllowedResultsAreMerged()
 {
     $firstMatchResult = MatchResult::fromMethodFailure(['GET']);
     $secondMatchResult = MatchResult::fromMethodFailure(['POST']);
     $matchResult = RouteCollectionMatcher::matchRouteCollection($this->buildRouteCollection([$firstMatchResult, $secondMatchResult]), $this->prophesize(ServerRequestInterface::class)->reveal(), 0, []);
     $this->assertInstanceOf(MatchResult::class, $matchResult);
     $this->assertTrue($matchResult->isMethodFailure());
     $this->assertEquals(['GET', 'POST'], $matchResult->getAllowedMethods());
 }
Ejemplo n.º 3
0
 public function testMergeMethodFailuresWithIncompatibleMatchResults()
 {
     $this->setExpectedException(DomainException::class, 'Both match results must be method failures');
     MatchResult::mergeMethodFailures(MatchResult::fromMatchFailure(), MatchResult::fromMatchFailure());
 }
Ejemplo n.º 4
0
 /**
  * Merges two method failure match results.
  *
  * @param  self $firstMatchResult
  * @param  self $secondMatchResult
  * @return self
  * @throws DomainException
  */
 public static function mergeMethodFailures(self $firstMatchResult, self $secondMatchResult)
 {
     if (!$firstMatchResult->isMethodFailure() || !$secondMatchResult->isMethodFailure()) {
         throw new DomainException('Both match results must be method failures');
     }
     return self::fromMethodFailure(array_unique(array_merge($firstMatchResult->getAllowedMethods(), $secondMatchResult->getAllowedMethods())));
 }
Ejemplo n.º 5
0
 public function testIncompletePathMatchWithChildMatch()
 {
     $matchResult = $this->buildRoute(['path_parser' => $this->getIncompletePathParser(), 'children' => $this->buildChildren([MatchResult::fromSuccess(['baz' => 'bat'])])])->match($this->buildRequest(), 4);
     $this->assertInstanceOf(MatchResult::class, $matchResult);
     $this->assertTrue($matchResult->isSuccess());
     $this->assertEquals(['foo' => 'bar', 'baz' => 'bat'], $matchResult->getParams());
 }
Ejemplo n.º 6
0
 /**
  * {@inheritdoc}
  *
  * @throws UnexpectedValueException
  */
 public function match(ServerRequestInterface $request)
 {
     $basePathLength = strlen($this->baseUri['path']);
     return RouteCollectionMatcher::matchRouteCollection($this->routeCollection, $request, $basePathLength, []) ?: MatchResult::fromMatchFailure();
 }
Ejemplo n.º 7
0
 /**
  * {@inheritdoc}
  *
  * @throws Exception\UnexpectedValueException
  */
 public function match(ServerRequestInterface $request, $pathOffset)
 {
     $uri = $request->getUri();
     $params = $this->defaults;
     // Verify scheme first, if set.
     if (true === $this->secure && 'https' !== $uri->getScheme()) {
         return MatchResult::fromSchemeFailure($uri->withScheme('https'));
     } elseif (false === $this->secure && 'http' !== $uri->getScheme()) {
         return MatchResult::fromSchemeFailure($uri->withScheme('http'));
     }
     // Then match hostname, if parser is set.
     if (null !== $this->hostnameParser) {
         $hostnameResult = $this->hostnameParser->parse($uri->getHost(), 0);
         if (null === $hostnameResult || strlen($uri->getHost()) !== $hostnameResult->getMatchLength()) {
             return null;
         }
         $params = $hostnameResult->getParams() + $params;
     }
     // Then match port, if set.
     if (null !== $this->port) {
         $port = $uri->getPort() ?: ('http' === $uri->getScheme() ? 80 : 443);
         if ($port !== $this->port) {
             return null;
         }
     }
     // Next match the path.
     $completePathMatched = false;
     if (null !== $this->pathParser) {
         if (null === ($pathResult = $this->pathParser->parse($uri->getPath(), $pathOffset))) {
             return null;
         }
         $pathOffset += $pathResult->getMatchLength();
         $completePathMatched = $pathOffset === strlen($uri->getPath());
         $params = $pathResult->getParams() + $params;
     }
     if ($completePathMatched) {
         if (null === $this->methods || in_array($request->getMethod(), $this->methods)) {
             return MatchResult::fromSuccess($params);
         }
         if (empty($this->methods)) {
             // Special case: when no methods are defined at all, this route may simply not terminate.
             return null;
         }
         return MatchResult::fromMethodFailure($this->methods);
     }
     // The path was not completely matched yet, so we check the children.
     if (null === $this->children) {
         return null;
     }
     return RouteCollectionMatcher::matchRouteCollection($this->children, $request, $pathOffset, $params);
 }