I would like to extend the i18n behavior, so that it joins the translation table automatically, on any type of query (DQL, relations, getTable).
Additionally it needs to define the default language parameter, so when I do a query without the language set, it falls back to the the default language.
Note: I'm looking for a generalized behavior, so that is applies to all i18n model objects, not to write and override for each of the classes.
Here is an example:
table product
-> id, category_id, price...
table product_translation
-> id, lang, name, description...
With the current solution when I do something like this: Doctrine_Core::getTable('Product')->findAll()
, it gets all the products without joining the translations.
So in the controller I have to loop trough all the records and reapply translated values, with $product->name = $product->Translation['en']->name
I would like something like this:
Doctrine_Core::getTable('Product')->findAll()
it should get the joined values for lang='en'Doctrine_Core::getTable('Product)->findAll('en')
same as above$user->Products
it should return a collection with translations included.$user->Products('en')
should return the collection for other (non-default) languagesDoctrine_Core::getTable('Product')->getByCategoryAndLang(1,'en')
Can anyone help? I'm looking at templates and behaviors, I think that is the way to go, but have no clue how to implement this
EDIT: I see there is not much interest in this, so let me try with a simpler question. How do you usually get i18n fields via relations. For instance how can I call $user->Products
and get the products with loaded translations?
I think that You do not need to extend the standard Doctrine behavior unless You want this fully automatic. But still You can try to do this like we do - we use a DAO (Data Access Object) that returns us concrete Doctrine entity (Doctrine table representation):
\DAO::get('Some\Namespace\Classname')
where Classname
stands for table described by PHP class model. Our DAO class creates the instance of Classname
that is encapsulated into proxy
(see Design Patterns).
Beyond table class model we create another class for this table that stands above the table model and manipulates with this model. Within this class we write methods like getProducts($args)
, getProduct($id)
, getProductsByCategory($catId)
etc.
I think that this is what You are looking for...
In method getProducts($args)
You can then implement ->leftJoin()
within DQL that will join the translations table by given $lang
identificator in $args
parameter. Simple example (not tested):
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;
}
}
Then by calling
$products = DAO::get('Some\Namespace\Product')->getProducts(array('lang' => 1));
You obtain all the products with english translations loaded...
It is not so much automaticated and You have to write Your own DAO class for every model but it is good approach as You have different data definition class (model) and data manipulation class (controller) that needed for MVC/MVP object oriented application architecture...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With