Reputation: 1
In my Symfony 7 project, I aim to automatically add the ID parameter to route generation if it is present in the current request parameters, whether generating the route via Twig or from a controller.
Example: To generate a URL for the route {Id}/admin (name: admin) from the route {Id}/home (name: home), I would only need to provide the route name 'admin' and my code would automatically add the ID parameter.
To achieve this, I decided to create a custom router. However, I found very few resources on this topic but managed to find an example.
Now, my CustomRouter is causing an error that I am struggling to properly configure and understand:
Error:
RuntimeException HTTP 500 Internal Server Error The definition ".service_locator.H.editd" has a reference to an abstract definition "Symfony\Component\Config\Loader\LoaderInterface". Abstract definitions cannot be the target of references.
src/Router/CustomRouter.php:
namespace App\Router;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Contracts\Service\ServiceSubscriberInterface;
class CustomRouter implements WarmableInterface, ServiceSubscriberInterface, RouterInterface, RequestMatcherInterface
{
/**
* @var Router
*/
private $router;
public function __construct(Router $router)
{
$this->router = $router;
}
public function getRouteCollection(): RouteCollection
{
return $this->router->getRouteCollection();
}
public function warmUp(string $cacheDir, ?string $buildDir = null): array
{
return $this->router->warmUp($cacheDir, $buildDir);
}
public static function getSubscribedServices(): array
{
return Router::getSubscribedServices();
}
public function setContext(RequestContext $context): void
{
$this->router->setContext($context);
}
public function getContext(): RequestContext
{
return $this->router->getContext();
}
public function matchRequest(Request $request): array
{
return $this->router->matchRequest($request);
}
public function generate(string $name, array $parameters = [], int $referenceType = self::ABSOLUTE_PATH): string
{
// My logic for injecting ID parameter
return $this->router->generate($name, $parameters, $referenceType);
}
public function match(string $pathinfo): array
{
return $this->router->match($pathinfo);
}
}
In my services.yaml:
services:
App\Router\CustomRouter:
decorates: router
arguments: ['@App\Router\CustomRouter.inner']
Why i want to do that ?
Actually, the reason I'm aiming for automatic injection of an id
parameter during route generation is that I want to use EasyAdmin while always having a reference in the URL to the Application we are operating on. However, when generating a dashboard with EasyAdmin, we get a URL like /admin
, and it doesn't seem feasible to add a parameter to the URL. When creating links to CRUD controllers (linkToCrud
), we can't add route parameters as we wish (we can configure the CRUD entity, the type of page (edit, index, create, etc.), but we are not 'really free' with the route parameters).
I could potentially use links like this in the dashboard:
yield MenuItem::linkToRoute('Home', 'fa fa-home', 'admin', ['appId' => $appId]);
But then I would also need to add appId
to every use of path()
in the EasyAdmin Twig files (for example, EasyAdmin uses path(ea.dashboardRouteName)
for the link to the dashboard). That's why I prefer to see if there's a way to automate this parameter addition to the route.
<?php
namespace App\Controller\Admin;
use App\Entity\App;
use App\Repository\AppRepository;
use App\Repository\UserRepository;
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\UX\Chartjs\Builder\ChartBuilderInterface;
use Symfony\UX\Chartjs\Model\Chart;
use App\Entity\User;
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
class DashboardController extends AbstractDashboardController
{
public function __construct(
public ChartBuilderInterface $chartBuilder,
public AppRepository $appRepository,
public RequestStack $requestStack,
public UserRepository $userRepository
) {
}
public function configureFilters(): Filters
{
return parent::configureFilters();
}
#[Route('/{appId}/admin', name: 'admin')]
public function index(): Response
{
return $this->render('admin/dashboard.html.twig', []);
}
public function configureDashboard(): Dashboard
{
return Dashboard::new()
->setTitle('Hub Cms');
}
public function configureMenuItems(): iterable
{
$appCount = $this->appRepository->count([]);
$usersCount = $this->userRepository->count([]);
yield MenuItem::linkToDashboard('Dashboard', 'fa fa-home');
yield MenuItem::linkToCrud('Users', 'fa fa-user', User::class)->setBadge($usersCount);
yield MenuItem::linkToCrud('Apps', 'fa fa-user', App::class)->setBadge($appCount);
}
}
How can I resolve this error and properly configure my CustomRouter? Any insights or examples would be greatly appreciated! Thank you!
Upvotes: 0
Views: 86