Bug(バグ) #4168
opI18N::__() のパラメータに語形変化の設定をしたSnsTermインスタンスを渡しても反映されない
100%
Description
Overview (概要)¶
SnsTerm の 複雑な使用例 に記載されている下記のようなコードが正しく動作せず、語形変化が適用されていない「friend」のまま出力される。
<?php echo __('%friend% are removed.', array('%friend%' => $op_term['friend']->pluralize()->fronting())); ?>
この問題は #1759 における 9b2f55d8 の修正以降から発生している。
これにより、opDiaryPlugin の日記作成画面を英語で表示した際に「My Friends」と表示されるべき箇所が「my friend」と表示される状態になっている。
Causes (原因)¶
前提として、SnsTerm は以下のような性質を持っている。
- SnsTerm インスタンスに設定した語形変化は
SnsTerm::__toString()
が呼ばれると初期状態に戻る$term = Doctrine_Core::getTable('SnsTerm')->get('my_friend'); $term->titleize(); var_dump((string)$term); // "My Friend" var_dump((string)$term); // "my friend"
- SnsTerm インスタンスは SnsTermTable クラス内でキャッシュされる
$term = Doctrine_Core::getTable('SnsTerm')->get('my_friend'); $term->titleize(); // $term と同一のインスタンスが返る $term2 = Doctrine_Core::getTable('SnsTerm')->get('my_friend'); var_dump((string)$term2); // "My Friend"
それを踏まえて、opI18N::__()
メソッドの動作を追うと以下のようになる。
// 以下のように呼ばれる。期待する出力は「Friends are removed.」
echo __('%friend% are removed.', array('%friend%' => $op_term['friend']->pluralize()->fronting()));
....
// lib/i18n/opI18N.class.php
public function __($string, $args = array(), $catalogue = 'messages')
{
if (empty($this->parsed[$string])) // 初回の呼び出しでは true になる
{
$this->parsed[$string] = array();
$matches = array();
preg_match_all('/%([a-zA-Z_]+)%/', $string, $matches); // 「%friend%」がヒットする
array_shift($matches);
foreach ($matches as $match)
{
foreach ($match as $v)
{
if ($this->terms[$v])
{
$term = $this->terms[$v]; // 性質 2 より、語形変化が適用されたままのインスタンスが返る
if ($this->titleize) // デフォルトで false
{
$term = $term->titleize();
}
$this->parsed[$string]['%'.$v.'%'] = (string)$term; // ここで返るのは「Friends」
}
}
}
}
$parsedString = $this->parsed[$string];
if (is_array($args))
{
foreach ($args as $k => $v)
{
if ($v instanceof SnsTerm)
{
$args[$k] = (string)$v; // 性質 1 より、ここで返るのは「friend」
}
}
$parsedString = array_merge($parsedString, $args); // 「Friends」が「friend」に上書きされる
}
// 「friend are removed.」が出力される (不具合)
return parent::__($string, $parsedString, $catalogue);
}
Way to fix (修正内容)¶
#1759 の修正を一旦取り消し、上記のような SnsTerm の不具合が生じないように #1759 の修正を再度行う。
Subtasks
Related issues
Associated revisions
allow passing null to opI18N::__() method (fixes #4168)
allow passing null to opI18N::__() method (fixes #4168)
(cherry picked from commit b6263b33698c73a09efd3a9602cc5725bc47a768)
History
#1 Updated by Youichi Kimura over 7 years ago
- Description updated (diff)
#2 Updated by Youichi Kimura over 7 years ago
- Related to Bug(バグ) #1759: occurs "warning" when second argument of the __() i18n translation method is non-array (i18nの翻訳メソッド__の第二引数に配列以外を渡した場合に warning が発生する) added
#3 Updated by Youichi Kimura over 7 years ago
- Description updated (diff)
- Status changed from New(新規) to Accepted(着手)
- Assignee set to Youichi Kimura
#4 Updated by Youichi Kimura over 7 years ago
- Status changed from Accepted(着手) to Pending Review(レビュー待ち)
- % Done changed from 0 to 50
下記 Pull Request にて修正しました
https://github.com/openpne/OpenPNE3/pull/451
#5 Updated by kaoru n over 7 years ago
- Status changed from Pending Review(レビュー待ち) to Rejected(差し戻し)
- Target version changed from OpenPNE 3.9.0-old to OpenPNE 3.9.0
対象バージョン変更により修正内容の確認が必要であるため差し戻します。
#6 Updated by Youichi Kimura about 7 years ago
- Status changed from Rejected(差し戻し) to Pending Review(レビュー待ち)
Pull Request の内容について old-master から master ブランチに rebase しました
https://github.com/openpne/OpenPNE3/pull/451
#7 Updated by kaoru n almost 7 years ago
- Status changed from Pending Review(レビュー待ち) to Pending Testing(テスト待ち)
- % Done changed from 50 to 70
レビューしました。問題ありません。
#9 Updated by kaoru n almost 7 years ago
- Status changed from Pending Testing(テスト待ち) to Fixed(完了)
- % Done changed from 70 to 100
マージしました