MDL-20636 Essay questions can now handle files in the HTML editor. #216
This commit is contained in:
+29
-15
@@ -119,15 +119,15 @@ class question_engine_data_mapper {
|
||||
$record->id = $this->db->insert_record('question_attempt_steps', $record);
|
||||
|
||||
foreach ($step->get_all_data() as $name => $value) {
|
||||
if ($value instanceof question_file_saver) {
|
||||
$value->save_files($record->id, $context);
|
||||
}
|
||||
|
||||
$data = new stdClass();
|
||||
$data->attemptstepid = $record->id;
|
||||
$data->name = $name;
|
||||
$data->value = $value;
|
||||
$this->db->insert_record('question_attempt_step_data', $data, false);
|
||||
|
||||
if ($value instanceof question_file_saver) {
|
||||
$value->save_files($record->id, $context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1022,24 +1022,27 @@ class question_file_saver {
|
||||
* @param string $component the component for the file area to save into.
|
||||
* @param string $filearea the name of the file area to save into.
|
||||
*/
|
||||
public function __construct($draftitemid, $component, $filearea) {
|
||||
public function __construct($draftitemid, $component, $filearea, $text = null) {
|
||||
$this->draftitemid = $draftitemid;
|
||||
$this->component = $component;
|
||||
$this->filearea = $filearea;
|
||||
$this->value = $this->compute_value($draftitemid, $text);
|
||||
}
|
||||
|
||||
protected function get_value() {
|
||||
/**
|
||||
* Compute the value that should be stored in the question_attempt_step_data
|
||||
* table. Contains a hash that (almost) uniquely encodes all the files.
|
||||
* @param int $draftitemid the draft file area itemid.
|
||||
* @param string $text optional content containing file links.
|
||||
*/
|
||||
protected function compute_value($draftitemid, $text) {
|
||||
global $USER;
|
||||
|
||||
if (!is_null($this->value)) {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
$fs = get_file_storage();
|
||||
$usercontext = get_context_instance(CONTEXT_USER, $USER->id);
|
||||
|
||||
$files = $fs->get_area_files($usercontext->id, 'user', 'draft',
|
||||
$this->draftitemid, 'sortorder, filepath, filename', false);
|
||||
$draftitemid, 'sortorder, filepath, filename', false);
|
||||
|
||||
$string = '';
|
||||
foreach ($files as $file) {
|
||||
@@ -1048,16 +1051,27 @@ class question_file_saver {
|
||||
}
|
||||
|
||||
if ($string) {
|
||||
$this->value = md5($string);
|
||||
$hash = md5($string);
|
||||
} else {
|
||||
$this->value = '';
|
||||
$hash = '';
|
||||
}
|
||||
|
||||
return $this->value;
|
||||
if (is_null($text)) {
|
||||
return $hash;
|
||||
}
|
||||
|
||||
// We add the file hash so a simple string comparison will say if the
|
||||
// files have been changed. First strip off any existing file hash.
|
||||
$text = preg_replace('/\s*<!-- File hash: \w+ -->\s*$/', '', $text);
|
||||
$text = file_rewrite_urls_to_pluginfile($text, $draftitemid);
|
||||
if ($hash) {
|
||||
$text .= '<!-- File hash: ' . $hash . ' -->';
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->get_value();
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+122
-42
@@ -1347,6 +1347,12 @@ class question_attempt {
|
||||
*/
|
||||
const PARAM_FILES = 'paramfiles';
|
||||
|
||||
/**
|
||||
* @var string special value to indicate a response variable that is uploaded
|
||||
* files.
|
||||
*/
|
||||
const PARAM_CLEANHTML_FILES = 'paramcleanhtmlfiles';
|
||||
|
||||
/** @var integer if this attempts is stored in the question_attempts table, the id of that row. */
|
||||
protected $id = null;
|
||||
|
||||
@@ -1661,6 +1667,21 @@ class question_attempt {
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last step with a particular question type varialbe set.
|
||||
* @param string $name the name of the variable to get.
|
||||
* @return question_attempt_step the last step, or a step with no variables
|
||||
* if there was not a real step.
|
||||
*/
|
||||
public function get_last_step_with_qt_var($name) {
|
||||
foreach ($this->get_reverse_step_iterator() as $step) {
|
||||
if ($step->has_qt_var($name)) {
|
||||
return $step;
|
||||
}
|
||||
}
|
||||
return new question_attempt_step_read_only();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the latest value of a particular question type variable. That is, get
|
||||
* the value from the latest step that has it set. Return null if it is not
|
||||
@@ -1672,12 +1693,12 @@ class question_attempt {
|
||||
* @return mixed string value, or $default if it has never been set.
|
||||
*/
|
||||
public function get_last_qt_var($name, $default = null) {
|
||||
foreach ($this->get_reverse_step_iterator() as $step) {
|
||||
if ($step->has_qt_var($name)) {
|
||||
return $step->get_qt_var($name);
|
||||
}
|
||||
$step = $this->get_last_step_with_qt_var($name);
|
||||
if ($step->has_qt_var($name)) {
|
||||
return $step->get_qt_var($name);
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1890,6 +1911,15 @@ class question_attempt {
|
||||
return $this->behaviour->summarise_action($step);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function used by {@link rewrite_pluginfile_urls()} and
|
||||
* {@link rewrite_response_pluginfile_urls()}.
|
||||
* @return array ids that need to go into the file paths.
|
||||
*/
|
||||
protected function extra_file_path_components() {
|
||||
return array($this->get_usage_id(), $this->get_slot());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link question_rewrite_question_urls()} with appropriate parameters
|
||||
* for content belonging to this question.
|
||||
@@ -1897,11 +1927,28 @@ class question_attempt {
|
||||
* @param string $component the component name (normally 'question' or 'qtype_...')
|
||||
* @param string $filearea the name of the file area.
|
||||
* @param int $itemid the item id.
|
||||
* @return srting the content with the URLs rewritten.
|
||||
*/
|
||||
public function rewrite_pluginfile_urls($text, $component, $filearea, $itemid) {
|
||||
return question_rewrite_question_urls($text,
|
||||
'pluginfile.php', $this->question->contextid, $component, $filearea,
|
||||
array($this->get_usage_id(), $this->get_slot()), $itemid);
|
||||
return question_rewrite_question_urls($text, 'pluginfile.php',
|
||||
$this->question->contextid, $component, $filearea,
|
||||
$this->extra_file_path_components(), $itemid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link question_rewrite_question_urls()} with appropriate parameters
|
||||
* for content belonging to responses to this question.
|
||||
*
|
||||
* @param string $text the text to update the URLs in.
|
||||
* @param int $contextid the id of the context the quba belongs to.
|
||||
* @param string $name the variable name the files belong to.
|
||||
* @param question_attempt_step $step the step the response is coming from.
|
||||
* @return srting the content with the URLs rewritten.
|
||||
*/
|
||||
public function rewrite_response_pluginfile_urls($text, $contextid, $name,
|
||||
question_attempt_step $step) {
|
||||
return $step->rewrite_response_pluginfile_urls($text, $contextid, $name,
|
||||
$this->extra_file_path_components());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2043,61 +2090,66 @@ class question_attempt {
|
||||
* {@link optional_param()}, except that the results is returned without
|
||||
* slashes.
|
||||
* @param string $name the paramter name.
|
||||
* @param int $type one of the PARAM_... constants.
|
||||
* @param int $type one of the standard PARAM_... constants, or one of the
|
||||
* special extra constands defined by this class.
|
||||
* @param array $postdata (optional, only inteded for testing use) take the
|
||||
* data from this array, instead of from $_POST.
|
||||
* @return mixed the requested value.
|
||||
*/
|
||||
public function get_submitted_var($name, $type, $postdata = null) {
|
||||
// Special case to work around PARAM_NUMBER converting '' to 0.
|
||||
if ($type == self::PARAM_MARK) {
|
||||
$mark = $this->get_submitted_var($name, PARAM_RAW_TRIMMED, $postdata);
|
||||
if ($mark === '') {
|
||||
return $mark;
|
||||
} else {
|
||||
return $this->get_submitted_var($name, PARAM_NUMBER, $postdata);
|
||||
}
|
||||
}
|
||||
switch ($type) {
|
||||
case self::PARAM_MARK:
|
||||
// Special case to work around PARAM_NUMBER converting '' to 0.
|
||||
$mark = $this->get_submitted_var($name, PARAM_RAW_TRIMMED, $postdata);
|
||||
if ($mark === '') {
|
||||
return $mark;
|
||||
} else {
|
||||
return $this->get_submitted_var($name, PARAM_NUMBER, $postdata);
|
||||
}
|
||||
|
||||
if ($type == self::PARAM_FILES) {
|
||||
return $this->process_response_files($name, $postdata);
|
||||
}
|
||||
case self::PARAM_FILES:
|
||||
return $this->process_response_files($name, $name, $postdata);
|
||||
|
||||
if (is_null($postdata)) {
|
||||
$var = optional_param($name, null, $type);
|
||||
} else if (array_key_exists($name, $postdata)) {
|
||||
$var = clean_param($postdata[$name], $type);
|
||||
} else {
|
||||
$var = null;
|
||||
}
|
||||
case self::PARAM_CLEANHTML_FILES:
|
||||
$var = $this->get_submitted_var($name, PARAM_CLEANHTML, $postdata);
|
||||
return $this->process_response_files($name, $name . ':itemid', $postdata, $var);
|
||||
|
||||
if (is_string($var)) {
|
||||
$var = $var;
|
||||
}
|
||||
default:
|
||||
if (is_null($postdata)) {
|
||||
$var = optional_param($name, null, $type);
|
||||
} else if (array_key_exists($name, $postdata)) {
|
||||
$var = clean_param($postdata[$name], $type);
|
||||
} else {
|
||||
$var = null;
|
||||
}
|
||||
|
||||
return $var;
|
||||
return $var;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a submitted variable representing uploaded files.
|
||||
* @param string $name the field name.
|
||||
* @param string $draftidname the field name holding the draft file area id.
|
||||
* @param array $postdata (optional, only inteded for testing use) take the
|
||||
* data from this array, instead of from $_POST. At the moment, this
|
||||
* behaves as if there were no files.
|
||||
* @param string $text optional reponse text.
|
||||
* @return question_file_saver that can be used to save the files later.
|
||||
*/
|
||||
protected function process_response_files($name, $postdata = null) {
|
||||
protected function process_response_files($name, $draftidname, $postdata = null, $text = null) {
|
||||
if ($postdata) {
|
||||
// There can be no files with test data (at the moment).
|
||||
return null;
|
||||
}
|
||||
|
||||
$draftitemid = file_get_submitted_draft_itemid($name);
|
||||
$draftitemid = file_get_submitted_draft_itemid($draftidname);
|
||||
if (!$draftitemid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new question_file_saver($draftitemid, 'question', 'response_' .
|
||||
str_replace($this->get_field_prefix(), '', $name));
|
||||
str_replace($this->get_field_prefix(), '', $name), $text);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2612,10 +2664,6 @@ class question_attempt_step {
|
||||
}
|
||||
}
|
||||
|
||||
public function get_id() {
|
||||
return $this->id; // TODO get rid of this.
|
||||
}
|
||||
|
||||
/** @return question_state The state after this step. */
|
||||
public function get_state() {
|
||||
return $this->state;
|
||||
@@ -2719,12 +2767,44 @@ class question_attempt_step {
|
||||
* @return int the draft itemid.
|
||||
*/
|
||||
public function prepare_response_files_draft_itemid($name, $contextid) {
|
||||
$draftid = 0; // Will be filled in by file_prepare_draft_area.
|
||||
file_prepare_draft_area($draftid, $contextid, 'question',
|
||||
'response_' . $name, $this->id);
|
||||
list($draftid, $notused) = $this->prepare_response_files_draft_itemid_with_text(
|
||||
$name, $contextid, null);
|
||||
return $draftid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare a draft file are for the files belonging the a response variable
|
||||
* of this step, while rewriting the URLs in some text.
|
||||
*
|
||||
* @param string $name the variable name the files belong to.
|
||||
* @param int $contextid the id of the context the quba belongs to.
|
||||
* @param string $text the text to update the URLs in.
|
||||
* @return array(int, string) the draft itemid and the text with URLs rewritten.
|
||||
*/
|
||||
public function prepare_response_files_draft_itemid_with_text($name, $contextid, $text) {
|
||||
$draftid = 0; // Will be filled in by file_prepare_draft_area.
|
||||
$newtext = file_prepare_draft_area($draftid, $contextid, 'question',
|
||||
'response_' . $name, $this->id, null, $text);
|
||||
return array($draftid, $newtext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrite the @@PLUGINFILE@@ tokens in a response variable from this step
|
||||
* that contains links to file. Normally you should probably call
|
||||
* {@link question_attempt::rewrite_response_pluginfile_urls()} instead of
|
||||
* calling this method directly.
|
||||
*
|
||||
* @param string $text the text to update the URLs in.
|
||||
* @param int $contextid the id of the context the quba belongs to.
|
||||
* @param string $name the variable name the files belong to.
|
||||
* @param array $extra extra file path components.
|
||||
* @return string the rewritten text.
|
||||
*/
|
||||
public function rewrite_response_pluginfile_urls($text, $contextid, $name, $extras) {
|
||||
return question_rewrite_question_urls($text, 'pluginfile.php', $contextid,
|
||||
'question', 'response_' . $name, $extras, $this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the question type variables.
|
||||
* @param array name => value pairs.
|
||||
|
||||
@@ -55,7 +55,12 @@ class qtype_essay_question extends question_with_responses {
|
||||
}
|
||||
|
||||
public function get_expected_data() {
|
||||
$expecteddata = array('answer' => PARAM_CLEANHTML, 'answerformat' => PARAM_FORMAT);
|
||||
if ($this->responseformat == 'editorfilepicker') {
|
||||
$expecteddata = array('answer' => question_attempt::PARAM_CLEANHTML_FILES);
|
||||
} else {
|
||||
$expecteddata = array('answer' => PARAM_CLEANHTML);
|
||||
}
|
||||
$expecteddata['answerformat'] = PARAM_FORMAT;
|
||||
if ($this->attachments != 0) {
|
||||
$expecteddata['attachments'] = question_attempt::PARAM_FILES;
|
||||
}
|
||||
@@ -92,6 +97,10 @@ class qtype_essay_question extends question_with_responses {
|
||||
// Response attachments visible if the question has them.
|
||||
return $this->attachments != 0;
|
||||
|
||||
} else if ($component == 'question' && $filearea == 'response_answer') {
|
||||
// Response attachments visible if the question has them.
|
||||
return $this->responseformat === 'editorfilepicker';
|
||||
|
||||
} else if ($component == 'qtype_essay' && $filearea == 'graderinfo') {
|
||||
return $options->manualcomment;
|
||||
|
||||
|
||||
@@ -42,17 +42,14 @@ class qtype_essay_renderer extends qtype_renderer {
|
||||
$responseoutput = $question->get_format_renderer($this->page);
|
||||
|
||||
// Answer field.
|
||||
$inputname = $qa->get_qt_field_name('answer');
|
||||
$response = $qa->get_last_qt_var('answer', '');
|
||||
$responseformat = $qa->get_last_qt_var('answerformat', FORMAT_HTML);
|
||||
$step = $qa->get_last_step_with_qt_var('answer');
|
||||
if (empty($options->readonly)) {
|
||||
$answer = $responseoutput->response_area_input($inputname,
|
||||
$response, $responseformat, $question->responsefieldlines,
|
||||
$options->context);
|
||||
$answer = $responseoutput->response_area_input('answer', $qa,
|
||||
$step, $question->responsefieldlines, $options->context);
|
||||
|
||||
} else {
|
||||
$answer = $responseoutput->response_area_read_only($inputname,
|
||||
$response, $responseformat, $question->responsefieldlines);
|
||||
$answer = $responseoutput->response_area_read_only('answer', $qa,
|
||||
$step, $question->responsefieldlines, $options->context);
|
||||
}
|
||||
|
||||
$files = '';
|
||||
@@ -114,6 +111,9 @@ class qtype_essay_renderer extends qtype_renderer {
|
||||
'attachments', $options->context->id);
|
||||
$pickeroptions->context = $options->context;
|
||||
|
||||
$pickeroptions->itemid = $qa->prepare_response_files_draft_itemid(
|
||||
'attachments', $options->context->id);
|
||||
|
||||
return form_filemanager_render($pickeroptions) . html_writer::empty_tag(
|
||||
'input', array('type' => 'hidden', 'name' => $qa->get_qt_field_name('attachments'),
|
||||
'value' => $pickeroptions->itemid));
|
||||
@@ -142,21 +142,32 @@ class qtype_essay_renderer extends qtype_renderer {
|
||||
abstract class qtype_essay_format_renderer_base extends plugin_renderer_base {
|
||||
/**
|
||||
* Render the students respone when the question is in read-only mode.
|
||||
* @param string $inputname the field name to use for this input.
|
||||
* @param string $response the student's current response.
|
||||
* @param string $name the variable name this input edits.
|
||||
* @param question_attempt $qa the question attempt being display.
|
||||
* @param question_attempt_step $step the current step.
|
||||
* @param int $lines approximate size of input box to display.
|
||||
* @param object $context the context teh output belongs to.
|
||||
* @return string html to display the response.
|
||||
*/
|
||||
public abstract function response_area_read_only($inputname, $response,
|
||||
$responseformat, $lines);
|
||||
public abstract function response_area_read_only($name, question_attempt $qa,
|
||||
question_attempt_step $step, $lines, $context);
|
||||
|
||||
/**
|
||||
* Render the students respone when the question is in read-only mode.
|
||||
* @param string $inputname the field name to use for this input.
|
||||
* @param string $response the student's current response.
|
||||
* @param string $name the variable name this input edits.
|
||||
* @param question_attempt $qa the question attempt being display.
|
||||
* @param question_attempt_step $step the current step.
|
||||
* @param int $lines approximate size of input box to display.
|
||||
* @param object $context the context teh output belongs to.
|
||||
* @return string html to display the response for editing.
|
||||
*/
|
||||
public abstract function response_area_input($inputname, $response,
|
||||
$responseformat, $lines, $contex);
|
||||
public abstract function response_area_input($name, question_attempt $qa,
|
||||
question_attempt_step $step, $lines, $context);
|
||||
|
||||
/**
|
||||
* @return string specific class name to add to the input element.
|
||||
*/
|
||||
protected abstract function class_name();
|
||||
}
|
||||
|
||||
|
||||
@@ -168,18 +179,21 @@ abstract class qtype_essay_format_renderer_base extends plugin_renderer_base {
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class qtype_essay_format_editor_renderer extends plugin_renderer_base {
|
||||
public function response_area_read_only($inputname, $response, $responseformat, $lines) {
|
||||
$formatoptions = new stdClass();
|
||||
$formatoptions->para = false;
|
||||
$response = $this->rewrite_pluginfile_urls($response);
|
||||
return html_writer::tag('div', format_text($response, $responseformat, $formatoptions),
|
||||
array('class' => 'qtype_essay_editor qtype_essay_response'));
|
||||
protected function class_name() {
|
||||
return 'qtype_essay_editor';
|
||||
}
|
||||
|
||||
public function response_area_input($inputname, $response, $responseformat, $lines, $context) {
|
||||
public function response_area_read_only($name, $qa, $step, $lines, $context) {
|
||||
return html_writer::tag('div', $this->prepare_response($name, $qa, $step, $context),
|
||||
array('class' => $this->class_name() . ' qtype_essay_response'));
|
||||
}
|
||||
|
||||
public function response_area_input($name, $qa, $step, $lines, $context) {
|
||||
global $CFG, $PAGE;
|
||||
require_once($CFG->dirroot.'/repository/lib.php');
|
||||
|
||||
$inputname = $qa->get_qt_field_name($name);
|
||||
$responseformat = $step->get_qt_var($name . 'format');
|
||||
$id = $inputname . '_id';
|
||||
|
||||
$editor = editors_get_preferred_editor($responseformat);
|
||||
@@ -189,13 +203,17 @@ class qtype_essay_format_editor_renderer extends plugin_renderer_base {
|
||||
$formats[$fid] = $strformats[$fid];
|
||||
}
|
||||
|
||||
list($draftitemid, $reponse) = $this->prepare_response_for_editing(
|
||||
$name, $step, $context);
|
||||
|
||||
$editor->use_editor($id, $this->get_editor_options($context),
|
||||
$this->get_filepicker_options());
|
||||
$this->get_filepicker_options($context, $draftitemid));
|
||||
|
||||
$output = '';
|
||||
$output .= html_writer::start_tag('div');
|
||||
$output .= html_writer::start_tag('div', array('class' =>
|
||||
$this->class_name() . ' qtype_essay_response'));
|
||||
|
||||
$output .= html_writer::tag('div', html_writer::tag('textarea', s($response),
|
||||
$output .= html_writer::tag('div', html_writer::tag('textarea', s($reponse),
|
||||
array('id' => $id, 'name' => $inputname, 'rows' => $lines)));
|
||||
|
||||
$output .= html_writer::start_tag('div');
|
||||
@@ -209,28 +227,46 @@ class qtype_essay_format_editor_renderer extends plugin_renderer_base {
|
||||
}
|
||||
$output .= html_writer::end_tag('div');
|
||||
|
||||
$output .= $this->nonjs_filepicker();
|
||||
$output .= $this->filepicker_html($inputname, $draftitemid);
|
||||
|
||||
$output .= html_writer::end_tag('div');
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $response the student's response.
|
||||
* @return string the response with file URLs processed.
|
||||
* Prepare the response for read-only display.
|
||||
* @param string $name the variable name this input edits.
|
||||
* @param question_attempt $qa the question attempt being display.
|
||||
* @param question_attempt_step $step the current step.
|
||||
* @param object $context the context the attempt belongs to.
|
||||
* @return string the response prepared for display.
|
||||
*/
|
||||
protected function rewrite_pluginfile_urls($response) {
|
||||
return $response;
|
||||
protected function prepare_response($name, question_attempt $qa,
|
||||
question_attempt_step $step, $context) {
|
||||
if (!$step->has_qt_var($name)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$formatoptions = new stdClass();
|
||||
$formatoptions->para = false;
|
||||
return format_text($step->get_qt_var($name), $step->get_qt_var($name . 'format'),
|
||||
$formatoptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array filepicker options for the editor.
|
||||
* Prepare the response for editing.
|
||||
* @param string $name the variable name this input edits.
|
||||
* @param question_attempt_step $step the current step.
|
||||
* @param object $context the context the attempt belongs to.
|
||||
* @return string the response prepared for display.
|
||||
*/
|
||||
protected function get_filepicker_options() {
|
||||
return array();
|
||||
protected function prepare_response_for_editing($name,
|
||||
question_attempt_step $step, $context) {
|
||||
return array(0, $step->get_qt_var($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $context the context the attempt belongs to.
|
||||
* @return array options for the editor.
|
||||
*/
|
||||
protected function get_editor_options($context) {
|
||||
@@ -238,9 +274,20 @@ class qtype_essay_format_editor_renderer extends plugin_renderer_base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Extra output for the filepicker, if used.
|
||||
* @param object $context the context the attempt belongs to.
|
||||
* @param int $draftitemid draft item id.
|
||||
* @return array filepicker options for the editor.
|
||||
*/
|
||||
protected function nonjs_filepicker() {
|
||||
protected function get_filepicker_options($context, $draftitemid) {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $inputname input field name.
|
||||
* @param int $draftitemid draft file area itemid.
|
||||
* @return string HTML for the filepicker, if used.
|
||||
*/
|
||||
protected function filepicker_html($inputname, $draftitemid) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -254,17 +301,93 @@ class qtype_essay_format_editor_renderer extends plugin_renderer_base {
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class qtype_essay_format_editorfilepicker_renderer extends qtype_essay_format_editor_renderer {
|
||||
|
||||
protected function rewrite_pluginfile_urls($response) {
|
||||
return $response;
|
||||
protected function class_name() {
|
||||
return 'qtype_essay_editorfilepicker';
|
||||
}
|
||||
|
||||
protected function get_filepicker_options() {
|
||||
return array();
|
||||
protected function prepare_response($name, question_attempt $qa,
|
||||
question_attempt_step $step, $context) {
|
||||
if (!$step->has_qt_var($name)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$formatoptions = new stdClass();
|
||||
$formatoptions->para = false;
|
||||
$text = $qa->rewrite_response_pluginfile_urls($step->get_qt_var($name),
|
||||
$context->id, 'answer', $step);
|
||||
return format_text($text, $step->get_qt_var($name . 'format'), $formatoptions);
|
||||
}
|
||||
|
||||
protected function nonjs_filepicker() {
|
||||
return '';
|
||||
protected function prepare_response_for_editing($name,
|
||||
question_attempt_step $step, $context) {
|
||||
return $step->prepare_response_files_draft_itemid_with_text(
|
||||
$name, $context->id, $step->get_qt_var($name));
|
||||
}
|
||||
|
||||
protected function get_editor_options($context) {
|
||||
return array(
|
||||
'subdirs' => 0,
|
||||
'maxbytes' => 0,
|
||||
'maxfiles' => -1,
|
||||
'context' => $context,
|
||||
'noclean' => 0,
|
||||
'trusttext'=>0
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the options required to configure the filepicker for one of the editor
|
||||
* toolbar buttons.
|
||||
* @param mixed $acceptedtypes array of types of '*'.
|
||||
* @param int $draftitemid the draft area item id.
|
||||
* @param object $context the context.
|
||||
* @return object the required options.
|
||||
*/
|
||||
protected function specific_filepicker_options($acceptedtypes, $draftitemid, $context) {
|
||||
$filepickeroptions = new stdClass();
|
||||
$filepickeroptions->accepted_types = $acceptedtypes;
|
||||
$filepickeroptions->return_types = FILE_INTERNAL | FILE_EXTERNAL;
|
||||
$filepickeroptions->context = $context;
|
||||
$filepickeroptions->env = 'filepicker';
|
||||
|
||||
$options = initialise_filepicker($filepickeroptions);
|
||||
$options->context = $context;
|
||||
$options->client_id = uniqid();
|
||||
$options->env = 'editor';
|
||||
$options->itemid = $draftitemid;
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
protected function get_filepicker_options($context, $draftitemid) {
|
||||
global $CFG;
|
||||
|
||||
return array(
|
||||
'image' => $this->specific_filepicker_options(array('image'),
|
||||
$draftitemid, $context),
|
||||
'media' => $this->specific_filepicker_options(array('video', 'audio'),
|
||||
$draftitemid, $context),
|
||||
'link' => $this->specific_filepicker_options('*',
|
||||
$draftitemid, $context),
|
||||
);
|
||||
}
|
||||
|
||||
protected function filepicker_html($inputname, $draftitemid) {
|
||||
$nonjspickerurl = new moodle_url('/repository/draftfiles_manager.php', array(
|
||||
'action' => 'browse',
|
||||
'env' => 'editor',
|
||||
'itemid' => $draftitemid,
|
||||
'subdirs' => false,
|
||||
'maxfiles' => -1,
|
||||
'sesskey' => sesskey(),
|
||||
));
|
||||
|
||||
return html_writer::empty_tag('input', array('type' => 'hidden',
|
||||
'name' => $inputname . ':itemid', 'value' => $draftitemid)) .
|
||||
html_writer::tag('noscript', html_writer::tag('div',
|
||||
html_writer::tag('object', '', array('type' => 'text/html',
|
||||
'data' => $nonjspickerurl, 'height' => 160, 'width' => 600,
|
||||
'style' => 'border: 1px solid #000;'))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,12 +413,13 @@ class qtype_essay_format_plain_renderer extends plugin_renderer_base {
|
||||
return 'qtype_essay_plain';
|
||||
}
|
||||
|
||||
public function response_area_read_only($inputname, $response, $responseformat, $lines) {
|
||||
return $this->textarea($response, $lines, array('readonly' => 'readonly'));
|
||||
public function response_area_read_only($name, $qa, $step, $lines, $context) {
|
||||
return $this->textarea($step->get_qt_var($name), $lines, array('readonly' => 'readonly'));
|
||||
}
|
||||
|
||||
public function response_area_input($inputname, $response, $responseformat, $lines, $contex) {
|
||||
return $this->textarea($response, $lines, array('name' => $inputname)) .
|
||||
public function response_area_input($name, $qa, $step, $lines, $context) {
|
||||
$inputname = $qa->get_qt_field_name($name);
|
||||
return $this->textarea($step->get_qt_var($name), $lines, array('name' => $inputname)) .
|
||||
html_writer::empty_tag('input', array('type' => 'hidden',
|
||||
'name' => $inputname . 'format', 'value' => FORMAT_PLAIN));
|
||||
}
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
white-space: pre;
|
||||
font-family: Andale Mono, Monaco, Courier New, DejaVu Sans Mono, monospace;
|
||||
}
|
||||
.que.essay .qtype_essay_response.qtype_essay_editor {
|
||||
.que.essay .qtype_essay_response {
|
||||
background-color: white;
|
||||
min-height: 3em;
|
||||
}
|
||||
.que.essay div.qtype_essay_response textarea {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user