0

私は現在、ユーザーがデバイスでいくつかのイベントメッセージを取得できるようにするAPIに取り組んでいます。ユーザーは自分のAPIを呼び出して、好みのロケールを指定します(たとえばfr_FR)。

バックオフィスでは、管理者はサポートする言語を選択できます。彼らが英語と中国語を選んだとしましょう。したがって、彼らはフランス語をサポートしていません。

私はすべての翻訳を処理するためにPropelI18Nの動作を使用しています。私のリクエストでは、現在次のことを行っています。

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

既存のロケールを指定すると正しく機能します。ただし、翻訳が利用できない場合は、nullを返します。論理的に聞こえます。

en_US私の質問は、提供されたロケールが管理者によって計画されていない場合、デフォルトのロケール(この場合)でユーザーをフォールバックできますか?はいの場合、どうすれば続行できますか?

ロケールが存在するかどうかを確認するために、事前のリクエストを送信することを考えました。しかし、パフォーマンス上の理由から(特にAPIの場合)、これは良い方法ではないと思います。

何か案が?

4

3 に答える 3

1

ドキュメントによると、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
  }
}

私はこのコードをテストしていませんが、それは解決策のようです。

また、クエリがどのように処理するかを確認するために、2つjoinWithI18N(1つはfor、en_USもう1つはfor )を追加しようとしましたか?fr_FR

于 2012-12-06T13:05:52.767 に答える
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);
}

これはパフォーマンス上の理由から最適なソリューションではありませんが、機能的です。

于 2012-12-13T13:25:41.930 に答える
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;
}
于 2012-12-22T16:19:56.773 に答える