diff --git a/question/type/ordering/edit_ordering_form.php b/question/type/ordering/edit_ordering_form.php index b0e102abe79..a621502fd83 100644 --- a/question/type/ordering/edit_ordering_form.php +++ b/question/type/ordering/edit_ordering_form.php @@ -36,14 +36,14 @@ defined('MOODLE_INTERNAL') || die(); */ class qtype_ordering_edit_form extends question_edit_form { - const NUM_ANS_ROWS = 2; + const NUM_ANS_ROWS = 2; const NUM_ANS_COLS = 60; - const NUM_ANS_START = 6; - const NUM_ANS_ADD = 2; + const NUM_ANS_START = 6; + const NUM_ANS_ADD = 3; // this functionality is currently disabled // because it is not fully functional - protected $use_editor_for_answers = false; + protected $use_editor_for_answers = true; /** * unique name for this question type @@ -112,6 +112,8 @@ class qtype_ordering_edit_form extends question_edit_form { $label = get_string($name, $plugin); if ($this->use_editor_for_answers) { $elements[] = $mform->createElement('editor', $name, $label, $this->get_editor_attributes(), $this->get_editor_options()); + $elements[] = $mform->createElement('submit', $name.'removeeditor', get_string('removeeditor', $plugin)); + //$elements[] = $mform->createElement('submit', $name.'removeitem', get_string('removeitem', $plugin)); } else { $elements[] = $mform->createElement('textarea', $name, $label, array('rows' => self::NUM_ANS_ROWS, 'cols' => self::NUM_ANS_COLS)); } @@ -128,6 +130,9 @@ class qtype_ordering_edit_form extends question_edit_form { $buttontext = get_string('addmoreanswers', $plugin, self::NUM_ANS_ADD); $this->repeat_elements($elements, $start, $options, 'countanswers', 'addanswers', self::NUM_ANS_ADD, $buttontext); + // adjust HTML editor and removal buttons + $this->adjust_html_editors($mform, $name); + // feedback $this->add_ordering_feedback_fields(true); @@ -156,6 +161,66 @@ class qtype_ordering_edit_form extends question_edit_form { ); } + /** + * adjust_html_editors + */ + protected function adjust_html_editors($mform, $name) { + + // check whether or not we are using editors + if (! $this->use_editor_for_answers) { + return; + } + + // cache the number of supported formats + // for the preferred editor for each format + $count = array(); + + $ids = array_keys($this->question->options->answers); + foreach ($ids as $i => $id) { + + $editor = $name.'['.$i.']'; + if (! $mform->elementExists($editor)) { + continue; + } + $editor = $mform->getElement($editor); + + // the old/new name of the button to remove the HTML editor + // old : the name of the button when added by repeat_elements + // new : the simplified name of the button to satisfy + // "no_submit_button_pressed()" in lib/formslib.php + $oldname = $name.'removeeditor['.$i.']'; + $newname = $name.'removeeditor_'.$i; + + // remove HTML editor, if necessary + if (optional_param($newname, 0, PARAM_RAW)) { + $value = $editor->getValue(); + $value['format'] = FORMAT_MOODLE; + $value = $editor->setValue($value); + $format = $editor->getFormat(); + // override incoming format value + $_POST['answer'][$i]['format'] = $format; + } else { + $format = $this->question->options->answers[$id]->answerformat; + } + + // check we have a submit button - it should always be there !! + if ($mform->elementExists($oldname)) { + if (! isset($count[$format])) { + $editor = editors_get_preferred_editor($format); + $count[$format] = $editor->get_supported_formats(); + $count[$format] = count($count[$format]); + } + if ($count[$format] > 1) { + $mform->removeElement($oldname); + } else { + $submit = $mform->getElement($oldname); + $submit->setName($newname); + } + $mform->registerNoSubmitButton($newname); + } + } + } + /** * data_preprocessing */ @@ -174,20 +239,14 @@ class qtype_ordering_edit_form extends question_edit_form { if (isset($question->options->answers)) { $i = 0; - foreach ($question->options->answers as $answer) { + foreach ($question->options->answers as $answerid => $answer) { if (trim($answer->answer)=='') { continue; // skip empty answers } if ($this->use_editor_for_answers) { - $draftid = file_get_submitted_draft_itemid("answer[$i]"); - - if (isset($answer->id)) { - $itemid = $answer->id; - } else { - $itemid = null; - } + $itemid = file_get_submitted_draft_itemid("answer[$i]"); if (isset($answer->answer)) { $text = $answer->answer; @@ -201,12 +260,12 @@ class qtype_ordering_edit_form extends question_edit_form { $format = FORMAT_MOODLE; } - $text = file_prepare_draft_area($draftid, $this->context->id, 'qtype_ordering', - 'answer', $itemid, $this->editoroptions, $text); + $text = file_prepare_draft_area($itemid, $this->context->id, 'question', 'answer', + $answerid, $this->editoroptions, $text); $question->answer[$i] = array('text' => $text, 'format' => $format, - 'itemid' => $draftid); + 'itemid' => $itemid); } else { $question->answer[$i]= $answer->answer; } @@ -246,7 +305,7 @@ class qtype_ordering_edit_form extends question_edit_form { $answercount = 0; foreach ($data['answer'] as $answer){ - if ($this->use_editor_for_answers) { + if (is_array($answer)) { $answer = $answer['text']; } if (trim($answer)=='') { diff --git a/question/type/ordering/lang/en/qtype_ordering.php b/question/type/ordering/lang/en/qtype_ordering.php index 990b6ae9953..975cbe36595 100644 --- a/question/type/ordering/lang/en/qtype_ordering.php +++ b/question/type/ordering/lang/en/qtype_ordering.php @@ -25,6 +25,8 @@ $string['layouttype_help'] = 'Choose whether to display the items vertically or $string['layouttype'] = 'Layout of items'; $string['noresponsedetails'] = 'Sorry, no details of the response to this question are available.'; $string['notenoughanswers'] = 'Ordering questions must have more than {$a} answers.'; +$string['removeeditor'] = 'Remove HTML editor'; +$string['removeitem'] = 'Remove draggable item'; $string['selectall'] = 'Select all items'; $string['selectcontiguous'] = 'Select a contiguous subset of items'; $string['selectcount_help'] = 'The number of items that will be displayed when the question is appears in a quiz.'; diff --git a/question/type/ordering/question.php b/question/type/ordering/question.php index e8628223953..0b370b018dd 100644 --- a/question/type/ordering/question.php +++ b/question/type/ordering/question.php @@ -167,6 +167,24 @@ class qtype_ordering_question extends question_graded_automatically { return array($fraction, question_state::graded_state_for_fraction($fraction)); } + public function check_file_access($qa, $options, $component, $filearea, $args, $forcedownload) { + if ($component=='question') { + if ($filearea=='answer') { + $answerid = reset($args); // "itemid" is answer id + return array_key_exists($answerid, $this->answers); + + } + if (in_array($filearea, $this->qtype->feedback_fields)) { + return $this->check_combined_feedback_file_access($qa, $options, $filearea); + + } + if ($filearea=='hint') { + return $this->check_hint_file_access($qa, $options, $args); + } + } + return parent::check_file_access($qa, $options, $component, $filearea, $args, $forcedownload); + } + //////////////////////////////////////////////////////////////////// // custom methods //////////////////////////////////////////////////////////////////// diff --git a/question/type/ordering/questiontype.php b/question/type/ordering/questiontype.php index 693390d16fc..bf905992436 100644 --- a/question/type/ordering/questiontype.php +++ b/question/type/ordering/questiontype.php @@ -115,6 +115,7 @@ class qtype_ordering extends question_type { $result = new stdClass(); $context = $question->context; + //$context = $this->get_context_by_category_id($question->category); // remove empty answers $question->answer = array_filter($question->answer, array($this, 'is_not_blank')); @@ -123,6 +124,14 @@ class qtype_ordering extends question_type { // count how many answers we have $countanswers = count($question->answer); + // search/replace strings to reduce simple
...
to plain text + $p_search = '/^\s*\s*(.*?)(\s*
)*\s*<\/p>\s*$/';
+ $p_replace = '$1';
+
+ // search/replace strings to standardize vertical align of tags
+ $img_search = '/(
]*)\bvertical-align:\s*[a-zA-Z0-9_-]+([^>]*>)/';
+ $img_replace = '$1'.'vertical-align:text-top'.'$2';
+
// check at least two answers exist
if ($countanswers < 2) {
$result->notice = get_string('notenoughanswers', 'qtype_ordering', '2');
@@ -138,16 +147,40 @@ class qtype_ordering extends question_type {
}
// Insert all the new answers
-
foreach ($question->answer as $i => $answer) {
+
+ // extract $answer fields
+ if (is_array($answer)) {
+ // editor
+ $answertext = $answer['text'];
+ $answerformat = $answer['format'];
+ $answeritemid = $answer['itemid'];
+ } else {
+ // textarea
+ $answertext = $answer;
+ $answerformat = FORMAT_MOODLE;
+ $answeritemid = 0; // i.e. no editor
+ }
+
+ // reduce simple
...
to plain text + if (substr_count($answertext, '')==1) { + $answertext = preg_replace($p_search, $p_replace, $answertext); + } + + // standardize vertical align of img tags + $answertext = preg_replace($img_search, $img_replace, $answertext); + + // prepare the $answer object $answer = (object)array( 'question' => $question->id, 'fraction' => ($i + 1), // start at 1 - 'answer' => (is_array($answer) ? $answer['text'] : $answer), - 'answerformat' => (is_array($answer) ? $answer['format'] : FORMAT_MOODLE), + 'answer' => $answertext, + 'answerformat' => $answerformat, 'feedback' => '', 'feedbackformat' => FORMAT_MOODLE, ); + + // add/insert $answer into the database if ($answer->id = array_shift($answerids)) { if (! $DB->update_record('question_answers', $answer)) { $result->error = get_string('cannotupdaterecord', 'error', 'question_answers (id='.$answer->id.')'); @@ -160,6 +193,14 @@ class qtype_ordering extends question_type { return $result; } } + + // copy files across from draft files area + // Note: we must do this AFTER inserting the answer record + // because the answer id is used as the file's "itemid" + if ($answeritemid) { + $answertext = file_save_draft_area_files($answeritemid, $context->id, 'question', 'answer', $answer->id, $this->fileoptions, $answertext); + $DB->set_field('question_answers', 'answer', $answertext, array('id' => $answer->id)); + } } // create $options for this ordering question @@ -187,7 +228,11 @@ class qtype_ordering extends question_type { // delete old answer records, if any if (count($answerids)) { - $DB->delete_records_list('question_answers', 'id', $answerids); + $fs = get_file_storage(); + foreach ($answerids as $answerid) { + $fs->delete_area_files($context->id, 'question', 'answer', $answerid); + $DB->delete_records('question_answers', array('id' => $answerid)); + } } return true; diff --git a/question/type/ordering/renderer.php b/question/type/ordering/renderer.php index 0a2ac880d52..215c64be80a 100644 --- a/question/type/ordering/renderer.php +++ b/question/type/ordering/renderer.php @@ -136,6 +136,7 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer { // because $answer->fraction holds the correct order number // $id = 'ordering_item_'.$answerid.'_'.intval($question->answers[$answerid]->fraction); $answer = $question->answers[$answerid]; + $answer->answer = $question->format_text($answer->answer, $answer->answerformat, $qa, 'question', 'answer', $answerid); $params = array('class' => $class, 'id' => $answer->md5key); $result .= html_writer::tag('li', $img.$answer->answer, $params); } diff --git a/question/type/ordering/version.php b/question/type/ordering/version.php index 0019ab305f9..fddd7227384 100644 --- a/question/type/ordering/version.php +++ b/question/type/ordering/version.php @@ -30,6 +30,6 @@ defined('MOODLE_INTERNAL') || die(); $plugin->cron = 0; $plugin->component = 'qtype_ordering'; $plugin->maturity = MATURITY_STABLE; // ALPHA=50, BETA=100, RC=150, STABLE=200 -$plugin->release = '2015-11-15 (30)'; -$plugin->version = 2015111530; +$plugin->release = '2015-11-18 (31)'; +$plugin->version = 2015111831; $plugin->requires = 2010112400; // Moodle 2.0