Doctrine 1.2 自动加入 i18n?
Posted
技术标签:
【中文标题】Doctrine 1.2 自动加入 i18n?【英文标题】:Doctrine 1.2 auto-join i18n? 【发布时间】:2011-03-25 17:14:19 【问题描述】:我想扩展 i18n 行为,以便它在任何类型的查询(DQL、关系、getTable)上自动加入转换表。 此外,它需要定义默认语言参数,所以当我在没有设置语言的情况下进行查询时,它会退回到默认语言。 注意:我正在寻找一种通用行为,因此它适用于所有 i18n 模型对象,而不是为每个类编写和覆盖。
这是一个例子:
表product
-> id、category_id、价格...
表product_translation
-> id、语言、名称、描述...
当我做这样的事情时,使用当前的解决方案:Doctrine_Core::getTable('Product')->findAll()
,它可以在不加入翻译的情况下获得所有产品。
所以在控制器中我必须循环遍历所有记录并重新应用翻译值,$product->name = $product->Translation['en']->name
我想要这样的东西:
Doctrine_Core::getTable('Product')->findAll()
它应该得到 lang='en' 的连接值
Doctrine_Core::getTable('Product)->findAll('en')
同上
它也应该适用于关系,例如,如果我有一个类 User 有很多产品 $user->Products
它应该返回一个包含翻译的集合。
类似$user->Products('en')
的东西也应该返回其他(非默认)语言的集合
魔术函数也不错(如果可能的话)...类似于Doctrine_Core::getTable('Product')->getByCategoryAndLang(1,'en')
有人可以帮忙吗?我正在查看模板和行为,我认为这是要走的路,但不知道如何实现这一点
编辑:我发现对此没什么兴趣,所以让我尝试一个更简单的问题。您通常如何通过关系获得 i18n 字段。例如,我如何致电$user->Products
并获取已加载翻译的产品?
【问题讨论】:
【参考方案1】:我认为你不需要扩展标准的 Doctrine 行为,除非你想要这个完全自动化。但是您仍然可以像我们一样尝试这样做 - 我们使用 DAO(数据访问对象)返回具体的 Doctrine 实体(Doctrine 表表示):
\DAO::get('Some\Namespace\Classname')
其中Classname
代表php 类模型描述的表。我们的 DAO 类创建了 Classname
的实例,该实例封装在 proxy
中(请参阅设计模式)。
除了表类模型,我们为这个表创建了另一个类,它位于表模型之上并使用这个模型进行操作。在这个类中,我们编写了 getProducts($args)
、getProduct($id)
、getProductsByCategory($catId)
等方法。
我认为这就是你要找的……
在方法getProducts($args)
中,您可以在DQL 中实现->leftJoin()
,它将通过$args
参数中给定的$lang
标识符加入翻译表。简单示例(未测试):
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;
然后通过调用
$products = DAO::get('Some\Namespace\Product')->getProducts(array('lang' => 1));
您获得所有已加载英文翻译的产品...
它不是那么自动化,您必须为每个模型编写自己的 DAO 类,但这是一种很好的方法,因为您有 MVC/MVP 对象所需的不同数据定义类(模型)和数据操作类(控制器)面向应用架构...
【讨论】:
谢谢,但您的建议可以在没有 DAO 的情况下完成。只需声明 ProductTable 类,并添加与 Translation 进行连接的 getXy 方法。无论如何它并没有解决问题,因为我仍然无法使用 $product->name 访问这些字段,但是 $product->Translation['en']->name 您无法通过product
模型访问name
属性,因为此模型中没有描述(也不存在于 db 表中)。使用我的方法,您可以在一个对象中(在 Doctrine_Collection 中)获得所有列 - 并进行一次具体翻译。所以循环通过$products = DAO::get('Some\Namespace\Product')->getProducts(array('lang' => 1));
foreach($products as $product) ...
你可以恕我直言访问$product->name
。你不能吗?
嗯...我不认为你仍然可以访问它,就像你说它没有在模态中描述。我能做的是将它作为数组水化,然后重新排列结果(删除翻译,并将名称向上传播一级)。这就是我现在正在使用的。但是,与 Table 类中的普通定义方法相比,我看不出你的方法有什么不同以上是关于Doctrine 1.2 自动加入 i18n?的主要内容,如果未能解决你的问题,请参考以下文章