Propel和I18N:如果没有找到,则回退到另一个区域设置

时间:2012-12-06 11:58:42

标签: php internationalization locale propel

我目前正在开发一个API,允许用户在他们的设备上获取一些事件消息。用户调用我的API指定他们的首选语言环境(例如fr_FR)。

在后台,管理员可以选择他们想要支持的语言。我们假设他们选择英语和中文。所以,他们不支持法语。

我正在使用Propel I18N行为来处理所有翻译。在我的要求中,我目前正在做:

SystemMessageQuery::create()
    ->joinWithI18N('fr_FR')
    ->findOne();

如果我指定现有的语言环境,它可以正常工作。但是,如果翻译不可用,则返回null。听起来合乎逻辑。

我的问题是:如果管理员没有规划提供的区域设置,我可以使用默认区域设置(在本例中为en_US)回退用户吗?如果是,我该怎么办?

我想发送一个先前的请求来检查区域设置是否存在。但我不认为这是出于性能原因的好方法(特别是对于API)。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

根据the documentation,Propel没有这种后退。

您可以尝试的是setLocalejoinWithI18N的组合。类似的东西:

$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&amp;一个用于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;
}