2011-03-25 15 views
7


Me gustaría extender el comportamiento de i18n, para que se una automáticamente a la tabla de traducción, en cualquier tipo de consulta (DQL, relations, getTable).
Además, necesita definir el parámetro de idioma predeterminado, de modo que cuando realizo una consulta sin el conjunto de idiomas, vuelve al idioma predeterminado.
Nota: Estoy buscando un comportamiento generalizado, por lo que se aplica a todos los objetos del modelo i18n, no para escribir y anular para cada una de las clases.Doctrine 1.2 auto-join i18n?

Aquí se muestra un ejemplo:
mesa product -> Identificación, category_id, precio ...
mesa product_translation -> Identificación, lang, nombre, descripción ...

Con la solución actual cuando lo haga algo como esto: Doctrine_Core::getTable('Product')->findAll(), obtiene todos los productos sin unir las traducciones.
Así, en el controlador de E tienen a valle bucle de todos los registros y volver a aplicar valores traducidos, con $product->name = $product->Translation['en']->name

me gustaría algo como esto:

  • Doctrine_Core::getTable('Product')->findAll() debe obtener los valores acumulados a lang = 'es '
  • Doctrine_Core::getTable('Product)->findAll('en') mismo que el anterior
  • también debe trabajar con las relaciones, así que por ejemplo si tengo un usuario clase que tiene muchos productos $user->Products debe devolver una colección con traducciones incluidas.
  • también algo así como $user->Products('en') debe devolver la colección para otros idiomas (no predeterminados)
  • funciones Magic también estaría bien (si es posible) ... algo así como Doctrine_Core::getTable('Product')->getByCategoryAndLang(1,'en')

¿Alguien puede ayudar? Estoy mirando plantillas y comportamientos, creo que ese es el camino a seguir, pero no tengo ni idea de cómo implementar esto

EDIT: Veo que no hay mucho interés en esto, así que déjame intentarlo con un pregunta más simple ¿Cómo se obtienen generalmente los campos i18n a través de las relaciones? Por ejemplo, ¿cómo puedo llamar al $user->Products y obtener los productos con traducciones cargadas?

Respuesta

1

Creo que no necesita extender el comportamiento estándar de Doctrine a menos que desee que esto sea completamente automático. Pero aún así usted puede tratar de hacer esto como nosotros - se utiliza un DAO (Data Access Object) que nos devuelve el hormigón entidad Doctrina (representación de tablas de Doctrine):

\DAO::get('Some\Namespace\Classname') 

donde Classname representa tabla descrita por el modelo de clases PHP . Nuestra clase DAO crea la instancia de Classname que está encapsulada en proxy (ver Patrones de diseño).

Más allá del modelo de clase de tabla, creamos otra clase para esta tabla que se encuentra sobre el modelo de tabla y que se manipula con este modelo. Dentro de esta clase, escribimos métodos como getProducts($args), getProduct($id), getProductsByCategory($catId), etc.

Creo que esto es lo que está buscando ...

En el método getProducts($args) A continuación, puede aplicar ->leftJoin() dentro DQL que se unirá a la mesa de traducciones dada por $lang identificador en $args parámetro. Ejemplo simple (no probado):

class Products extends \DAO { 
    public function save($item) { 
     $item->save(); 
    } 

    public function getProducts($args = array()) { 
     $order = array('p.id'); 

     $result = \Doctrine_Query::create() 
      ->from('Some\Namespace\Product p') 
      ->where('1 = 1'); 

     if(!empty($args['lang'])) { 
      $result = $result->leftJoin('Some\Namespace\ProductTranslation pt ON pt.product_id = p.id AND pt.language = ?', $args['lang']); 
     } 

     $result = $result->orderBy($order); 

     $result = $result->execute(); 

     return $result; 
    } 
} 

Entonces llamando

$products = DAO::get('Some\Namespace\Product')->getProducts(array('lang' => 1)); 

Se puede obtener todos los productos con traducciones inglesas cargadas ...

No es tanto automaticated y hay que escriba su propia clase DAO para cada modelo, pero es un buen enfoque ya que tiene diferente clase de definición de datos (modelo) y clase de manipulación de datos (controlador) que necesita para la arquitectura de aplicación orientada a objetos MVC/MVP ...

+0

Gracias, pero lo que está sugiriendo podría hacerse sin el DAO. Simplemente declare la clase ProductTable y agregue los métodos getXy que hacen la unión con Translation. De todos modos no resuelve el problema, porque todavía no puedo acceder a esos campos con $ product-> name, pero $ product-> Translation ['en'] -> name – ZolaKt

+0

No puedes acceder a la propiedad 'name' directamente a través de' modelo de producto ya que no se describe en este modelo (y no está presente en la tabla db). Con mi método, obtiene todas las columnas en un objeto (dentro de Doctrine_Collection) y para UNA traducción concreta. Así que recorriendo '$ products = DAO :: get ('Some \ Namespace \ Product') -> getProducts (array ('lang' => 1));' de esta manera 'foreach ($ products as $ product) {. ..} 'Usted ** puede ** En mi humilde opinión,' $ product-> name'. ¿No puedes? – shadyyx

+0

Hmm ... No creo que todavía pueda acceder, como dijo que no se describe en modal. Lo que podría hacer es hidratarlo como matriz y reorganizar los resultados (eliminar la traducción y propagar el nombre de un nivel). Esto es lo que estoy usando ahora. Pero aún así, no puedo ver ninguna diferencia en su método en comparación con los métodos de definición normales en las clases de tabla – ZolaKt