Skip to content

Commit

Permalink
Fix resolving type hinting routes in FastRouteDispatcher, PhrouteDisp…
Browse files Browse the repository at this point in the history
…atcher
  • Loading branch information
rougin committed Dec 13, 2023
1 parent def9257 commit 39d39d3
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 37 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ All notable changes to `Slytherin` will be documented in this file.
- Backward compatibility for `LeagueContainer::set` (as of `~3.0`)
- Backward compatibility for `TwigRenderer::render` (as of `~3.0`)
- Backward compatibility for `StratigilityDispatcher::process` (until `~3.0`)
- Resolving type hinted routes for third-party routers
- Resolving type hinted routes for third-party routing dispatchers

### Removed
- `Integration\ConfigurationInterface` as its not being used
Expand Down
6 changes: 6 additions & 0 deletions src/Middleware/StratigilityDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,12 @@ public function process(ServerRequestInterface $request, HandlerInterface $handl
{
$item = $this->setMiddleware($item);

// @codeCoverageIgnoreStart
if (! $this->hasFactory() && $this->hasPsr())
{
$item = $this->setPsrMiddleware($item);
}
// @codeCoverageIgnoreEnd

$this->zend->pipe($item);
}
Expand All @@ -93,11 +95,13 @@ public function process(ServerRequestInterface $request, HandlerInterface $handl

$zend = $this->zend;

// @codeCoverageIgnoreStart
if ($this->hasPsr())
{
/** @phpstan-ignore-next-line */
return $zend->process($request, $next);
}
// @codeCoverageIgnoreEnd

/** @phpstan-ignore-next-line */
return $zend($request, $response, $next);
Expand Down Expand Up @@ -135,13 +139,15 @@ protected function setFactory(ResponseInterface $response)
*/
protected function setMiddleware(MiddlewareInterface $item)
{
// @codeCoverageIgnoreStart
if ($this->hasPsr())
{
return function ($request, $handler) use ($item)
{
return $item->process($request, new Interop($handler));
};
}
// @codeCoverageIgnoreEnd

return function ($request, $response, $next) use ($item)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Routing/FastRouteDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public function dispatch($method, $uri)
/** @var \Rougin\Slytherin\Routing\RouteInterface */
$route = $result[1];

/** @var string[] */
/** @var array<string, string> */
$params = $result[2];

return $route->setParams($params);
Expand Down
16 changes: 15 additions & 1 deletion src/Routing/FastRouteRouter.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,21 @@ public function parsed(array $routes = array())
{
foreach ($routes as $route)
{
$collector->addRoute($route->getMethod(), $route->getUri(), $route);
// Convert the ":name" pattern into "{name}" pattern ------------------
$uri = $route->getUri();

$matched = preg_match_all('/\:([a-zA-Z0-9\_\-]+)/i', $uri, $matches);

if ($matched)
{
foreach ($matches[0] as $key => $item)
{
$uri = str_replace($item, '{' . $matches[1][$key] . '}', $uri);
}
}
// --------------------------------------------------------------------

$collector->addRoute($route->getMethod(), $uri, $route);
}
};

Expand Down
22 changes: 21 additions & 1 deletion src/Routing/PhrouteDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,27 @@ public function dispatch($method, $uri)
try
{
/** @var \Rougin\Slytherin\Routing\RouteInterface */
return $phroute->dispatch($method, $uri);
$route = $phroute->dispatch($method, $uri);

// Combine values from resolver and the current parameters -------------
$regex = '/\{([a-zA-Z0-9\_\-]+)\}/i';

$matched = preg_match_all($regex, $route->getUri(), $matches);

// If "{name}" pattern is not found, try the ":name" pattern instead ---
if (! $matched)
{
$regex = '/\:([a-zA-Z0-9\_\-]+)/i';

$matched = preg_match_all($regex, $route->getUri(), $matches);
}
// ---------------------------------------------------------------------

/** @var array<string, string> */
$params = array_combine($matches[1], $route->getParams());

return $route->setParams($params);
// ---------------------------------------------------------------------
}
catch (HttpRouteNotFoundException $e)
{
Expand Down
16 changes: 15 additions & 1 deletion src/Routing/PhrouteRouter.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,21 @@ public function asParsed(array $routes)
{
foreach ($routes as $route)
{
$this->collector->addRoute($route->getMethod(), $route->getUri(), $route);
// Convert the ":name" pattern into "{name}" pattern ------------------
$uri = $route->getUri();

$matched = preg_match_all('/\:([a-zA-Z0-9\_\-]+)/i', $uri, $matches);

if ($matched)
{
foreach ($matches[0] as $key => $item)
{
$uri = str_replace($item, '{' . $matches[1][$key] . '}', $uri);
}
}
// --------------------------------------------------------------------

$this->collector->addRoute($route->getMethod(), $uri, $route);
}

return $this->collector->getData();
Expand Down
8 changes: 5 additions & 3 deletions src/Routing/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class Route implements RouteInterface
protected $middlewares;

/**
* @var string[]
* @var array<string, string>
*/
protected $params = array();

Expand Down Expand Up @@ -98,7 +98,7 @@ public function getMiddlewares()
/**
* Returns the defined parameters.
*
* @return string[]
* @return array<string, string>
*/
public function getParams()
{
Expand Down Expand Up @@ -143,7 +143,9 @@ public function getUri()
}

/**
* @param string[] $params
* Sets the parameters to the route.
*
* @param array<string, string> $params
* @return self
*/
public function setParams($params)
Expand Down
14 changes: 0 additions & 14 deletions src/System.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,6 @@ public function __construct($container = null, Configuration $config = null)
}
}

/**
* Finds an entry of the container by its identifier and returns it.
*
* @param string $id
* @return mixed
*
* @throws \Psr\Container\NotFoundExceptionInterface
* @throws \Psr\Container\ContainerExceptionInterface
*/
public function get($id)
{
return $this->container->get($id);
}

/**
* Handles the ServerRequestInterface to convert it to a ResponseInterface.
*
Expand Down
11 changes: 0 additions & 11 deletions tests/Application/ApplicationTestCases.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,17 +200,6 @@ public function testHandleMethodWithServerRequest()
*/
public function testHandleMethodWithTypehintedParameter()
{
$interface = 'Rougin\Slytherin\Routing\DispatcherInterface';

$dispatcher = $this->application->get($interface);

// TODO: Implement resolving of type hinted parameters from container to PhrouteResolver ----------
if (is_a($dispatcher, 'Rougin\Slytherin\Routing\PhrouteDispatcher'))
{
$this->markTestSkipped('Resolving type hinted parameters are not yet implemented in Phroute.');
}
// ------------------------------------------------------------------------------------------------

$request = $this->request('GET', '/typehint/202');

$expected = (integer) 202;
Expand Down
4 changes: 2 additions & 2 deletions tests/Routing/FastRouteDispatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@ public function testDispatchMethodWithClassAndPhrouteRouter()

$router->prefix('', 'Rougin\Slytherin\Fixture\Classes');

$router->get('/', 'NewClass@index');
$router->get('/hello/:name', 'NewClass@index');

$dispatcher = new FastRouteDispatcher($router);

$controller = new NewClass;

$route = $dispatcher->dispatch('GET', '/');
$route = $dispatcher->dispatch('GET', '/hello/Slytherin');

$expected = (string) $controller->index();

Expand Down
4 changes: 2 additions & 2 deletions tests/Sample/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function routes($parsed = false)

$this->get('/response', 'Hello@response');

$this->get('/hi/{name}', 'Hello@name');
$this->get('/hi/:name', 'Hello@name');

$this->get('without-slash', 'Hello@string');

Expand All @@ -49,7 +49,7 @@ public function routes($parsed = false)
return 'Welcome ' . $name . ', ' . $age . '!';
});

$this->get('/call/{name}', function ($name)
$this->get('/call/:name', function ($name)
{
return 'Welcome ' . $name . '!';
});
Expand Down

0 comments on commit 39d39d3

Please sign in to comment.