Skip to content

Commit

Permalink
Merge pull request #2641 from l0gicgate/4.x-RouteCollectorProxy
Browse files Browse the repository at this point in the history
4.x - RouteCollectorProxy
  • Loading branch information
l0gicgate authored Apr 21, 2019
2 parents e65a4dc + a5f09ac commit 7377499
Show file tree
Hide file tree
Showing 11 changed files with 803 additions and 426 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
## 4.0.0 - 2019-07-03

### Added
- [#2641](https://github.com/slimphp/Slim/pull/2641) Add `RouteCollectorProxyInterface` which extracts all the route mapping functionality from app into its own interface.
- [#2640](https://github.com/slimphp/Slim/pull/2640) Add `RouteParserInterface` and decouple FastRoute route parser entirely from core. The methods `relativePathFor()`, `urlFor()` and `fullUrlFor()` are now located on this interface.
- [#2639](https://github.com/slimphp/Slim/pull/2639) Add `DispatcherInterface` and decouple FastRoute dispatcher entirely from core. This enables us to swap out our router implementation for any other router.
- [#2638](https://github.com/slimphp/Slim/pull/2638) Add `RouteCollector::fullUrlFor()` to give the ability to generate fully qualified URLs
Expand All @@ -24,6 +25,7 @@

### Deprecated

- [#2641](https://github.com/slimphp/Slim/pull/2641) Deprecate `RouteCollector::pushGroup()`,`RouteCollector::popGroup()` which gets replaced by `RouteCollector::group()`
- [#2638](https://github.com/slimphp/Slim/pull/2638) Deprecate `RouteCollector::pathFor()` which gets replaced by `RouteCollector::urlFor()` preserving the orignal functionality
- [#2555](https://github.com/slimphp/Slim/pull/2555) Double-Pass Middleware Support has been deprecated

Expand Down
266 changes: 21 additions & 245 deletions Slim/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,16 @@

namespace Slim;

use Closure;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UriInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Slim\Interfaces\CallableResolverInterface;
use Slim\Interfaces\RouteCollectorInterface;
use Slim\Interfaces\RouteGroupInterface;
use Slim\Interfaces\RouteInterface;
use Slim\Interfaces\RouteResolverInterface;
use Slim\Routing\RouteCollector;
use Slim\Routing\RouteCollectorProxy;
use Slim\Routing\RouteResolver;
use Slim\Routing\RouteRunner;

Expand All @@ -33,7 +29,7 @@
* configure, and run a Slim Framework application.
* The \Slim\App class also accepts Slim Framework middleware.
*/
class App implements RequestHandlerInterface
class App extends RouteCollectorProxy implements RequestHandlerInterface
{
/**
* Current version
Expand All @@ -42,50 +38,24 @@ class App implements RequestHandlerInterface
*/
public const VERSION = '4.0.0-dev';

/**
* Container
*
* @var ContainerInterface|null
*/
private $container;

/**
* @var CallableResolverInterface
*/
protected $callableResolver;

/**
* @var MiddlewareDispatcher
*/
protected $middlewareDispatcher;

/**
* @var RouteCollectorInterface
*/
protected $routeCollector;

/**
* @var RouteResolverInterface
*/
protected $routeResolver;

/**
* @var ResponseFactoryInterface
*/
protected $responseFactory;

/********************************************************************************
* Constructor
*******************************************************************************/

/**
* Create new application
*
* @param ResponseFactoryInterface $responseFactory
* @param ContainerInterface|null $container
* @param CallableResolverInterface $callableResolver
* @param RouteCollectorInterface $routeCollector
* @param RouteResolverInterface $routeResolver
* @param ResponseFactoryInterface $responseFactory
* @param ContainerInterface|null $container
* @param CallableResolverInterface|null $callableResolver
* @param RouteCollectorInterface|null $routeCollector
* @param RouteResolverInterface|null $routeResolver
*/
public function __construct(
ResponseFactoryInterface $responseFactory,
Expand All @@ -94,20 +64,27 @@ public function __construct(
RouteCollectorInterface $routeCollector = null,
RouteResolverInterface $routeResolver = null
) {
$this->responseFactory = $responseFactory;
$this->container = $container;
$this->callableResolver = $callableResolver ?? new CallableResolver($container);
$this->routeCollector = $routeCollector ?? new RouteCollector(
parent::__construct(
$responseFactory,
$this->callableResolver,
$container
$callableResolver ?? new CallableResolver($container),
$container,
$routeCollector
);
$this->routeResolver = $routeResolver ?? new RouteResolver($this->routeCollector);

$this->routeResolver = $routeResolver ?? new RouteResolver($this->routeCollector);
$routeRunner = new RouteRunner($this->routeResolver);

$this->middlewareDispatcher = new MiddlewareDispatcher($routeRunner, $container);
}

/**
* @return RouteResolverInterface
*/
public function getRouteResolver(): RouteResolverInterface
{
return $this->routeResolver;
}

/**
* @param MiddlewareInterface|string|callable $middleware
* @return self
Expand All @@ -128,207 +105,6 @@ public function addMiddleware(MiddlewareInterface $middleware): self
return $this;
}

/********************************************************************************
* Getter methods
*******************************************************************************/

/**
* Get container
*
* @return ContainerInterface|null
*/
public function getContainer(): ?ContainerInterface
{
return $this->container;
}

/**
* Get callable resolver
*
* @return CallableResolverInterface
*/
public function getCallableResolver(): CallableResolverInterface
{
return $this->callableResolver;
}

/**
* Get route collector
*
* @return RouteCollectorInterface
*/
public function getRouteCollector(): RouteCollectorInterface
{
return $this->routeCollector;
}

/**
* Get route resolver
*
* @return RouteResolverInterface
*/
public function getRouteResolver(): RouteResolverInterface
{
return $this->routeResolver;
}

/********************************************************************************
* Router proxy methods
*******************************************************************************/

/**
* Add GET route
*
* @param string $pattern The route URI pattern
* @param callable|string $callable The route callback routine
*
* @return RouteInterface
*/
public function get(string $pattern, $callable): RouteInterface
{
return $this->map(['GET'], $pattern, $callable);
}

/**
* Add POST route
*
* @param string $pattern The route URI pattern
* @param callable|string $callable The route callback routine
*
* @return RouteInterface
*/
public function post(string $pattern, $callable): RouteInterface
{
return $this->map(['POST'], $pattern, $callable);
}

/**
* Add PUT route
*
* @param string $pattern The route URI pattern
* @param callable|string $callable The route callback routine
*
* @return RouteInterface
*/
public function put(string $pattern, $callable): RouteInterface
{
return $this->map(['PUT'], $pattern, $callable);
}

/**
* Add PATCH route
*
* @param string $pattern The route URI pattern
* @param callable|string $callable The route callback routine
*
* @return RouteInterface
*/
public function patch(string $pattern, $callable): RouteInterface
{
return $this->map(['PATCH'], $pattern, $callable);
}

/**
* Add DELETE route
*
* @param string $pattern The route URI pattern
* @param callable|string $callable The route callback routine
*
* @return RouteInterface
*/
public function delete(string $pattern, $callable): RouteInterface
{
return $this->map(['DELETE'], $pattern, $callable);
}

/**
* Add OPTIONS route
*
* @param string $pattern The route URI pattern
* @param callable|string $callable The route callback routine
*
* @return RouteInterface
*/
public function options(string $pattern, $callable): RouteInterface
{
return $this->map(['OPTIONS'], $pattern, $callable);
}

/**
* Add route for any HTTP method
*
* @param string $pattern The route URI pattern
* @param callable|string $callable The route callback routine
*
* @return RouteInterface
*/
public function any(string $pattern, $callable): RouteInterface
{
return $this->map(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], $pattern, $callable);
}

/**
* Add route with multiple methods
*
* @param string[] $methods Numeric array of HTTP method names
* @param string $pattern The route URI pattern
* @param callable|string $callable The route callback routine
*
* @return RouteInterface
*/
public function map(array $methods, string $pattern, $callable): RouteInterface
{
// Bind route callable to container, if present
if ($this->container instanceof ContainerInterface && $callable instanceof Closure) {
$callable = $callable->bindTo($this->container);
}

return $this->routeCollector->map($methods, $pattern, $callable);
}

/**
* Add a route that sends an HTTP redirect
*
* @param string $from
* @param string|UriInterface $to
* @param int $status
*
* @return RouteInterface
*/
public function redirect(string $from, $to, int $status = 302): RouteInterface
{
$handler = function () use ($to, $status) {
$response = $this->responseFactory->createResponse($status);
return $response->withHeader('Location', (string)$to);
};

return $this->get($from, $handler);
}

/**
* Route Groups
*
* This method accepts a route pattern and a callback. All route
* declarations in the callback will be prepended by the group(s)
* that it is in.
*
* @param string $pattern
* @param callable $callable
*
* @return RouteGroupInterface
*/
public function group(string $pattern, $callable): RouteGroupInterface
{
$group = $this->routeCollector->pushGroup($pattern, $callable);
$group($this);
$this->routeCollector->popGroup();
return $group;
}

/********************************************************************************
* Runner
*******************************************************************************/

/**
* Run application
*
Expand Down
18 changes: 6 additions & 12 deletions Slim/Interfaces/RouteCollectorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ public function getNamedRoute(string $name): RouteInterface;
public function removeNamedRoute(string $name): RouteCollectorInterface;

/**
* Lookup a route via the route's unique identifier
*
* @param string $identifier
*
* @return RouteInterface
Expand All @@ -107,21 +109,13 @@ public function removeNamedRoute(string $name): RouteCollectorInterface;
public function lookupRoute(string $identifier): RouteInterface;

/**
* Add a route group to the array
*
* @param string $pattern The group pattern
* @param callable $callable A group callable
* Add route group
*
* @param string $pattern
* @param string|callable $callable
* @return RouteGroupInterface
*/
public function pushGroup(string $pattern, $callable): RouteGroupInterface;

/**
* Removes the last route group from the array
*
* @return RouteGroupInterface|null
*/
public function popGroup(): ?RouteGroupInterface;
public function group(string $pattern, $callable): RouteGroupInterface;

/**
* Add route
Expand Down
Loading

0 comments on commit 7377499

Please sign in to comment.