Skip to content

Route Model and getId / getRouteKey with string requirement #495

@tft7000

Description

@tft7000

I upgraded to the Routing Bundle v3, which made my application break because _route is now set to empty string.

I found out that Model\Route::getRouteKey() and the underlying Model\Route::getId() method are returning now a string. So in case Model\Route::$id is null Model\Route::getRouteKey() will return an empty String. That leads to my problem: in UrlMatcher::getAttributes there is a check, if $route->getRoute() is a string. Since v3 this will be always true because of the forced type conversion in Model\Route::getId(). So my application breaks because _route will now be set to empty String instead of the provided $name.

Possible Workaround: I will need to either reimplement the base model or decorate the UrlMatcher to solve that problem.

Questions:

  • Is there a reason, why the ID is not allowed to be null anymore (since v3)? In the corresponding commit I could not find one and the Interface still allows null.
  • would it break anything if that type conversion would be removed again?

In case of interest: my workaround looks like this:

<?php

namespace App\Routing;

use Symfony\Cmf\Component\Routing\NestedMatcher\UrlMatcher;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

/**
 * overwrites getAttributes in such way, that it behaves like in v2 of the cmf routing bundle
 */
#[AsDecorator(decorates: 'cmf_routing.final_matcher')]
class UrlMatcherDecorator extends UrlMatcher
{
    public function __construct(
        #[Autowire(service: 'cmf_routing.matcher.dummy_collection')]
        RouteCollection $routes,
        #[Autowire(service: 'cmf_routing.matcher.dummy_context')]
        RequestContext  $context,
    )
    {
        parent::__construct($routes, $context);
    }

    protected function getAttributes(Route $route, string $name, array $attributes): array
    {
        if ($route instanceof RouteObjectInterface && is_string($route->getRouteKey()) && !empty($route->getRouteKey())) {
            $name = $route->getRouteKey();
        }
        $attributes[RouteObjectInterface::ROUTE_NAME] = $name;
        $attributes[RouteObjectInterface::ROUTE_OBJECT] = $route;

        return $this->mergeDefaults($attributes, $route->getDefaults());
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions