Symfony 4 / Sonata: Administrar una Interfaz de Administración Multi-Servidor

Veremos cómo gestionar una interfaz de administración que se conecta a múltiples servidores.
En nuestro ejemplo, hemos configurado un servidor MySQL predeterminado que gestiona nuestra interfaz de administración. Usuarios, medios, etc.
Y hemos configurado un servidor PostgreSQL que contiene una tabla que deseamos gestionar.
Podemos agregar tantos servidores como deseemos.

Nuestro Servidor MySQL

Tradicionalmente hemos configurado una instancia de Symfony Sonata por defecto con una conexión clásica a MySQL. Así podemos crear nuestra base de datos, el esquema y el usuario por defecto de nuestra interfaz de administración.

php bin/console doctrine:database:create
php bin/console doctrine:schema:update --force
php bin/console fos:user:create --super-admin
Sélection_162

Nuestro Servidor PostgreSQL

Por otro lado, tenemos un servidor PostgreSQL que contiene una tabla "test".

Sélection_161-1

Las Conexiones

En las versiones recientes de Symfony, las credenciales para las conexiones se gestionan en el archivo .env en la raíz de tu proyecto.
Vamos a crear 1 conexión para cada servidor.

DATABASE_URL_PGSQL=pgsql://tbourdin:123456@127.0.0.1:5432/test?
DATABASE_URL_MYSQL=mysql://root:toor@127.0.0.1:3306/symfony-sonata-skeleton?serverVersion=5.7

Luego configuraremos nuestros ajustes de Doctrine creando una conexión predeterminada (MySQL) y una conexión adicional para nuestro servidor PostgreSQL.
Ten cuidado, para evitar confusiones, usamos un guión bajo "_" en lugar de guiones "–" porque Symfony luego convertirá nuestros "–" en "_" y el mapeo no se hará correctamente.

Especificamos que todas nuestras entidades predeterminadas serán gestionadas en src/entity/ServerMysql y que las entidades que necesitan conectarse a Pgsql estarán todas almacenadas en el directorio /src/Entity/ServerPgsql

doctrine:
    dbal:
        default_connection: db_mysql_local
        types:
            json: Sonata\Doctrine\Types\JsonType   
        connections:
            db_mysql_local:
                url: '%env(resolve:DATABASE_URL_MYSQL)%'
                driver: 'pdo_mysql'
                server_version: '5.7'
                charset: utf8

                default_table_options:
                    charset: utf8mb4
                    collate: utf8mb4_unicode_ci
                    
            db_pgsql_local:
                url: '%env(resolve:DATABASE_URL_PGSQL)%'
                driver: 'pdo_pgsql'
                server_version: '9.6.11'
                charset: utf8
                default_table_options:
                    charset: utf8mb4
                    collate: utf8mb4_unicode_ci
                                    

        
        # IMPORTANT: You MUST configure your server version,
        # either here or in the DATABASE_URL env var (see .env file)
        #server_version: '5.7'
    orm:
        auto_generate_proxy_classes: true
        
        default_entity_manager: App
        
        entity_managers:
        #default code, the sonata admin, that use the default connexion (no need to define it here)
            App:
                connection: db_mysql_local
                naming_strategy: doctrine.orm.naming_strategy.underscore
                auto_mapping: true
                mappings:
                    ApplicationSonataMediaBundle: ~
                    SonataMediaBundle: ~
                    App:
                        is_bundle: false
                        type: annotation
                        dir: '%kernel.project_dir%/src/Entity/ServerMysql'
                        prefix: 'App\Entity\ServerMysql'
                        alias: App       
        
        #our pgSql entities that use our pgsql connexion       
            app-pgsql:
                connection: db_pgsql_local
                naming_strategy: doctrine.orm.naming_strategy.underscore
                auto_mapping: false
                mappings:
                    AppPgsql:
                        is_bundle: false
                        type: annotation
                        dir: '%kernel.project_dir%/src/Entity/ServerPgsql'
                        prefix: 'App\Entity\ServerPgsql\'
                        alias: AppPgsql           



Y para verificar nuestro procedimiento intentamos gestionar nuestra interfaz de prueba

image-4

Y por supuesto, no funciona. Porque nuestra entidad está almacenada en nuestro directorio predeterminado.
Entonces la movemos a nuestro directorio "/src/Entity/ServerPgsql"
Solo necesitamos modificar el servicio y la definición de la entidad, ¡y listo!

#/config/services.yaml 
   admin.table1:
        class: App\Admin\Table1Admin
        arguments: [~, App\Entity\ServerPgsql\Table1, App\Controller\Table1AdminController]
        tags:
            - { name: sonata.admin, manager_type: orm, group: admin, label: Table1 }
        public: true

<?php

namespace App\Entity\ServerPgsql;

use Doctrine\ORM\Mapping as ORM;

/**
 * Table1
 *
 * @ORM\Table(name="table1")
 * @ORM\Entity
 */
class Table1
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="SEQUENCE")
     * @ORM\SequenceGenerator(sequenceName="table1_id_seq", allocationSize=1, initialValue=1)
     */
    private $id;

    /**
     * @var string|null
     *
     * @ORM\Column(name="var1", type="string", length=250, nullable=true)
     */
    private $var1;

    /**
     * @var json|null
     *
     * @ORM\Column(name="var2", type="json", nullable=true)
     */
    private $var2;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getVar1(): ?string
    {
        return $this->var1;
    }

    public function setVar1(?string $var1): self
    {
        $this->var1 = $var1;

        return $this;
    }

    public function getVar2(): ?array
    {
        return $this->var2;
    }

    public function setVar2(?array $var2): self
    {
        $this->var2 = $var2;

        return $this;
    }


}

image-5