プロジェクト

全般

プロフィール

Backport(バックポート) #4043

完了

Bug(バグ) #4000: MemberConfigFormのIsUnique制約に対するエラーメッセージが適切に出力されていない

MemberConfigFormのIsUnique制約に対するエラーメッセージが適切に出力されていない

isao sano さんが約8年前に追加. 6年以上前に更新.

ステータス:
Fixed(完了)
優先度:
Normal(通常)
担当者:
対象バージョン:
開始日:
2016-11-15
期日:
進捗率:

100%

予定工数:

説明

現象

「PC メールアドレス設定」(/member/config?category=pcAddress) で、変更後のメールアドレスが他のメンバーとメードアドレスが重複する場合に「Invalid pc_address.」というエラーメッセージが表示される。

原因

当初 #3736 ではこの不具合を英日の翻訳漏れとして扱っていたが、実際には #1069 で追加したエラーメッセージが「Invalid %name%.」であったのに対して翻訳は「Invalid %name%.」ではなく「Invalid mobile_address.」に対して行われていたことに起因する問題であった。

source:lib/form/doctrine/MemberConfigForm.class.php@43190aa1#L232:

    throw new sfValidatorError($validator, 'Invalid %name%.', array('name' => $name));

source:i18n/messages.ja.xml@43190aa1#L85

      <trans-unit id="">
        <source>Invalid mobile_address.</source>
        <target>メールアドレスが無効です。</target>
      </trans-unit>

このことで mobile_address 以外の IsUnique 制約を使用する全ての設定項目に対しては未翻訳のエラーメッセージが出力される状態となっていた。

また、この問題は「Invalid %name%.」に対する翻訳を追加するだけでは解決しない(「Invalid pc_address.」と表示されるまま変わらない)。
そもそも sfValidatorError::__construct($validator, $code, $arguments) の第 2 引数はエラーメッセージそのものを渡すのではなくバリデーター内部で識別するエラーコードを渡すものであり、今まで Invalid pc_address. のようなエラーメッセージが表示されていたのはエラーコードに対応するメッセージが存在しなかったためである。「%name%」のようなトークンを含むテキストに対して opI18n クラスによるローカライゼーションが正しく機能するためには、例えば以下のように適切な用法に書き換える必要がある。

  public function setMemberConfigWidget($name)
  {
....
    if (!empty($config['IsUnique']))
    {
      $uniqueValidator = new sfValidatorCallback(array(
        'callback'    => array($this, 'isUnique'),
        'arguments'   => array('name' => $name),
        'empty_value' => $this->validatorSchema[$name]->getOption('empty_value'),
      )); 

      $uniqueValidator->addMessage('duplicate', 'Invalid %name%.');
....
  }

  public function isUnique($validator, $value, $arguments = array())
  {
....
    throw new sfValidatorError($validator, 'duplicate', array('name' => $name));
  }

ここまで修正してようやく「Invalid %name%」に対して翻訳文が出力される状態になる。

これらの経緯をまとめると、下記の問題点が積み重なった結果として冒頭の「現象」が現れたといえる。

  • 独自のエラーメッセージを追加するために sfValidatorBase::addMessage() を使用せず sfValidatorErorr::__construct() の引数 $code に直接エラーメッセージを指定していた
  • 上記が原因でローカライゼーションが正しく機能せず「Invalid %name%.」に対する翻訳が行えなかったため、やむなく「Invalid mobile_address.」に対して訳文を追加していた(と思われる)
  • mobile_address 以外の IsUnique 制約を使用する member_config の設定項目については、訳文が存在しないため原文のままエラーメッセージが出力される状態となった

修正内容

MemberConfigForm 内でエラーメッセージを記述している箇所を上記の sfValidatorBase::addMessage() を使用した用法に書き換えた上で、下記の翻訳文を追加する。

      <trans-unit id="">
        <source>Invalid %name%.</source>
        <target>不正な %name% です。</target>
      </trans-unit>

また、この翻訳文の改善について #3999 にて扱っており、修正の際にはコンフリクトする可能性がある点を留意する必要がある。


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

関連している OpenPNE 3 - Backport(バックポート) #2571: メールアドレス設定など、確認欄がある場合のエラー表示が適切ではないFixed(完了)isao sano2011-10-14

操作

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