MoodleのFeedbackに質問タイプを追加してみる

#Feedbackモジュールの質問タイプ
MoodleのFeedbackモジュールには通常、以下のような質問が選択できる。

  - Captcha
  - ラベル
  - 多肢選択
  - 多肢選択（評定）
  - 情報
  - 改ページ
  - 数値回答
  - 短文回答
  - 長文回答

質問ではないものもあるが、ここに新しく質問タイプを追加したい。
さしあたってメールアドレスを入力させ、バリデーションを行う質問タイプ「メールアドレス」を作成することとする。

#追加手順
##既存の問題タイプからコピペする
短文回答（input type="text"）をベースとして作成するため、コピーする

```
# cd moodle/mod/feedback/item
# cp -ra textfield email
```

##適当に書き換える
サーバ側だけでメールアドレスとして正当かどうかのバリデーションをすると、マッチしなかった場合に、必須回答でない質問の場合には警告が表示されず空文字が記録されてしまう。それを回避するためにクライアント側でもバリデーションを行うように追加している。

```diff:diff&nbsp;textfield/lib.php&nbsp;email/lib.php
20,21c20,21
< class feedback_item_textfield extends feedback_item_base {
<     protected $type = "textfield";
---
> class feedback_item_email extends feedback_item_base {
>     protected $type = "email";
25c25
<         require_once('textfield_form.php');
---
>         require_once('email_form.php');
43,55d42
<         $size_and_length = explode('|', $item->presentation);
<
<         if (isset($size_and_length[0]) AND $size_and_length[0] >= 5) {
<             $itemsize = $size_and_length[0];
<         } else {
<             $itemsize = 30;
<         }
<
<         $itemlength = isset($size_and_length[1]) ? $size_and_length[1] : 255;
<
<         $item->itemsize = $itemsize;
<         $item->itemmaxlength = $itemlength;
<
70c57
<         $this->item_form = new feedback_textfield_form('edit_item.php', $customdata);
---
>         $this->item_form = new feedback_email_form('edit_item.php', $customdata);
95d81
<
122d107
<
125a111
>
181,186c167,173
<         list($size, $maxlength) = explode ("|", $item->presentation);
<         $form->add_form_element($item,
<                 ['text', $inputname, $name, ['maxlength' => $maxlength, 'size' => $size]]);
<         $form->set_element_type($inputname, PARAM_NOTAGS);
<
<         $form->add_element_rule($inputname, get_string('maximumchars', '', $maxlength), 'maxlength', $maxlength, 'client');
---
>         list($size) = explode ("|", $item->presentation);
>         $form->add_form_element(
>                 $item,
>                 ['text', $inputname, $name, ['maxlength' => 255, 'size' => $size]]
>             );
>         $form->set_element_type($inputname, PARAM_EMAIL);
>         $form->add_element_rule($inputname, get_string('invalidemail'), PARAM_EMAIL, null, 'client');
189,193d175
<     /**
<      * Converts the value from complete_form data to the string value that is stored in the db.
<      * @param mixed $value element from mod_feedback_complete_form::get_data() with the name $item->typ.'_'.$item->id
<      * @return string
<      */
195c177,179
<         return s($value);
---
>         $value = clean_param($value, PARAM_EMAIL);
>
>         return $value;
```

```php:email/email_form.php
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

require_once($CFG->dirroot.'/mod/feedback/item/feedback_item_form_class.php');

class feedback_email_form extends feedback_item_form {
    protected $type = "email";

    public function definition() {

        $item = $this->_customdata['item'];
        $common = $this->_customdata['common'];
        $positionlist = $this->_customdata['positionlist'];
        $position = $this->_customdata['position'];

        $mform =& $this->_form;

        $mform->addElement('header', 'general', get_string($this->type));
        $mform->addElement('advcheckbox', 'required', get_string('required', 'feedback'), '' , null , array(0, 1));

        $mform->addElement('text',
                            'name',
                            get_string('item_name', 'feedback'),
                            array('size'=>FEEDBACK_ITEM_NAME_TEXTBOX_SIZE, 'maxlength'=>255));
        $mform->addElement('text',
                            'label',
                            get_string('item_label', 'feedback'),
                            array('size'=>FEEDBACK_ITEM_LABEL_TEXTBOX_SIZE, 'maxlength'=>255));

        $mform->addElement('select',
                            'itemsize',
                            get_string('textfield_size', 'feedback').'&nbsp;',
                            array_slice(range(0, 255), 40, 255, true));

        parent::definition();
        $this->set_data($item);

    }

    public function get_data() {
        if (!$item = parent::get_data()) {
            return false;
        }

        $item->presentation = $item->itemsize;

        return $item;
    }

}
```

##Moodle上で確認してみる
oh...
![fig1.png](https://qiita-image-store.s3.amazonaws.com/0/63695/319c36a9-fd01-8784-0d7f-7a86fb84a711.png)

バージョンアップ作業時に問題が出るため、langファイルを直接編集するのは避けたいが、 `moodledata/lang/xxxx_local`以下に追加してもオリジナルの上書きとしか意味がないらしい。
諦めて`mod/feedback/lang/en/feedback.php`にダミーを追加してxxxx_localと併せて対応することにした･･･