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

Refine routes list functionality #58

Open
wants to merge 20 commits into
base: 2.10.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
74360ac
Refactor RoutesFilter to use a RouteFilterOptionsInterface object
settermjd Oct 25, 2024
c1d7005
Add docblock comments for RouteFilterOptionsInterface methods
settermjd Oct 25, 2024
d6428c4
Refactor filter options as class member variables
settermjd Oct 25, 2024
59af694
Refactor RouteFilterOptions to require specific types without defaults
settermjd Nov 14, 2024
5db68d1
Replace the Exception with a Throwable in RoutesFilter
settermjd Nov 14, 2024
924dce8
Refactor ListRoutesCommand to take a RouteCollector directly
settermjd Nov 14, 2024
8ebec29
Minor code clean up
settermjd Nov 14, 2024
d9d312b
Refactor how ListRoutesCommandFactory retrieves a ConfigLoaderInterface
settermjd Nov 14, 2024
85272ab
Add a default way of retrieving routes from the application
settermjd Nov 14, 2024
8629833
Load the DefaultRoutesConfigLoaderFactory with Mezzio Tooling
settermjd Nov 14, 2024
faca61d
Update src/Routes/Filter/RouteFilterOptionsInterface.php
settermjd Dec 10, 2024
4d43eea
Update src/Routes/Filter/RouteFilterOptions.php
settermjd Dec 10, 2024
1e444fc
Clean up file to match changes in recent commits
settermjd Dec 10, 2024
f060930
Update README to match style guide
settermjd Dec 10, 2024
85fb178
Remove redundant EmptyRouteFilterOptions
settermjd Dec 10, 2024
0196ed9
Update RouteFilterOptions to match RouteFilterOptionsInterface
settermjd Dec 10, 2024
b698744
Remove unrequired RouteFilterOptionsInterface parameter
settermjd Dec 10, 2024
59cd05c
Update ConfigProvider configuration for RoutesFileConfigLoader
settermjd Dec 10, 2024
ec8cff7
Remove redundant toArray method from RouteFilterOptions
settermjd Dec 10, 2024
0155d7d
Fix up a small bug in RouteFilterOptions
settermjd Dec 10, 2024
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
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,19 @@ The command supports several options, listed in the table below.
| `--has-middleware` | `-w` | Accepts a comma-separated list of one or more middleware classes, and filters out routes that do not require those classes. The classes can be fully-qualified, unqualified, or a regular expression, supported by the preg_* functions. For example, "\Mezzio\Middleware\LazyLoadingMiddleware,LazyLoadingMiddleware,\Mezzio*". |
<!-- markdownlint-enable MD037 -->

##### Configuration

By default, `Mezzio\Tooling\Routes\DefaultRoutesConfigLoaderFactory` registers a `ConfigLoaderInterface` service with the application's DI container, which retrieves the application's routes from two sources:

- `config/routes.php`
- Routes registered by any loaded `ConfigProvider` class

However, this is a default/fallback implementation.
If you don't store any routes in _config/routes.php_ or need a custom implementation, then you need to do two things:

1. Write a custom loader implementation that implements `Mezzio\Tooling\Routes\ConfigLoaderInterface`
2. Register it with the application's DI container as an alias for `Mezzio\Tooling\Routes\ConfigLoaderInterface`

##### Usage Example

Here is an example of what you can expect from running the command.
Expand Down
884 changes: 445 additions & 439 deletions composer.lock

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions src/ConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@
use Mezzio\Tooling\Module\DeregisterCommandFactory;
use Mezzio\Tooling\Module\RegisterCommand;
use Mezzio\Tooling\Module\RegisterCommandFactory;
use Mezzio\Tooling\Routes\ConfigLoaderInterface;
use Mezzio\Tooling\Routes\DefaultRoutesConfigLoaderFactory;
use Mezzio\Tooling\Routes\ListRoutesCommand;
use Mezzio\Tooling\Routes\ListRoutesCommandFactory;
use Mezzio\Tooling\Routes\RoutesFileConfigLoader;

final class ConfigProvider
{
Expand Down Expand Up @@ -65,6 +68,9 @@ public function getConsoleConfig(): array
public function getDependencies(): array
{
return [
'aliases' => [
ConfigLoaderInterface::class => RoutesFileConfigLoader::class,
],
'factories' => [
Create::class => CreateFactory::class,
CreateActionCommand::class => CreateActionCommandFactory::class,
Expand All @@ -77,6 +83,7 @@ public function getDependencies(): array
MigrateInteropMiddlewareCommand::class => MigrateInteropMiddlewareCommandFactory::class,
MigrateMiddlewareToRequestHandlerCommand::class => MigrateMiddlewareToRequestHandlerCommandFactory::class,
RegisterCommand::class => RegisterCommandFactory::class,
RoutesFileConfigLoader::class => DefaultRoutesConfigLoaderFactory::class,
],
];
}
Expand Down
36 changes: 36 additions & 0 deletions src/Routes/DefaultRoutesConfigLoaderFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace Mezzio\Tooling\Routes;

use Mezzio\Application;
use Mezzio\MiddlewareFactory;
use Psr\Container\ContainerInterface;

/**
* This class provides a default factory implementation for retrieving an app's routes

* The assumption with this "default" config loader factory is that you're
* loading routes from config/routes.php in your Mezzio application. So, if
* that's not the case in your application, create a custom loader
* implementation and override the alias in the DiC.
*/
final class DefaultRoutesConfigLoaderFactory
{
public function __invoke(ContainerInterface $container): ConfigLoaderInterface
{
/** @var Application $application */
$application = $container->get(Application::class);

/** @var MiddlewareFactory $factory */
$factory = $container->get(MiddlewareFactory::class);

return new RoutesFileConfigLoader(
'config/routes.php',
$application,
$factory,
$container
);
}
}
71 changes: 25 additions & 46 deletions src/Routes/Filter/RouteFilterOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,85 +4,64 @@

namespace Mezzio\Tooling\Routes\Filter;

use function array_filter;
use function array_map;
use function get_object_vars;
use function in_array;
use function is_array;
use function is_string;
use function strtoupper;

final class RouteFilterOptions
final class RouteFilterOptions implements RouteFilterOptionsInterface
{
private string $middleware;
private string $name;
private string $path;
private array $allowedFilterOptions = ['methods', 'middleware', 'name', 'path'];
private array $methods;

/** @var array<array-key,string> */
private array $methods = [];

/**
* @param string|array<array-key,string> $methods
*/
/** @param list<string> $methods */
public function __construct(
string $middleware = '',
string $name = '',
string $path = '',
$methods = []
private string|null $middleware,
private string|null $name,
private string|null $path,
array $methods
) {
if (is_string($methods)) {
$this->methods = [$methods];
}
if (is_array($methods)) {
$this->methods = $methods;
}
$this->middleware = $middleware;
$this->name = $name;
$this->path = $path;
$this->methods = array_map(static fn(string $value): string => strtoupper($value), $methods);
}

private function getFilterOptionsMinusMethods(): array
{
return array_filter($this->allowedFilterOptions, fn($value) => $value !== "methods");
}

public function has(string $filterOption): bool
{
if (in_array($filterOption, ['middleware', 'name', 'path'])) {
return $this->$filterOption !== null;
if (! in_array($filterOption, $this->allowedFilterOptions)) {
return false;
}

if ($filterOption === 'methods') {
return [] !== $this->methods;
if (in_array($filterOption, $this->getFilterOptionsMinusMethods())) {
return $this->$filterOption !== null;
}

return false;
return $this->methods !== [] && $this->methods !== null;
}

public function getMiddleware(): string
public function getMiddleware(): string|null
{
return $this->middleware;
}

public function getName(): string
public function getName(): string|null
{
return $this->name;
}

public function getPath(): string
public function getPath(): string|null
{
return $this->path;
}

/**
* @return array<array-key,string>
*/
public function getMethods(): array
{
return $this->methods;
}

public function toArray(): array
{
$values = [];
foreach (get_object_vars($this) as $key => $value) {
if (! empty($value)) {
$values[$key] = $value;
}
}

return $values;
}
}
35 changes: 35 additions & 0 deletions src/Routes/Filter/RouteFilterOptionsInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This interface seems unnecessary

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's still used in RoutesFilter and seems worth keeping.


namespace Mezzio\Tooling\Routes\Filter;

interface RouteFilterOptionsInterface
{
/**
* Determines if the specified filter ($filterOption) has been set
*/
public function has(string $filterOption): bool;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The has method seems unnecessary when consumers can test for $options->getMiddleware() === [] or $options->getName() === null


/**
* Retrieves a route middleware filter the available routing data by
*/
public function getMiddleware(): string|null;

/**
* Retrieves a route name filter the available routing data by
*/
public function getName(): string|null;

/**
* Retrieves a route path to filter the available routing data by
*/
public function getPath(): string|null;

/**
* Returns any route methods to filter the available routing data by
*
* @return list<string>
*/
public function getMethods(): array;
}
Loading