操作
Bug(バグ) #1264
完了プロフィール項目の日付やテキストの最小値を最大値より大きくして設定できてしまう
開始日:
2010-04-05
期日:
進捗率:
100%
予定工数:
3.6 で発生するか:
3.8 で発生するか:
説明
備考¶
このチケットは #940 のBPとして作成されたものですが、対応時点に混乱があり、 #930 で潜在的に生じていた不具合 #1595 の修正が含まれないままこの修正が行われています。
このチケットを #940 のBPとして扱うべきではないと判断して、トラッカーをバグとして、3.2系のみに対応したこととします。
現象¶
プロフィール項目の登録/編集画面にある、
フォームタイプのテキストと日付にある最小値/最大値の設定で、最小値>最大値という設定ができてしまう。エラー表示もされない。
再現方法¶
例:日付の場合- 「pc_backend.php/profile/edit」を開く
- プルダウンから「自分で入力する」を選択する
- フォームタイプで「日付」を選択する
- 最小値「2010/04/07」と最大値に「2010/04/05」と入力し、追加ボタンを押す
- 設定できてしまう。
最小値、最大値をstrotime()が解釈できる値でも同じように最小値>最大値の設定が出来ます。
再現バージョン¶
- OpenPNE3.5.x
- OpenPNE3.4.x
- OpenPNE3.2.x
- OpenPNE3.0.x
修正内容¶
Itsuro Tajima さんが14年以上前に更新
- ステータス を New(新規) から Accepted(着手) に変更
- 担当者 を Itsuro Tajima にセット
Minoru Takai さんが14年以上前に更新
- ステータス を Accepted(着手) から Pending Review(レビュー待ち) に変更
- 進捗率 を 0 から 50 に変更
更新履歴 928b5e8d148495ba2024d869b23551917e3dd545 で適用されました。
Rimpei Ogawa さんが14年以上前に更新
- ステータス を Pending Review(レビュー待ち) から Pending Testing(テスト待ち) に変更
- 進捗率 を 50 から 70 に変更
Mutsumi Imamura さんが14年以上前に更新
- ステータス を Pending Testing(テスト待ち) から Rejected(差し戻し) に変更
- 進捗率 を 70 から 50 に変更
確認しました。
最小値・最大値に0000/00/00を入力することができてしまいます。
0000/00/00を設定した状態でメンバー側で日付プロフィールを設定するとInternal Server Errorが発生することも確認しました。
本件に似たチケットがいくつかありますが、実装者と相談しこのチケットで差し戻すことにしました。
Minoru Takai さんが14年以上前に更新
- ステータス を Accepted(着手) から Pending Review(レビュー待ち) に変更
更新履歴 1d87087ceebc5e23170bb968ed337aed771e50f6 で適用されました。
Rimpei Ogawa さんが14年以上前に更新
- ステータス を Pending Review(レビュー待ち) から Pending Testing(テスト待ち) に変更
- 進捗率 を 50 から 70 に変更
Mutsumi Imamura さんが14年以上前に更新
- ステータス を Pending Testing(テスト待ち) から Fixed(完了) に変更
- 進捗率 を 70 から 100 に変更
確認しました。テストOKです。
Minoru Takai さんが14年以上前に更新
元チケットではエラーメッセージに含まれる日付フォーマットの修正も行いますが、3.2.7 に関してはリリースが迫っているため note-7 までの修正内容に留めておきます。
Minoru Takai さんが13年以上前に更新
このチケットでの対応内容を示しておきます(親チケットは完了しておらず、通常のBP対応とは異なっています)。
修正内容¶
- apps/pc_backend/modules/profile/templates/editSuccess.php
<ul> -<li><?php echo __('Please input in format: %format% . For example: %example%', array('%format%' => 'YYYY/MM/DD HH:MM:SS', '%example%' => '2009/01/01 23:59:21')) ?></li> +<li><?php echo __('Please input in format: %format%. For example: %example%', array('%format%' => 'YYYY/MM/DD', '%example%' => '2010/07/18, 0001/01/01')) ?></li> <li><?php echo __('Besides, you can use any particular string that can be interpreted by strtotime() function of PHP.') ?></li> </ul>
- 文言が翻訳されていない記述ミスを修正、日付の記述例を datetime から date に変更。
- lib/form/doctrine/ProfileForm.class.php
public function bind($params) { - if ($params['form_type'] === 'input' || $params['form_type'] === 'textarea') + if ('input' === $params['form_type'] || 'textarea' === $params['form_type']) (*1) コーディング規約に反する記述を修正 { - $validator = new sfValidatorInteger(array('required' => false)); - $this->setValidator('value_min', $validator); - $validator = new sfValidatorInteger(array('required' => false)); - $this->setValidator('value_max', $validator); + $validatorArgs = array( + 'required' => false, + 'trim' => true, + ); + $validatorMin = new sfValidatorInteger($validatorArgs); + $validatorMax = new sfValidatorInteger($validatorArgs); + if ('integer' !== $params['value_type']) + { + $validatorMin->setOption('min', 0); + $validatorMax->setOption('min', 1); + } (*2) 文字数制限の場合に最小値(min=0, max=1)を指定 + + $this->setValidator('value_min', $validatorMin); + $this->setValidator('value_max', $validatorMax); } - elseif ($params['form_type'] === 'date') + elseif ('date' === $params['form_type']) (*1) コーディング規約に反する記述を修正 { - $validator = new opValidatorDate(array('required' => false)); - $this->setValidator('value_min', $validator); - $validator = new opValidatorDate(array('required' => false)); - $this->setValidator('value_max', $validator); + $validatorArgs = array( + 'required' => false, + 'trim' => true, + 'with_time' => true, + 'datetime_output' => 'Y/m/d', + 'min' => '0001/01/01', + ); (*3) 日付の場合は、 Y/m/d 表記で保存し、0年などを入力できないように指定 + $validatorMin = new opValidatorDate($validatorArgs); + $validatorMax = new opValidatorDate($validatorArgs); + + $this->setValidator('value_min', $validatorMin); + $this->setValidator('value_max', $validatorMax); } elseif ($params['value_min'] || $params['value_max']) { throw new sfValidatorError($validator, 'invalid'); } + $this->validatorSchema->setPostValidator(new sfValidatorCallback( + array('callback' => array($this, 'compareMinAndMax')), + array('invalid' => 'Value must be less than or equal to Minimum value.') + )); + (*4) 日付の入力値が必ず yyyy/mm/dd と変換されることを前提に、 min と max の日付の大小を比較 return parent::bind($params); } + public function compareMinAndMax(sfValidatorBase $validator, $params) + { + $value_min = $params['value_min']; + $value_max = $params['value_max']; + if (!is_null($value_min) && !is_null($value_max)) + { + if ('date' !== $params['form_type']) + { + $value_min = (int)$value_min; + $value_max = (int)$value_max; + } + if ($value_min > $value_max) + { + throw new sfValidatorErrorSchema($validator, array('value_max' => new sfValidatorError($validator, 'invalid'))); + } + } + return $params; + } +
- i18n/messages.ja.xml
+ <trans-unit id=""> + <source>"%value%" must be at least %min%.</source> + <target>%min%以上でなければなりません。</target> + </trans-unit> + <trans-unit id=""> + <source>"%value%" must be at most %max%.</source> + <target>%max%以下でなければなりません。</target> + </trans-unit> + <trans-unit id=""> + <source>Value must be less than or equal to Minimum value.</source> + <target>最小値以下でなければなりません。</target> + </trans-unit>
- 比較に関する翻訳を追加。
備考¶
- #1147 (BP from #930) で、可能なはずの入力ができなくなっている問題 #1595 が生じていたことを知らずに、それを仕様だと思ってこのチケットで修正が行われている。
- 上記修正は、本来あるべき仕様とは異なる仕様における対応内容として扱われるべきである( 3.2 で可能なことが 3.4 以降で不可能になっている可能性がある)
- 本来あるべき仕様では、日付の min, max の大小比較は常にできない可能性がある( #940 参照)
- 以下の文言は意味的に間違っている(「最小値以下(less than)」は「最小値以上(greater than)」の誤り)
+ <source>Value must be less than or equal to Minimum value.</source> + <target>最小値以下でなければなりません。</target>
- 以下の文言は意味的に間違っている(「最小値以下(less than)」は「最小値以上(greater than)」の誤り)
操作