Doctrine 1.2 auto-join i18n?
Here is an example:
tableproduct
-> 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.
$product->name = $product->Translation['en']->name
开发者_如何学CI 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- It should also work with relations, so for instance if I have a class User which has many products
$user->Products
it should return a collection with translations included. - Also something like
$user->Products('en')
should return the collection for other (non-default) languages - Magic functions would also be nice (if possible)...something like
Doctrine_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...
精彩评论