Notice: Undefined index: month in moodle\lib\form\dateselector.php

Notice: Undefined index: month in moodle\lib\form\dateselector.php

- Tatsuya Shirai の投稿
返信数: 2

 実害は全く無いのですが,気持ちが悪いので報告します.

 サイト管理ブロックのユーザ,アカウント,ユーザリストの表示で,何らかの検索条件を入力して検索を開始すると,Notice: Undefined index month in ... という警告が大量に表示されます.ただし,この警告はPHPの警告の出力をOnにしていないと表示されません.
 この警告が発生するメカニズムは単純なものです.MoodleQuickFormで日付関係のフォームを自動生成します.たとえばログイン日時や最終アクセス日時などの日時系のプルダウンメニュー式入力フォームです(”拡張要素を表示する”をクリックすると表示されます).この年・月・日のそれぞれのプルダウンメニューを自動生成する際に,年や日はプルダウンメニューの各要素の値(表示値ではなく,選択された時にセットされる値です)は,"2010", "2009", "2008"であったり,"1", "2", "3"であったりします.月も同様にuserdate()関数に引数"%B"を付けて"01", "02", "03"と二文字の文字列で用意されます.実はここに落とし穴.実は年や日はintの数字です.でも,月だけは二文字の文字列です.

 プルダウンメニューが用意された後に,初期値をセットします.プルダウンメニューの何個目の項目が選ばれた状態にあるのかをしていする訳なのですが,このときに初期値として現在の日付を元にして年,月,日,それぞれ何項目目が選ばれているのかをsetValue()するのですが....ここで現在の日付を与えるときに,1, 2, 3, 4,..., 12といった整数を与えてしまっています.無いのです,リストの中に.なにせりストの中身は"01", "02", "03", "04"といった文字列ですから3と一致する項目を発見できません.ここからは予想です.一致しないにも関わらず,現在は3月ですので初期値として"3月"が自動的に選択されています.3がリスト中に見当たらなかったので,3をarrayの項目ではなくキーと判断したか,あるいは3番目の項目と判断して"3月"を初期値として選んでいるのでしょう.ですので一見,問題はありませんし,このまま放置しても良い問題です.

 この問題を解決するには以下のように,現在の日付を元にして初期値をセットする際に,リストを作成したのと同じく"%B"引数を付けてusergetdate()を呼ぶようにすればOKです."%B"なしの場合は3(int)を返しますが,付ければ"03"(string(2))を返します.

 Tracker(MDL-21929)にも報告しました.

 修正箇所は以下の通り:

lib/form/dataselector.php

function onQuickFormEvent()
(Moodle1.9)以降のみ

                $requestvalue=$value;
                if ($value == 0) {
                    $value = time();
                }
                if (!is_array($value)) {
// (Debug032): サイト管理ブロックのユーザリストの表示においてインデックスmonthが存在しないという警告が多数表示されるバグ (2010/03/26)
// (Debug032): ここから修正
//
                  $currentdate = usergetdate($value);
                    $currentdate = usergetdate($value, "%B");
// (Debug032): ここまで修正
                    $value = array(
                        'day' => $currentdate['mday'],
                        'month' => $currentdate['mon'],
                        'year' => $currentdate['year']);
                    // If optional, default to off, unless a date was provided
                     if($this->_options['optional']) {
                        $value['off'] = ($requestvalue == 0) ? true : false;
                    }
                } else {
                    $value['off'] = (isset($value['off'])) ? true : false;
                }

添付 undefinedIndexMonth.jpg
Tatsuya Shirai への返信

Re: Notice: Undefined index: month in moodle\lib\form\dateselector.php

- Tatsuya Shirai の投稿

 ただ,実は前から少し気になっていたのですが,usergetdate()の実装を見て貰えれば分かるのですが,ちょっと変態な仕様がありますね.

 フォーラムなどの投稿日を見ていただくと分かるのですが,月は1,2,3,4,5,.., 12 なのに,日付は01, 02, 03, 04,...,31ですよね...

Tatsuya Shirai への返信

Re: Notice: Undefined index: month in moodle\lib\form\dateselector.php

- Tatsuya Shirai の投稿

 報告が遅れていました.
 上記私の修正方法はナンセンスで効果のない物でした.失礼しました.

 より正しい修正方法がHubert Chati氏により示されており,私もその方法について調査を行い,同意見となりました.ただ,yearとdayも(int)でキャスティングする必要はありませんので,それは副作用を最小にした方が良いと考えるのであれば止めた方が良いでしょう.

moodle/lib/form/dateselector.phpの function onQuickFormEvent()のcase 'updateValue'の中ほど.

                if (!is_array($value)) {
                    $currentdate = usergetdate($value);
                    $value = array(
                        'day' => $currentdate['mday'],
//                      'month' => $currentdate['mon'],
                        'month' => (int)$currentdate['mon'],
                        'year' => $currentdate['year']);
                    // If optional, default to off, unless a date was provided
                     if($this->_options['optional']) {
                        $value['off'] = ($requestvalue == 0) ? true : false;
                    }
                } else {