Backport(バックポート) #2194
完了The translation is wrong when there are same string to files of the translation (複数の翻訳ファイルに同一の文言が存在した場合、間違った翻訳がされる)
100%
説明
Overview (現象)¶
再現手順¶
1. キャッシュをクリアする
symfony cc
2. トピック作成の項目「タイトル」と表示されている事を確認
http://exmaple.com/communityTopic/new/1
3. 再度トピック作成を表示すると「タイトル」が「名前」になっている
Causes (原因)¶
フォームの翻訳時に、他の箇所で読み込んだ翻訳ファイルのリストがクリアされていないことが原因。
現象例で示したトピック作成で「タイトル」が「名前」となる原因は、
アプリケーション登録ページで同一の文言「Name」を定義しているためである。
http://exmaple.com/connection/new
また、一度目に「タイトル」と正常に表示されたのは、
「symfony cc」した時点でキャッシュが作成されておらず、
この時「sfMessageSource_OpenPNECache」クラスではなく「sfMessageSource_OpenPNE」クラスが使用されたためである。
Way to fix (修正内容)¶
sfMessageSource_OpenPNECached::load() の呼び出し時に、
$this->messages に読み込んだ翻訳ファイルの内容をクリアしていないことが原因。
継承元の sfMessageSource::load() では以下のように初期化している。
lib/vendor/symfony/lib/i18n/sfMessageSource.class.php 157 function load($catalogue = 'messages') 158 { 159 $variants = $this->getCatalogueList($catalogue); 160 161 $this->messages = array(); 162
しかしこのままの実装でこの修正を行うと、
include() で毎回翻訳ファイルが読み込まれる問題があるため、
翻訳ファイルの内容をキャッシュする実装にするべきである。
sfMessageSource::load() では読み込んだ内容をキャッシュする機構がすでに備わっており、
そもそも sfMessageSource::load() をオーバーライドするのではなく、
sfMessageSource::load() 内で呼ばれるメソッドをオーバーライドして実装するべきではないか。
下記のような実装で修正したところ、正常な挙動となった。
public function getCatalogueList($catalogue) { $variants = explode('_', $this->culture); - $base = $this->source.DIRECTORY_SEPARATOR.$catalogue.$this->dataSeparator; + $base = $catalogue.$this->dataSeparator; return array( $base.$variants[0].$this->dataExt, $base.$this->culture.$this->dataExt, ); } - public function load($catalogue = 'messages') - { - $variants = $this->getCatalogueList($catalogue); - - foreach ($variants as $variant) - { - if (isset($this->messages[$variant])) - { - return true; - } - - if (is_file($variant)) - { - $this->messages[$variant] = include($variant); - - return true; - } - } - - return true; - } - public function save($catalogue = 'messages') { return true; @@ -65,4 +44,9 @@ class sfMessageSource_OpenPNECached extends sfMessageSource_File { return true; } + + public function &loadData($variant) + { + return include($variant); + } }
この修正によって、今まで翻訳されていた箇所が翻訳されなくなる部分があります。
これは今までの挙動が間違っていただけであり、適切な翻訳を追加して対応する必要があります。
今回の修正よって、独自のカテゴリを指定している箇所で影響が出ます。
確認した限り以下の箇所が翻訳されていませんでした。
* communityTopic/new/[id] * communityEvent/new/[id] Photo 1 → 写真 1 Photo 2 → 写真 2 Photo 3 → 写真 3