Skip to content

Commit

Permalink
New routes and groups syntax (#99)
Browse files Browse the repository at this point in the history
  • Loading branch information
yiiliveext committed Mar 26, 2021
1 parent cf43bff commit c799f4f
Show file tree
Hide file tree
Showing 9 changed files with 263 additions and 273 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -70,7 +70,7 @@ $response = $result->process($request, $handler);
`UrlGeneratorInterface` and `UrlMatcher` are specific to adapter package used. See its readme on how to properly
configure it.

In `addMiddleware()` you can either specify PSR middleware class name or a callback.
In `middleware()` and `prependMiddleware()` you can either specify PSR middleware class name or a callback.

Note that pattern specified for routes depends on the underlying routing library used.

Expand Down
82 changes: 60 additions & 22 deletions src/Group.php
Expand Up @@ -5,6 +5,7 @@
namespace Yiisoft\Router;

use InvalidArgumentException;
use RuntimeException;
use Yiisoft\Middleware\Dispatcher\MiddlewareDispatcher;
use function get_class;
use function in_array;
Expand All @@ -19,32 +20,37 @@ final class Group implements RouteCollectorInterface
*/
protected array $items = [];
protected ?string $prefix;

protected array $middlewareDefinitions = [];

private bool $routesAdded = false;
private bool $middlewareAdded = false;
private array $disabledMiddlewareDefinitions = [];
private ?MiddlewareDispatcher $dispatcher = null;
private ?MiddlewareDispatcher $dispatcher;

private function __construct(?string $prefix = null, ?callable $callback = null, MiddlewareDispatcher $dispatcher = null)
private function __construct(?string $prefix = null, MiddlewareDispatcher $dispatcher = null)
{
$this->dispatcher = $dispatcher;
$this->prefix = $prefix;

if ($callback !== null) {
$callback($this);
}
}

/**
* Create a new instance
* Create a new group instance.
*
* @param string|null $prefix
* @param array|callable $routes
* @param MiddlewareDispatcher|null $dispatcher
* @param string|null $prefix URL prefix to prepend to all routes of the group.
* @param MiddlewareDispatcher|null $dispatcher Middleware dispatcher to use for the group.
*
* @return self
*/
public static function create(?string $prefix = null, $routes = [], MiddlewareDispatcher $dispatcher = null): self
public static function create(?string $prefix = null, MiddlewareDispatcher $dispatcher = null): self
{
return new self($prefix, $dispatcher);
}

public function routes(...$routes): self
{
if ($this->middlewareAdded) {
throw new RuntimeException('routes() can not be used after prependMiddleware().');
}
if (is_callable($routes)) {
$callback = $routes;
} elseif (is_array($routes)) {
Expand All @@ -56,15 +62,20 @@ public static function create(?string $prefix = null, $routes = [], MiddlewareDi
$group->addGroup($route);
} else {
$type = is_object($route) ? get_class($route) : gettype($route);
throw new InvalidArgumentException(sprintf('Route should be either instance of Route or Group, %s given.', $type));
throw new InvalidArgumentException(sprintf('Route should be either an instance of Route or Group, %s given.', $type));
}
}
};
} else {
$callback = null;
}

return new self($prefix, $callback, $dispatcher);
if ($callback !== null) {
$callback($this);
}
$this->routesAdded = true;

return $this;
}

public function withDispatcher(MiddlewareDispatcher $dispatcher): self
Expand Down Expand Up @@ -101,28 +112,55 @@ public function addGroup(self $group): self
$group = $group->withDispatcher($this->dispatcher);
}
$this->items[] = $group;


return $this;
}

/**
* Adds a handler middleware definition that should be invoked for a matched route.
* Last added handler will be executed first.
* Appends a handler middleware definition that should be invoked for a matched route.
* First added handler will be executed first.
*
* @param $middlewareDefinition mixed
* @param mixed $middlewareDefinition
*
* @return self
*/
public function addMiddleware($middlewareDefinition): self
public function middleware($middlewareDefinition): self
{
if ($this->routesAdded) {
throw new RuntimeException('middleware() can not be used after routes().');
}
array_unshift($this->middlewareDefinitions, $middlewareDefinition);

return $this;
}

/**
* Prepends a handler middleware definition that should be invoked for a matched route.
* First added handler will be executed last.
*
* @param mixed $middlewareDefinition
* @return $this
*/
public function prependMiddleware($middlewareDefinition): self
{
$this->middlewareDefinitions[] = $middlewareDefinition;
$this->middlewareAdded = true;
return $this;
}

/**
* Excludes middleware from being invoked when action is handled.
* It is useful to avoid invoking one of the parent group middleware for
* a certain route.
*
* @param mixed $middlewareDefinition
* @return $this
*/
public function disableMiddleware($middlewareDefinition): self
{
$route = clone $this;
$route->disabledMiddlewareDefinitions[] = $middlewareDefinition;
return $route;
$this->disabledMiddlewareDefinitions[] = $middlewareDefinition;
return $this;
}

/**
Expand All @@ -141,7 +179,7 @@ public function getPrefix(): ?string
public function getMiddlewareDefinitions(): array
{
foreach ($this->middlewareDefinitions as $index => $definition) {
if (in_array($definition, $this->disabledMiddlewareDefinitions)) {
if (in_array($definition, $this->disabledMiddlewareDefinitions, true)) {
unset($this->middlewareDefinitions[$index]);
}
}
Expand Down

0 comments on commit c799f4f

Please sign in to comment.