Symfony 4 / Sonata : Utiliser une clef primaire avec un /

Aussi bizarre que cela puisse paraître j’ai du utiliser une entity avec une primary key positionné sur un champ de type varchar, et certaines valeurs contenaient un « / ».

Tant que l’on est pas confronté au problème, impossible de se dire que cela va poser un soucis. Et la c’est le drame.

image
An exception has been thrown during the rendering of a template ("Parameter "id" for route "admin_app_wtype_edit" must match "[^/]++" ("MACHIN/CHOSE" given) to generate a corresponding URL.").

En gros, le slash est interprété par le générateur d’URL comme un séparateur de l’URL et cela fait planter le système.
Du coup, il faut modifier le générateur d’URL pour qu’il transforme ce « / » en autre chose (en gros URL encodé), et ensuite en entrée il faut modifier la valeur de la clef primaire récupéré pour sélectionner l’objet pour qu’il fasse la transformation inverse.

Dans votre fichier XxxAdmin.php, rajoutez l’interface :

use Symfony\Component\Routing\Generator\UrlGeneratorInterface as RoutingUrlGeneratorInterface;

Puis rajoutez les deux fonction suivantes :

 public function generateUrl($name, array $parameters = [], $absolute = RoutingUrlGeneratorInterface::ABSOLUTE_PATH)
    {
       
        if(!empty($parameters['id'])){
            $parameters['id'] = str_replace("/","%2F",$parameters['id']);
        }
        
        return $this->routeGenerator->generateUrl($this, $name, $parameters, $absolute);
    }
    
    public function getObject($id)
    {
        $id=str_replace("%2F","/",$id);

        $object = $this->getModelManager()->find($this->getClass(), $id);
        foreach ($this->getExtensions() as $extension) {
            $extension->alterObject($this, $object);
        }
    
        return $object;
    }