SonataAdminBundle con campos traducibles (extensiones de doctrina)


Tengo una tabla con todas las traducciones en una tabla "ext_translations".

La traducción funciona muy bien. El problema es ahora: quiero administrar esas traducciones a través de sonata-admin bundle.

Ya he encontrado una documentación, cómo obtener extensiones de doctrina de trabajo con sonata admin. Pero en mi caso tengo UNA tabla/entidad para todas mis traducciones (para múltiples entidades).

Así que según esta documentación: http://www.elao.com/blog/symfony-2/doctrine-2/how-to-manage-translations-for-your-object-using-sonataadminbundle.html ¿cuál debería ser mi atributo mappedBy (ver más abajo)?

Ext_translations tabla:

mysql> show columns from ext_translations;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | int(11)      | NO   | PRI | NULL    | auto_increment |
| locale       | varchar(8)   | NO   | MUL | NULL    |                |
| object_class | varchar(255) | NO   |     | NULL    |                |
| field        | varchar(32)  | NO   |     | NULL    |                |
| foreign_key  | varchar(64)  | NO   |     | NULL    |                |
| content      | longtext     | YES  |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+

Mapeado por:

   /**
     * @ORM\OneToMany(targetEntity="ProfileTranslation", mappedBy="object", cascade={"persist", "remove"})
     */
    protected $translations;

Por lo que he entendido el problema aquí: "Tengo una clave compuesta (objectclass (la entidad) + nombre (del atributo) + ForeignKey (id de la entidad)), entonces, ¿cómo debería el 'mappedBy' referirse a esto?

No quiero crear un extra clase para cada entidad traducible (como en el tutorial de arriba)

Author: PeeHaa, 2013-10-28

1 answers

Su situación es bastante compleja. Probablemente lo mejor podría ser si no utilizas ninguna anotación, sobrescribes la clase de repositorio, y construyes toda tu propia lógica.

Podemos intentar aprovechar la nueva habilidad desde la Doctrina 2.1 de crear Claves Compuestas Compuestas como Clave Primaria, como dijo Feras en su comentario.

Doctrina 2 soporta claves primarias compuestas de forma nativa. Teclas compuestas son un concepto de base de datos relacional muy potente y tomamos buen cuidado asegúrese La Doctrina 2 soporta la mayor parte de la clave primaria compuesta casos de uso. Para Doctrine 2.0 las claves compuestas de tipos de datos primitivos son compatible, para Doctrine 2.1 incluso las claves foráneas como claves primarias son apoyar.

En los documentos, tenemos un buen ejemplo de un caso de uso que es más o menos similar al tuyo:

Atributos dinámicos de una Entidad (por ejemplo Artículo). Cada Artículo tiene muchos atributos con clave primaria "article_id" y "attribute_name".

Puedes ver el ejemplo aquí: http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#use-case-1-dynamic-attributes

Pero como ese enfoque solo considera una entidad, tenemos que adaptarla a sus necesidades. Podemos seguir estos pasos:

  1. Crea una especie de vistas de tu ext_translations tabla

    CREATE VIEW profile_ext_translations
    AS 
    SELECT * 
    FROM ext_translations
    WHERE  object_class = 'Profile'
    
  2. Luego cree diferentes entidades, para esas vistas, por lo que tendría una entidad ProfileExtTranslations con una clave primaria compuesta, como sigue:

    **
    * @Entity
    */
    class ProfileExtTranslations
    {
    
      /**
      * @ORM\ManyToOne(targetEntity="Profile", inversedBy="translations")   
      * @ORM\JoinColumn(name="foreign_key", referencedColumnName="id", onDelete="CASCADE")*/
       private $profile;
    
     /** @Id @Column(type="string") */
     private $field;
    
     //Other fields and methods
    
    
    }
    
  3. Y ahora, el código de la entidad de Perfil, en el mappedBy de las traducciones, solo usa:

    /**
    * @ORM\OneToMany(targetEntity="ProfileExtTranslation", mappedBy="profile", cascade={"persist", "remove"})
    */
    protected $translations;
    

Y con esto y probablemente un poco de afinación, deberías tenerlo funcionando.

 2
Author: Carlos Robles,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-03 13:27:28