芝麻web文件管理V1.00
编辑当前文件:/home2/sdektunc/.trash/cepali/question/type/multianswer/edit_multianswer_form.php
. /** * Defines the editing form for the multi-answer question type. * * @package qtype * @subpackage multianswer * @copyright 2007 Jamie Pratt me@jamiep.org * @license http://www.gnu.org/copyleft/gpl.html GNU Public License */ defined('MOODLE_INTERNAL') || die(); require_once($CFG->dirroot . '/question/type/numerical/questiontype.php'); /** * Form for editing multi-answer questions. * * @copyright 2007 Jamie Pratt me@jamiep.org * @license http://www.gnu.org/copyleft/gpl.html GNU Public License */ class qtype_multianswer_edit_form extends question_edit_form { // The variable $questiondisplay will contain the qtype_multianswer_extract_question from // the questiontext. public $questiondisplay; // The variable $savedquestiondisplay will contain the qtype_multianswer_extract_question // from the questiontext in database. public $savedquestion; public $savedquestiondisplay; /** @var bool this question is used in quiz */ public $usedinquiz = false; /** @var bool the qtype has been changed */ public $qtypechange = false; /** @var integer number of questions that have been deleted */ public $negativediff = 0; /** @var integer number of quiz that used this question */ public $nbofquiz = 0; /** @var integer number of attempts that used this question */ public $nbofattempts = 0; public $confirm = 0; public $reload = false; /** @var qtype_numerical_answer_processor used when validating numerical answers. */ protected $ap = null; public function __construct($submiturl, $question, $category, $contexts, $formeditable = true) { global $SESSION, $CFG, $DB; $this->regenerate = true; $this->reload = optional_param('reload', false, PARAM_BOOL); $this->usedinquiz = false; if (isset($question->id) && $question->id != 0) { // TODO MDL-43779 should not have quiz-specific code here. $this->savedquestiondisplay = fullclone($question); $this->nbofquiz = $DB->count_records('quiz_slots', array('questionid' => $question->id)); $this->usedinquiz = $this->nbofquiz > 0; $this->nbofattempts = $DB->count_records_sql(" SELECT count(1) FROM {quiz_slots} slot JOIN {quiz_attempts} quiza ON quiza.quiz = slot.quizid WHERE slot.questionid = ? AND quiza.preview = 0", array($question->id)); } parent::__construct($submiturl, $question, $category, $contexts, $formeditable); } protected function definition_inner($mform) { $mform->addElement('hidden', 'reload', 1); $mform->setType('reload', PARAM_INT); // Remove meaningless defaultmark field. $mform->removeElement('defaultmark'); $this->confirm = optional_param('confirm', false, PARAM_BOOL); // Display the questions from questiontext. if ($questiontext = optional_param_array('questiontext', false, PARAM_RAW)) { $this->questiondisplay = fullclone(qtype_multianswer_extract_question($questiontext)); } else { if (!$this->reload && !empty($this->savedquestiondisplay->id)) { // Use database data as this is first pass // question->id == 0 so no stored datasets. $this->questiondisplay = fullclone($this->savedquestiondisplay); foreach ($this->questiondisplay->options->questions as $subquestion) { if (!empty($subquestion)) { $subquestion->answer = array(''); foreach ($subquestion->options->answers as $ans) { $subquestion->answer[] = $ans->answer; } } } } else { $this->questiondisplay = ""; } } if (isset($this->savedquestiondisplay->options->questions) && is_array($this->savedquestiondisplay->options->questions)) { $countsavedsubquestions = 0; foreach ($this->savedquestiondisplay->options->questions as $subquestion) { if (!empty($subquestion)) { $countsavedsubquestions++; } } } else { $countsavedsubquestions = 0; } if ($this->reload) { if (isset($this->questiondisplay->options->questions) && is_array($this->questiondisplay->options->questions)) { $countsubquestions = 0; foreach ($this->questiondisplay->options->questions as $subquestion) { if (!empty($subquestion)) { $countsubquestions++; } } } else { $countsubquestions = 0; } } else { $countsubquestions = $countsavedsubquestions; } $mform->addElement('submit', 'analyzequestion', get_string('decodeverifyquestiontext', 'qtype_multianswer')); $mform->registerNoSubmitButton('analyzequestion'); if ($this->reload) { for ($sub = 1; $sub <= $countsubquestions; $sub++) { if (isset($this->questiondisplay->options->questions[$sub]->qtype)) { $this->editas[$sub] = $this->questiondisplay->options->questions[$sub]->qtype; } else { $this->editas[$sub] = optional_param('sub_'.$sub.'_qtype', 'unknown type', PARAM_PLUGIN); } $storemess = ''; if (isset($this->savedquestiondisplay->options->questions[$sub]->qtype) && $this->savedquestiondisplay->options->questions[$sub]->qtype != $this->questiondisplay->options->questions[$sub]->qtype) { $this->qtypechange = true; $storemess = ' ' . html_writer::tag('span', get_string( 'storedqtype', 'qtype_multianswer', question_bank::get_qtype_name( $this->savedquestiondisplay->options->questions[$sub]->qtype)), array('class' => 'error')); } $mform->addElement('header', 'subhdr'.$sub, get_string('questionno', 'question', '{#'.$sub.'}').' '.question_bank::get_qtype_name( $this->questiondisplay->options->questions[$sub]->qtype).$storemess); $mform->addElement('static', 'sub_'.$sub.'_questiontext', get_string('questiondefinition', 'qtype_multianswer')); if (isset ($this->questiondisplay->options->questions[$sub]->questiontext)) { $mform->setDefault('sub_'.$sub.'_questiontext', $this->questiondisplay->options->questions[$sub]->questiontext['text']); } $mform->addElement('static', 'sub_'.$sub.'_defaultmark', get_string('defaultmark', 'question')); $mform->setDefault('sub_'.$sub.'_defaultmark', $this->questiondisplay->options->questions[$sub]->defaultmark); if ($this->questiondisplay->options->questions[$sub]->qtype == 'shortanswer') { $mform->addElement('static', 'sub_'.$sub.'_usecase', get_string('casesensitive', 'qtype_shortanswer')); } if ($this->questiondisplay->options->questions[$sub]->qtype == 'multichoice') { $mform->addElement('static', 'sub_'.$sub.'_layout', get_string('layout', 'qtype_multianswer')); $mform->addElement('static', 'sub_'.$sub.'_shuffleanswers', get_string('shuffleanswers', 'qtype_multichoice')); } foreach ($this->questiondisplay->options->questions[$sub]->answer as $key => $ans) { $mform->addElement('static', 'sub_'.$sub.'_answer['.$key.']', get_string('answer', 'question')); if ($this->questiondisplay->options->questions[$sub]->qtype == 'numerical' && $key == 0) { $mform->addElement('static', 'sub_'.$sub.'_tolerance['.$key.']', get_string('acceptederror', 'qtype_numerical')); } $mform->addElement('static', 'sub_'.$sub.'_fraction['.$key.']', get_string('grade')); $mform->addElement('static', 'sub_'.$sub.'_feedback['.$key.']', get_string('feedback', 'question')); } } $this->negativediff = $countsavedsubquestions - $countsubquestions; if (($this->negativediff > 0) ||$this->qtypechange || ($this->usedinquiz && $this->negativediff != 0)) { $mform->addElement('header', 'additemhdr', get_string('warningquestionmodified', 'qtype_multianswer')); } if ($this->negativediff > 0) { $mform->addElement('static', 'alert1', "
". get_string('questiondeleted', 'qtype_multianswer')."
", get_string('questionsless', 'qtype_multianswer', $this->negativediff)); } if ($this->qtypechange) { $mform->addElement('static', 'alert1', "
". get_string('questiontypechanged', 'qtype_multianswer')."
", get_string('questiontypechangedcomment', 'qtype_multianswer')); } } if ($this->usedinquiz) { if ($this->negativediff < 0) { $diff = $countsubquestions - $countsavedsubquestions; $mform->addElement('static', 'alert1', "
". get_string('questionsadded', 'qtype_multianswer')."
", "
".get_string('questionsmore', 'qtype_multianswer', $diff). "
"); } $a = new stdClass(); $a->nb_of_quiz = $this->nbofquiz; $a->nb_of_attempts = $this->nbofattempts; $mform->addElement('header', 'additemhdr2', get_string('questionusedinquiz', 'qtype_multianswer', $a)); $mform->addElement('static', 'alertas', get_string('youshouldnot', 'qtype_multianswer')); } if (($this->negativediff > 0 || $this->usedinquiz && ($this->negativediff > 0 || $this->negativediff < 0 || $this->qtypechange)) && $this->reload) { $mform->addElement('header', 'additemhdr', get_string('questionsaveasedited', 'qtype_multianswer')); $mform->addElement('checkbox', 'confirm', '', get_string('confirmquestionsaveasedited', 'qtype_multianswer')); $mform->setDefault('confirm', 0); } else { $mform->addElement('hidden', 'confirm', 0); $mform->setType('confirm', PARAM_BOOL); } $this->add_interactive_settings(true, true); } public function set_data($question) { global $DB; $defaultvalues = array(); if (isset($question->id) and $question->id and $question->qtype && $question->questiontext) { foreach ($question->options->questions as $key => $wrapped) { if (!empty($wrapped)) { // The old way of restoring the definitions is kept to gradually // update all multianswer questions. if (empty($wrapped->questiontext)) { $parsableanswerdef = '{' . $wrapped->defaultmark . ':'; switch ($wrapped->qtype) { case 'multichoice': $parsableanswerdef .= 'MULTICHOICE:'; break; case 'shortanswer': $parsableanswerdef .= 'SHORTANSWER:'; break; case 'numerical': $parsableanswerdef .= 'NUMERICAL:'; break; default: print_error('unknownquestiontype', 'question', '', $wrapped->qtype); } $separator = ''; foreach ($wrapped->options->answers as $subanswer) { $parsableanswerdef .= $separator . '%' . round(100 * $subanswer->fraction) . '%'; if (is_array($subanswer->answer)) { $parsableanswerdef .= $subanswer->answer['text']; } else { $parsableanswerdef .= $subanswer->answer; } if (!empty($wrapped->options->tolerance)) { // Special for numerical answers. $parsableanswerdef .= ":{$wrapped->options->tolerance}"; // We only want tolerance for the first alternative, it will // be applied to all of the alternatives. unset($wrapped->options->tolerance); } if ($subanswer->feedback) { $parsableanswerdef .= "#{$subanswer->feedback}"; } $separator = '~'; } $parsableanswerdef .= '}'; // Fix the questiontext fields of old questions. $DB->set_field('question', 'questiontext', $parsableanswerdef, array('id' => $wrapped->id)); } else { $parsableanswerdef = str_replace('', '&\#', $wrapped->questiontext); } $question->questiontext = str_replace("{#$key}", $parsableanswerdef, $question->questiontext); } } } // Set default to $questiondisplay questions elements. if ($this->reload) { if (isset($this->questiondisplay->options->questions)) { $subquestions = fullclone($this->questiondisplay->options->questions); if (count($subquestions)) { $sub = 1; foreach ($subquestions as $subquestion) { $prefix = 'sub_'.$sub.'_'; // Validate parameters. $answercount = 0; $maxgrade = false; $maxfraction = -1; if ($subquestion->qtype == 'shortanswer') { switch ($subquestion->usecase) { case '1': $defaultvalues[$prefix.'usecase'] = get_string('caseyes', 'qtype_shortanswer'); break; case '0': default : $defaultvalues[$prefix.'usecase'] = get_string('caseno', 'qtype_shortanswer'); } } if ($subquestion->qtype == 'multichoice') { $defaultvalues[$prefix.'layout'] = $subquestion->layout; if ($subquestion->single == 1) { switch ($subquestion->layout) { case '0': $defaultvalues[$prefix.'layout'] = get_string('layoutselectinline', 'qtype_multianswer'); break; case '1': $defaultvalues[$prefix.'layout'] = get_string('layoutvertical', 'qtype_multianswer'); break; case '2': $defaultvalues[$prefix.'layout'] = get_string('layouthorizontal', 'qtype_multianswer'); break; default: $defaultvalues[$prefix.'layout'] = get_string('layoutundefined', 'qtype_multianswer'); } } else { switch ($subquestion->layout) { case '1': $defaultvalues[$prefix.'layout'] = get_string('layoutmultiple_vertical', 'qtype_multianswer'); break; case '2': $defaultvalues[$prefix.'layout'] = get_string('layoutmultiple_horizontal', 'qtype_multianswer'); break; default: $defaultvalues[$prefix.'layout'] = get_string('layoutundefined', 'qtype_multianswer'); } } if ($subquestion->shuffleanswers ) { $defaultvalues[$prefix.'shuffleanswers'] = get_string('yes', 'moodle'); } else { $defaultvalues[$prefix.'shuffleanswers'] = get_string('no', 'moodle'); } } foreach ($subquestion->answer as $key => $answer) { if ($subquestion->qtype == 'numerical' && $key == 0) { $defaultvalues[$prefix.'tolerance['.$key.']'] = $subquestion->tolerance[0]; } if (is_array($answer)) { $answer = $answer['text']; } $trimmedanswer = trim($answer); if ($trimmedanswer !== '') { $answercount++; if ($subquestion->qtype == 'numerical' && !(qtype_numerical::is_valid_number($trimmedanswer) || $trimmedanswer == '*')) { $this->_form->setElementError($prefix.'answer['.$key.']', get_string('answermustbenumberorstar', 'qtype_numerical')); } if ($subquestion->fraction[$key] == 1) { $maxgrade = true; } if ($subquestion->fraction[$key] > $maxfraction) { $maxfraction = $subquestion->fraction[$key]; } // For 'multiresponse' we are OK if there is at least one fraction > 0. if ($subquestion->qtype == 'multichoice' && $subquestion->single == 0 && $subquestion->fraction[$key] > 0) { $maxgrade = true; } } $defaultvalues[$prefix.'answer['.$key.']'] = htmlspecialchars($answer); } if ($answercount == 0) { if ($subquestion->qtype == 'multichoice') { $this->_form->setElementError($prefix.'answer[0]', get_string('notenoughanswers', 'qtype_multichoice', 2)); } else { $this->_form->setElementError($prefix.'answer[0]', get_string('notenoughanswers', 'question', 1)); } } if ($maxgrade == false) { $this->_form->setElementError($prefix.'fraction[0]', get_string('fractionsnomax', 'question')); } foreach ($subquestion->feedback as $key => $answer) { $defaultvalues[$prefix.'feedback['.$key.']'] = htmlspecialchars ($answer['text']); } foreach ($subquestion->fraction as $key => $answer) { $defaultvalues[$prefix.'fraction['.$key.']'] = $answer; } $sub++; } } } } $defaultvalues['alertas'] = "
".get_string('questioninquiz', 'qtype_multianswer'). "
"; if ($defaultvalues != "") { $question = (object)((array)$question + $defaultvalues); } $question = $this->data_preprocessing_hints($question, true, true); parent::set_data($question); } public function validation($data, $files) { $errors = parent::validation($data, $files); $questiondisplay = qtype_multianswer_extract_question($data['questiontext']); $errors = array_merge($errors, qtype_multianswer_validate_question($questiondisplay)); if (($this->negativediff > 0 || $this->usedinquiz && ($this->negativediff > 0 || $this->negativediff < 0 || $this->qtypechange)) && !$this->confirm) { $errors['confirm'] = get_string('confirmsave', 'qtype_multianswer', $this->negativediff); } return $errors; } public function qtype() { return 'multianswer'; } }