プロジェクト

全般

プロフィール

Bug(バグ) #2490

完了

翻訳ファイルの優先順位がキャッシュ時に逆になっている

Maki Takahashi さんが約13年前に追加. 約9年前に更新.

ステータス:
Fixed(完了)
優先度:
High(高め)
担当者:
対象バージョン:
開始日:
2011-10-14
期日:
進捗率:

100%

予定工数:
3.6 で発生するか:
Unknown (未調査)
3.8 で発生するか:
Unknown (未調査)

説明

概要

i18n 翻訳用のメッセージファイルは複数ファイルで同じ語に対する翻訳を記述した場合、「モジュール → アプリケーション → 全体」の優先順に読み込まれる仕様であるが、翻訳ファイルのキャッシュを生成する過程の処理に誤りがあり、この優先順位が逆になってしまう問題がある。

これにより mobile_frontend 用の i18n ファイルに半角カタカナのエントリーを追加しているにもかかわらず、全角カタカナが表示されてしまうような現象が発生する。

なお、キャッシュファイルがない状態でアクセスした場合にはこの現象は発生しない。

詳細

opI18N::generateApplicationMessages() でキャッシュファイルを生成するが、この中で複数の i18n のメッセージファイルの内容をマージする処理で優先度の低いファイルの内容を優先してマージをしてしまっている。

opI18N::generateApplicationMessages() の引数 $dirs には優先度の高い順にディレクトリパスが格納された配列が渡されるが、foreach のループ内では後の値を前の値よりも優先させる形で array_merge() を使っているために本来の優先順位と逆の内容のキャッシュファイルが生成されていた。

修正前のコード:

  public function generateApplicationMessages($dirs)
  {
    $catalogues = array();
...
    foreach ($files as $file)
    {
...
      $data = $messageSource->loadData($file);

      $catalogues[$name] = array_merge($catalogues[$name], $data);
    }

確認バージョン

OpenPNE 3.7.0-dev (master)
OpenPNE 3.6.1 (stable-3.6.x)


関連するチケット 5 (0件未完了5件完了)

関連している opDiaryPlugin - Bug(バグ) #2284: 携帯版においてDiaryPluginに関連する文言のみの半角カタカナに対応していないFixed(完了)Maki Takahashi2011-07-21

操作
関連している OpenPNE 3 - Backport(バックポート) #2550: 翻訳ファイルの優先順位がキャッシュ時に逆になっているFixed(完了)Maki Takahashi2011-10-14

操作
関連している OpenPNE 3 - Bug(バグ) #1894: The translation is wrong when there are same string to files of the translation (複数の翻訳ファイルに同一の文言が存在した場合、間違った翻訳がされる)Fixed(完了)Masato Nagasawa2011-01-26

操作
関連している OpenPNE 3 - Bug(バグ) #2800: 翻訳ファイルの読み込みが誤った順序でおこなわれてしまい、たとえば、携帯版で「Login」が「ログイン」ではなく「ログイン」と翻訳されてしまうFixed(完了)Kousuke Ebihara2011-10-14

操作
関連している OpenPNE 3 - Backport(バックポート) #3119: 翻訳ファイルの優先順位がキャッシュ時に逆になっているFixed(完了)開 石切山2011-10-14

操作

Maki Takahashi さんが約13年前に更新

  • 説明 を更新 (差分)
  • ステータスNew(新規) から Accepted(着手) に変更
  • 担当者Maki Takahashi にセット

Maki Takahashi さんが約13年前に更新

  • ステータスAccepted(着手) から Pending Review(レビュー待ち) に変更
  • 進捗率0 から 50 に変更

更新履歴 7047ccf4ebcc6891319e783d1c10142e9d45b6e3 で適用されました。

Minoru Takai さんが約13年前に更新

  • 優先度Normal(通常) から High(高め) に変更

この問題の重要度についてコメントします。

これにより mobile_frontend 用の i18n ファイルに半角カタカナのエントリーを追加しているにもかかわらず、全角カタカナが表示されてしまうような現象が発生する。

チケットで示されている内容が正しいと仮定すると、 OpenPNE 側の実装に誤りがあるために、国際化の機構(i18n による機能)について、キャッシュが使われるときと使われないときで動作結果が異なり、上記の引用内容のような不具合を生じさせているということになります。

キャッシュが使われる場合に、翻訳ファイルが適切に(想定される順序で)適用されないことは、適切に翻訳ファイルを用意している場合であっても上記のような問題が起こることだけでなく、この問題の原因が分からない開発者が翻訳関連でこの問題に遭遇したときに不毛な調査を要してしまうことが懸念されます。

この問題は可及的速やかに対応すべきと考えます。これを示す意味でチケットの優先度を High に設定します。

Kousuke Ebihara さんがほぼ13年前に更新

  • ステータスPending Review(レビュー待ち) から Rejected(差し戻し) に変更
  • 3.6 で発生するかUnknown (未調査) にセット
  • 3.4 で発生するかUnknown (未調査) にセット

この修正により、たとえば携帯版ログイン画面において、「ログイン」と翻訳されていた文言が「ログイン」に置き換わってしまいます。

このチケットで修正された opI18N::generateApplicationMessages() の第一引数の $dir は、「優先度の高い順に i18n ディレクトリのパス文字列が格納された配列」ですので、修正内容自体は正しいように見えます。ですが、肝心の $dir の順序が間違っているために、この修正を適用することで、前述の「ログイン」のように誤った翻訳がなされる箇所が出てきてしまいます。

opI18N::generateApplicationMessages() に渡される引数は opApplicationConfiguration::getI18NDirs() により生成されたものです。したがって、この修正を適用するためには、併せて opApplicationConfiguration::getI18NDirs() も修正する必要があります。

opApplicationConfiguration::getI18NDirs() により生成される配列要素の順序は以下のようになります(太字は sfApplicationConfiguration::getI18NDirs() の生成した配列要素)。

0. [sf_root_dir]/i18n
1. plugins/op*Plugin/apps/[app_name]/i18n
2. plugins/op*Plugin/apps/[app_name]/modules/[module_name]/i18n
3. apps/[app_name]/modules/[module_name]/i18n
4. apps/[app_name]/i18n
5. plugins/*/modules/[module_name]/i18n
6. plugins/*/i18n

しかし、これは期待通りの結果ではありません。上述の結果を、期待通りの順番に並び替えたものが以下です。

2. plugins/op*Plugin/apps/[app_name]/modules/[module_name]/i18n
1. plugins/op*Plugin/apps/[app_name]/i18n
3. apps/[app_name]/modules/[module_name]/i18n
4. apps/[app_name]/i18n
0. [sf_root_dir]/i18n
5. plugins/*/modules/[module_name]/i18n
6. plugins/*/i18n

この並び順は以下のような考え方に基づいています。

  • OpenPNE 3 プラグインのディレクトリ( plugins/op*Plugin/ 以下)は、 OpenPNE 3 本体よりも優先される
  • OpenPNE 3 本体のディレクトリは、 symfony プラグインのディレクトリ( plugins/*/modulesplugins/*/i18n )よりも優先される?

これは、『symfony 1.4 による Web アプリケーション開発』(拙著/共著)の p399 に記載されている考え方に沿っています。以下に引用します。

このような symfony プラグインと OpenPNE プラグインとの差異は、 symfony プラグインが「symfony を拡張する」という役割を担っており、拡張された symfony を利用して開発を進めていくことを想定しているのに対し、 OpenPNE プラグインの場合は、「既に完成された symfony アプリケーションを拡張する」という役割を担っているというところから生じています。

ということで、これでよさそうに思いますが、「0. [sf_root_dir]/i18n 」の順番が妥当かどうかは若干怪しいところです(このディレクトリの立ち位置はいまひとつ明確でない気がしています)。

なので、 [sf_root_dir]/i18n に関してだけはとりあえずこの修正前の挙動を維持する形で、以下のような順序にすることもアリだと思います。ちなみに、この順序ならば sfApplicationConfiguration::getI18NDirs() の結果が利用できます。

2. plugins/op*Plugin/apps/[app_name]/modules/[module_name]/i18n
1. plugins/op*Plugin/apps/[app_name]/i18n
3. apps/[app_name]/modules/[module_name]/i18n
4. apps/[app_name]/i18n
5. plugins/*/modules/[module_name]/i18n
6. plugins/*/i18n
0. [sf_root_dir]/i18n

Maki Takahashi さんがほぼ13年前に更新

  • ステータスRejected(差し戻し) から Pending Review(レビュー待ち) に変更

更新履歴 cbab5cb65cdb2876bf02054ec0768df186e312b0 で適用されました。

Kousuke Ebihara さんがほぼ13年前に更新

  • ステータスPending Review(レビュー待ち) から Rejected(差し戻し) に変更

この修正により生成されることになる配列要素の順序は以下のようになります。

1. plugins/op*Plugin/apps/[app_name]/i18n
2. plugins/op*Plugin/apps/[app_name]/modules/[module_name]/i18n
3. apps/[app_name]/modules/[module_name]/i18n
4. apps/[app_name]/i18n
5. plugins/*/modules/[module_name]/i18n
6. plugins/*/i18n
0. [sf_root_dir]/i18n

これは http://redmine.openpne.jp/issues/2490#note-4 にて示した見解とは異なります(1 と 2 の順序が違う)。これは意図したものなのでしょうか。

モジュールに与えられた翻訳よりもアプリケーションに与えられた翻訳を優先する妥当な理由はないように思います。

Maki Takahashi さんがほぼ13年前に更新

  • ステータスRejected(差し戻し) から Pending Review(レビュー待ち) に変更

更新履歴 aef957686b79094fe51dd5fad3c5a3e9b144f59a で適用されました。

Maki Takahashi さんがほぼ13年前に更新

aef9576 にて前回の修正時に見落としていた1と2の順番を入れ替えました。申し訳ありません。

Kousuke Ebihara さんがほぼ13年前に更新

  • ステータスPending Review(レビュー待ち) から Pending Testing(テスト待ち) に変更
  • 進捗率50 から 70 に変更

Shouta Kashiwagi さんがほぼ13年前に更新

  • ステータスPending Testing(テスト待ち) から Fixed(完了) に変更
  • 進捗率70 から 100 に変更

テストOKです。

kaoru n さんが約9年前に更新

  • 3.8 で発生するかUnknown (未調査) にセット

他の形式にエクスポート: Atom PDF