Hablemos de su proyecto
PHP symfony Sonata

Symfony 4 / Sonata: Usar una clave primaria con un /

Aunque parezca extraño, tuve que utilizar una entidad con una clave primaria establecida en un campo varchar, y algunos valores contenían un " / ".Hasta que te enfrentas al problema, es imposible imaginar que causará un inconveniente. Y luego, se ...

Symfony 4 / Sonata: Usar una clave primaria con un /

Aunque parezca extraño, tuve que utilizar una entidad con una clave primaria establecida en un campo varchar, y algunos valores contenían un " / ".

Hasta que te enfrentas al problema, es imposible imaginar que causará un inconveniente. Y luego, se desata el drama.

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 resumen, la barra inclinada es interpretada por el generador de URL como un separador de URL, lo que provoca el colapso del sistema.
Por lo tanto, necesitas modificar el generador de URL para que convierta este " / " en algo distinto (esencialmente codificado para URL), y luego en la entrada, necesitas modificar el valor de la clave primaria recuperada para seleccionar el objeto de modo que realice la transformación inversa.

En tu archivo XxxAdmin.php, añade la siguiente interfaz:

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

Luego agrega las siguientes dos funciones:

 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;
    }

Adaptar el ejemplo a la versión instalada

Los ejemplos de Symfony y Sonata permanecen ligados a las versiones indicadas en el artículo. Symfony 4.x y Symfony 6.2 ya no se mantienen: para un proyecto actual, utilice una rama mantenida y la documentación que corresponda exactamente a sus dependencias.

php bin/console about
composer show symfony/framework-bundle sonata-project/admin-bundle

Antes de retomar el código, controle las firmas, los servicios, las rutas y las plantillas correspondientes. Después, agregue una prueba funcional que cubra los permisos, el código HTTP y el resultado visible.

Referencia: versiones de Symfony mantenidas.

Compartir este artículo