Skip to content

Commit

Permalink
Merge pull request #36 from ricventu/handle-multiple-nested-controller
Browse files Browse the repository at this point in the history
Handle multiple nested routes
  • Loading branch information
freekmurze authored Jan 22, 2025
2 parents 63ffa97 + 6e5842f commit 2b2c500
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 23 deletions.
51 changes: 29 additions & 22 deletions src/PendingRouteTransformers/HandleUrisOfNestedControllers.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@
class HandleUrisOfNestedControllers implements PendingRouteTransformer
{
/**
* @param Collection<PendingRoute> $pendingRoutes
* @param Collection<int, PendingRoute> $pendingRoutes
*
* @return Collection<PendingRoute>
* @return Collection<int, PendingRoute>
*/
public function transform(Collection $pendingRoutes): Collection
{
$pendingRoutes->each(function (PendingRoute $parentPendingRoute) use ($pendingRoutes) {
$childNode = $this->findChild($pendingRoutes, $parentPendingRoute);
$childrenNodes = $this->findChild($pendingRoutes, $parentPendingRoute);

if (! $childNode) {
if (! $childrenNodes->count()) {
return;
}

Expand All @@ -33,35 +33,42 @@ public function transform(Collection $pendingRoutes): Collection
return;
}

$childNode->actions->each(function (PendingRouteAction $action) use ($parentPendingRoute, $parentAction) {
$paramsToRemove = $action->modelParameters()
->filter(
fn (ReflectionParameter $parameter) => $parentAction
->modelParameters()
->contains(
fn (ReflectionParameter $parentParameter) => $parentParameter->getName() === $parameter->getName()
$childrenNodes->each(function (PendingRoute $childNode) use ($parentPendingRoute, $parentAction) {
$childNode->actions->each(function (PendingRouteAction $action) use ($parentPendingRoute, $parentAction) {
$paramsToRemove = $action->modelParameters()
->filter(
fn (ReflectionParameter $parameter) => $parentAction
->modelParameters()
->contains(
fn (ReflectionParameter $parentParameter) => $parentParameter->getName() === $parameter->getName()
)
);
$result = Str::of($action->uri)
->replace(
$paramsToRemove->map(fn (ReflectionParameter $parameter) => "{{$parameter->getName()}}")->toArray(),
''
)
);
$result = Str::of($action->uri)
->replace(
$paramsToRemove->map(fn (ReflectionParameter $parameter) => "{{$parameter->getName()}}")->toArray(),
''
)
->replace('//', '/')
->replace($parentPendingRoute->uri, $parentAction->uri);
->replace('//', '/')
->replace($parentPendingRoute->uri, $parentAction->uri);

$action->uri = $result;
$action->uri = $result;
});
});
});

return $pendingRoutes;
}

protected function findChild(Collection $pendingRoutes, PendingRoute $parentRouteAction): ?PendingRoute
/**
* @param Collection<int, PendingRoute> $pendingRoutes
* @param PendingRoute $parentRouteAction
* @return Collection<int, PendingRoute>
*/
protected function findChild(Collection $pendingRoutes, PendingRoute $parentRouteAction): Collection
{
$childNamespace = $parentRouteAction->childNamespace();

return $pendingRoutes->first(
return $pendingRoutes->filter(
fn (PendingRoute $potentialChildRoute) => $potentialChildRoute->namespace() === $childNamespace
);
}
Expand Down
14 changes: 13 additions & 1 deletion tests/RouteDiscoveryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Spatie\RouteDiscovery\Tests\Support\TestClasses\Controllers\NestedWithMultipleParametersController\Photos\CommentsController as MpCommentsController;
use Spatie\RouteDiscovery\Tests\Support\TestClasses\Controllers\NestedWithMultipleParametersController\PhotosController as MpPhotosController;
use Spatie\RouteDiscovery\Tests\Support\TestClasses\Controllers\NestedWithParametersController\Photos\CommentsController;
use Spatie\RouteDiscovery\Tests\Support\TestClasses\Controllers\NestedWithParametersController\Photos\UsersController;
use Spatie\RouteDiscovery\Tests\Support\TestClasses\Controllers\NestedWithParametersController\PhotosController;
use Spatie\RouteDiscovery\Tests\Support\TestClasses\Controllers\Nesting\Nested\ChildController;
use Spatie\RouteDiscovery\Tests\Support\TestClasses\Controllers\Nesting\Nested\Deepest\IndexController as DeepestIndexController;
Expand Down Expand Up @@ -99,7 +100,7 @@
->routeRegistrar
->registerDirectory(controllersPath('NestedWithParametersController'));

$this->assertRegisteredRoutesCount(4);
$this->assertRegisteredRoutesCount(6);

$this->assertRouteRegistered(
PhotosController::class,
Expand All @@ -123,6 +124,17 @@
controllerMethod: 'edit',
uri: 'photos/{photo}/comments/edit/{comment}',
);

$this->assertRouteRegistered(
UsersController::class,
controllerMethod: 'show',
uri: 'photos/{photo}/users/{user}',
);
$this->assertRouteRegistered(
UsersController::class,
controllerMethod: 'edit',
uri: 'photos/{photo}/users/edit/{user}',
);
});

it('can automatically discover a nested route with multiple model parameters', function () {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Spatie\RouteDiscovery\Tests\Support\TestClasses\Controllers\NestedWithParametersController\Photos;

use Spatie\RouteDiscovery\Tests\Support\TestClasses\Models\User;

class UsersController
{
public function show(User $user)
{
}

public function edit(User $user)
{
}
}

0 comments on commit 2b2c500

Please sign in to comment.