Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New syntax #225

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 169 additions & 0 deletions src/Builder/GroupBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Router\Builder;

use RuntimeException;
use Yiisoft\Router\Group;
use Yiisoft\Router\RoutableInterface;
use Yiisoft\Router\Route;

/**
* GroupBuilder allows you to build group of routes using a flexible syntax.
*/
final class GroupBuilder implements RoutableInterface
{
/**
* @var Group[]|RoutableInterface[]|Route[]
*/
private array $routes = [];

/**
* @var array[]|callable[]|string[]
* @psalm-var list<array|callable|string>
*/
private array $middlewares = [];

private array $disabledMiddlewares = [];

/**
* @var string[]
*/
private array $hosts = [];
private bool $routesAdded = false;
private bool $middlewareAdded = false;

/**
* @var array|callable|string|null Middleware definition for CORS requests.
*/
private $corsMiddleware = null;

private function __construct(
private ?string $prefix = null,
private ?string $namePrefix = null,
) {
}

/**
* Create a new group instance.
*
* @param string|null $prefix URL prefix to prepend to all routes of the group.
*/
public static function create(?string $prefix = null, ?string $namePrefix = null): self
{
return new self($prefix, $namePrefix);
}

public function routes(Group|Route|RoutableInterface ...$routes): self
{
if ($this->middlewareAdded) {
throw new RuntimeException('routes() can not be used after prependMiddleware().');
}

$new = clone $this;
$new->routes = $routes;
$new->routesAdded = true;

return $new;
}

/**
* Adds a middleware definition that handles CORS requests.
* If set, routes for {@see Method::OPTIONS} request will be added automatically.
*
* @param array|callable|string|null $middlewareDefinition Middleware definition for CORS requests.
*/
public function withCors(array|callable|string|null $middlewareDefinition): self
{
$group = clone $this;
$group->corsMiddleware = $middlewareDefinition;

return $group;
}

/**
* Appends a handler middleware definition that should be invoked for a matched route.
* First added handler will be executed first.
*/
public function middleware(array|callable|string ...$definition): self
{
if ($this->routesAdded) {
throw new RuntimeException('middleware() can not be used after routes().');
}

$new = clone $this;
array_push(
$new->middlewares,
...array_values($definition)
);

return $new;
}

/**
* Prepends a handler middleware definition that should be invoked for a matched route.
* First added handler will be executed last.
*/
public function prependMiddleware(array|callable|string ...$definition): self
{
$new = clone $this;
array_unshift(
$new->middlewares,
...array_values($definition)
);

$new->middlewareAdded = true;

return $new;
}

public function namePrefix(string $namePrefix): self
{
$new = clone $this;
$new->namePrefix = $namePrefix;
return $new;
}

public function host(string $host): self
{
return $this->hosts($host);
}

public function hosts(string ...$hosts): self
{
$new = clone $this;
$new->hosts = array_values($hosts);

Check warning on line 136 in src/Builder/GroupBuilder.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "UnwrapArrayValues": --- Original +++ New @@ @@ public function hosts(string ...$hosts) : self { $new = clone $this; - $new->hosts = array_values($hosts); + $new->hosts = $hosts; return $new; } /**

Check warning on line 136 in src/Builder/GroupBuilder.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "UnwrapArrayValues": --- Original +++ New @@ @@ public function hosts(string ...$hosts) : self { $new = clone $this; - $new->hosts = array_values($hosts); + $new->hosts = $hosts; return $new; } /**

return $new;
}

/**
* 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.
*/
public function disableMiddleware(mixed ...$definition): self
{
$new = clone $this;
array_push(
$new->disabledMiddlewares,
...array_values($definition),
);

return $new;
}

public function toRoute(): Group|Route
{
return new Group(
prefix: $this->prefix,
namePrefix: $this->namePrefix,
routes: $this->routes,
middlewares: $this->middlewares,
hosts: $this->hosts,
disabledMiddlewares: $this->disabledMiddlewares,
corsMiddleware: $this->corsMiddleware
);
}
}
216 changes: 216 additions & 0 deletions src/Builder/RouteBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Router\Builder;

use Stringable;
use Yiisoft\Http\Method;
use Yiisoft\Router\Group;
use Yiisoft\Router\RoutableInterface;
use Yiisoft\Router\Route;

/**
* RouteBuilder allows you to build routes using a flexible syntax.
*/
final class RouteBuilder implements RoutableInterface
{
private ?string $name = null;

/**
* @var array|callable|string|null
*/
private $action = null;

/**
* @var string[]
*/
private array $hosts = [];

private bool $override = false;

private array $disabledMiddlewares = [];

/**
* @var array[]|callable[]|string[]
* @psalm-var list<array|callable|string>
*/
private array $middlewares = [];

/**
* @var array<array-key,scalar|Stringable|null>
*/
private array $defaults = [];

/**
* @param string[] $methods
*/
private function __construct(
private array $methods,
private string $pattern,
) {
}

public static function get(string $pattern): self
{
return self::methods([Method::GET], $pattern);
}

public static function post(string $pattern): self
{
return self::methods([Method::POST], $pattern);
}

public static function put(string $pattern): self
{
return self::methods([Method::PUT], $pattern);
}

public static function delete(string $pattern): self
{
return self::methods([Method::DELETE], $pattern);
}

public static function patch(string $pattern): self
{
return self::methods([Method::PATCH], $pattern);
}

public static function head(string $pattern): self
{
return self::methods([Method::HEAD], $pattern);
}

public static function options(string $pattern): self
{
return self::methods([Method::OPTIONS], $pattern);
}

/**
* @param string[] $methods
*/
public static function methods(array $methods, string $pattern): self
{
return new self(methods: $methods, pattern: $pattern);
}

public function name(string $name): self
{
$route = clone $this;
$route->name = $name;
return $route;
}

public function pattern(string $pattern): self
{
$new = clone $this;
$new->pattern = $pattern;
return $new;
}

public function host(string $host): self
{
return $this->hosts($host);
}

public function hosts(string ...$hosts): self
{
$route = clone $this;
$route->hosts = array_values($hosts);

Check warning on line 119 in src/Builder/RouteBuilder.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "UnwrapArrayValues": --- Original +++ New @@ @@ public function hosts(string ...$hosts) : self { $route = clone $this; - $route->hosts = array_values($hosts); + $route->hosts = $hosts; return $route; } /**

Check warning on line 119 in src/Builder/RouteBuilder.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "UnwrapArrayValues": --- Original +++ New @@ @@ public function hosts(string ...$hosts) : self { $route = clone $this; - $route->hosts = array_values($hosts); + $route->hosts = $hosts; return $route; } /**

return $route;
}

/**
* Marks route as override. When added it will replace existing route with the same name.
*/
public function override(): self
{
$route = clone $this;
$route->override = true;
return $route;
}

/**
* Parameter default values indexed by parameter names.
*
* @psalm-param array<array-key,null|Stringable|scalar> $defaults
*/
public function defaults(array $defaults): self
{
$route = clone $this;
$route->defaults = $defaults;
return $route;
}

/**
* Appends a handler middleware definition that should be invoked for a matched route.
* First added handler will be executed first.
*/
public function middleware(array|callable|string ...$definition): self
{
$route = clone $this;
array_push(
$route->middlewares,
...array_values($definition)
);

return $route;
}

/**
* Prepends a handler middleware definition that should be invoked for a matched route.
* Last added handler will be executed first.
*/
public function prependMiddleware(array|callable|string ...$definition): self
{
$route = clone $this;
array_unshift(
$route->middlewares,
...array_values($definition)
);

return $route;
}

/**
* Appends action handler. It is a primary middleware definition that should be invoked last for a matched route.
*/
public function action(array|callable|string $middlewareDefinition): self
{
$route = clone $this;
$route->action = $middlewareDefinition;
return $route;
}

/**
* 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.
*/
public function disableMiddleware(mixed ...$definition): self
{
$route = clone $this;
array_push(
$route->disabledMiddlewares,
...array_values($definition)
);

return $route;
}

public function toRoute(): Group|Route
{
return new Route(
methods: $this->methods,
pattern: $this->pattern,
name: $this->name,
action: $this->action,
middlewares: $this->middlewares,
defaults: $this->defaults,
hosts: $this->hosts,
override: $this->override,
disabledMiddlewares: $this->disabledMiddlewares
);
}
}
Loading
Loading