我目前正在开发一个API,允许用户在他们的设备上获取一些事件消息。用户调用我的API指定他们的首选语言环境(例如fr_FR
)。
在后台,管理员可以选择他们想要支持的语言。我们假设他们选择英语和中文。所以,他们不支持法语。
我正在使用Propel I18N行为来处理所有翻译。在我的要求中,我目前正在做:
SystemMessageQuery::create()
->joinWithI18N('fr_FR')
->findOne();
如果我指定现有的语言环境,它可以正常工作。但是,如果翻译不可用,则返回null。听起来合乎逻辑。
我的问题是:如果管理员没有规划提供的区域设置,我可以使用默认区域设置(在本例中为en_US
)回退用户吗?如果是,我该怎么办?
我想发送一个先前的请求来检查区域设置是否存在。但我不认为这是出于性能原因的好方法(特别是对于API)。
有什么想法吗?
答案 0 :(得分:1)
根据the documentation,Propel没有这种后退。
您可以尝试的是setLocale
和joinWithI18N
的组合。类似的东西:
$default_locale = 'en_US';
$items = ItemQuery::create()
->joinWithI18n('fr_FR')
->find();
foreach ($items as $item)
{
echo $item->getPrice();
// test if name is translated
if (!$name = $item->getName())
{
// otherwise, try to get the translation with default locale
$item->setLocale($default_locale);
$name = $item->getName(); // one query to retrieve the English translation
}
}
我没有测试过这段代码,但它似乎是一个解决方案。
此外,您是否尝试添加两个joinWithI18N
(一个用于en_US
&一个用于fr_FR
)以查看查询如何处理它?</ p>
答案 1 :(得分:1)
最后,我使用了以下代码:
public function setLocale($locale = 'en_US', $fallbackEnabled = false)
{
if($fallbackEnabled) {
$localeExists = SystemMessageI18nQuery::create()
->filterByLocale($locale)
->filterById($this->getId())
->count();
if(!$localeExists) {
$locale = SystemMessageI18nQuery::create()
->filterById($this->getId())
->select('locale')
->findOne();
}
}
parent::setLocale($locale);
}
出于性能原因,它不是最佳解决方案,但它是功能性的。
答案 2 :(得分:0)
尝试这样的事情
public function joinWithI18nFallback($locale=null, $joinType = Criteria::LEFT_JOIN, $default_locale=null)
{
$languages = sfConfig::get('sf_languages');
if(null == $locale)
{
$locale = sfPropel::getDefaultCulture();
}
if(null == $default_locale)
{
$default_locale = sfPropel::getDefaultCulture();
}
$languages[] = $locale;
$languages[] = $default_locale;
$languages = array_unique($languages);
$FallbackQuery = CategoryQuery::create()
->leftJoin('CategoryI18n')
->addJoinCondition('CategoryI18n', "CategoryI18n.Culture IN ('".implode("','", $languages)."')" )
->withColumn('CategoryI18n.Culture', 'CultureDefault')
->addAscendingOrderByColumn("FIELD(category_i18n.culture, '".$locale."', '".implode("','", $languages)."' )")
->where("CategoryI18n.name != ''");
$this->addSelectQuery($FallbackQuery, 'Category')
->join('CategoryI18n', $joinType)
->addJoinCondition('CategoryI18n', 'CategoryI18n.Culture = Category.CultureDefault' )
->with('CategoryI18n')
->groupById();
$this->with['CategoryI18n']->setIsWithOneToMany(false);
return $this;
}