简体   繁体   中英

Propel and I18N: fallback to another locale if first is not found

I am currently working on a API allowing users to get some event messages on their devices. Users call my API specifying me their preferred locale (for instance fr_FR ).

On the back-office, administrators can choose the languages they want to support. Let's assume they choose English and Chinese. So, they do not support French language.

I am using the Propel I18N behavior to deal with all the translations. In my requests, I am currently doing:

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

It works correctly if I specify an existing locale. Yet, if the translation is not available, it returns null. Sounds logical.

My question is: can I fallback the user on a default locale (in this case, en_US ) if the provided locale is not planned by an administrator? If yes, how can I proceed?

I thought to send a prior request to check if the locale exists. But I do not think it is a good way for performances reasons (especially for an API).

Any idea?

According to the documentation , there is not such a fallback in Propel.

What you can try, is the combination of setLocale and joinWithI18N . Something like:

$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
  }
}

I haven't tested this code but it seems to be a solution.

Also, have you tried to add two joinWithI18N (one for en_US & one for fr_FR ) to see how the query handle it?

Finally, I used the following code:

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);
}

It is not the best solution for performance reasons, but it is functionnal.

Try something like this

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM