Bug(バグ) #3209
完了携帯版の「携帯メールアドレス設定」で入力フォームが表示されない
0%
説明
概要¶
携帯版の「携帯メールアドレス設定」で入力フォームが表示されない
下記図のメニュー「携帯メールアドレス設定」を選択した後その次のページには携帯メールアドレス設定が表示されるはずが表示されない
本来は下記のように表示されるべきである.
確認環境¶
OpenPNE 3.6.5
原因¶
下記コード部で,「携帯メールアドレス設定」の場合に $form->count() の値が 1 となっており 7 行目のフォームが表示される動作が行われずに 13 行目のフォームフィールドが csrf_token 用のフォームのみが存在する場合に該当してしまうため表示が行われない.
これが 「携帯メールアドレス設定」の場合にのみ発生する原因はわかっていない.
apps/mobile_frontend/modules/member/templates/configSuccess.php
7 <?php if ($categoryName && 1 < $form->count()): // except CSRF token field ?> 8 <?php op_include_form('configForm', $form, array( 9 'url' => url_for('member/config?category='.$categoryName), 10 'align' => 'center', 11 'button' => __('Save') 12 )) ?> 13 <?php elseif ($categoryName && 1 === $form->count()) : ?> 14 <?php echo __('There is no available settings.'); ?> 15 <?php else: ?> 16 <?php echo __('Please select the item from the menu.'); ?> 17 <?php endif; ?>
ファイル
Yuya Watanabe さんが約12年前に更新
- 優先度 を Normal(通常) から High(高め) に変更
- 対象バージョン を OpenPNE 3.9.0-old にセット
- 3.8 で発生するか を Unknown (未調査) から Yes (はい) に変更
Rimpei Ogawa さんが約12年前に更新
原因について調べた結果を書きます。
発生条件¶
この問題は以下の条件をすべて満たす場合に発生します。
- mobile_frontend アプリケーション
- MemberConfig に対応するデータが存在しない
原因詳細¶
以下のような流れで問題が発生します。
- FormFieldSchema が _csrf_token のみの時点で初期化される【BaseForm::appendMobileInputMode()】
- WidgetSchema に MemberConfigWidget を登録する際に FormFieldSchema を破棄しない【MemberConfigForm::setMemberConfigWidget()】
- sfForm::setDefault() を呼ばない場合は FormFieldSchema が破棄されることなく Form の初期化が終了する
- sfForm::count() は FormFieldSchema を参照するため結果が 1 となる【テンプレート】
1. の appendMobileInputMode() が実行されるのは mobile_frontend アプリケーションのみなので、発生条件の一つになります。FormFieldSchema の初期化は foreach 部分で暗黙的に sfForm::offsetGet() が呼ばれることにより行われます。また、BaseForm::__construct() 実行後に widget 追加されることは想定されていないため、このチケットの問題の他に appendMobileInputMode() の効果が MemberConfigForm の widget には適用されないという別の問題があります。
2. は widget 登録時に sfForm::setWidget() を通さず WidgetSchema への直接登録のみで済ませているために、FormFieldSchema が破棄されません(sfForm::setWidget() は内部で sfForm::resetFormFields() を呼ぶことで破棄をする)。ここで setWidget() を呼ぶようにすれば問題は解消します。
--- a/lib/form/doctrine/MemberConfigForm.class.php +++ b/lib/form/doctrine/MemberConfigForm.class.php @@ -109,7 +109,7 @@ class MemberConfigForm extends BaseForm public function setMemberConfigWidget($name) { $config = $this->memberConfigSettings[$name]; - $this->widgetSchema[$name] = opFormItemGenerator::generateWidget($config); + $this->setWidget($name, opFormItemGenerator::generateWidget($config)); $this->widgetSchema->setLabel($name, $config['Caption']); $memberConfig = Doctrine::getTable('MemberConfig')->retrieveByNameAndMemberId($name, $this->member->getId()); if ($memberConfig) {
3. の sfForm::setDefault() は内部で sfForm::resetFormFields() を呼ぶため、FormFieldSchema を破棄してくれます。MemberConfig のデータが存在する場合はこの処理が呼ばれるので問題が発生しません。発生条件の一つです。ここに限らずどこかのタイミングで sfForm::resetFormFields() を呼ぶのも解決策になります。
Yuya Watanabe さんが約12年前に更新
setWidget() の中で resetFormFields() が呼ばれていることから, 更新時には FormFields のリセットが必要という意図が受け取られるので sfForm の外側で widget を更新しながら resetFormFields() を呼ぶようなコードは,意図に反した処理を行いながら無理矢理辻褄をあわせている感じがするので嫌です.また setDefault() についても意図してそういう実装になっているわけではなく偶然動いてるような気がするためこちらも嫌です.よって widget を更新するという意図を変更せずに FormFields を明示的にリセットするように記述されている setWidget() を用いるような方法を用いて修正を行います.
lib/vendor/symfony/lib/form/sfForm.class.php 664 public function setWidget($name, sfWidgetForm $widget) 665 { 666 $this->widgetSchema[$name] = $widget; 667 668 $this->resetFormFields(); 669 670 return $this; 671 }
Yuya Watanabe さんが約12年前に更新
- ステータス を Accepted(着手) から Pending Review(レビュー待ち) に変更
- 進捗率 を 0 から 50 に変更
更新履歴 023549e578cbbc5ca1df06c12256f6581faac3d4 で適用されました。
Rimpei Ogawa さんが約12年前に更新
- ステータス を Pending Review(レビュー待ち) から Pending Testing(テスト待ち) に変更
- 進捗率 を 50 から 70 に変更