MDL-20636 Can now display the attachments to an essay question that has attachments.

This commit is contained in:
Tim Hunt
2011-03-31 12:44:47 +01:00
parent b36d2d0643
commit caeeff0726
4 changed files with 112 additions and 10 deletions
+78 -1
View File
@@ -466,6 +466,11 @@ class question_display_options {
*/
public $history = self::HIDDEN;
/**
* @var int the context the attempt being output belongs to.
*/
public $contextid;
/**
* Set all the feedback-related fields {@link $feedback}, {@link generalfeedback},
* {@link rightanswer} and {@link manualcomment} to
@@ -916,6 +921,7 @@ class question_usage_by_activity {
* @return string HTML fragment representing the question.
*/
public function render_question($slot, $options, $number = null) {
$options->contextid = $this->context->id;
return $this->get_question_attempt($slot)->render($options, $number);
}
@@ -926,6 +932,7 @@ class question_usage_by_activity {
* @return string HTML fragment.
*/
public function render_question_head_html($slot) {
$options->contextid = $this->context->id;
return $this->get_question_attempt($slot)->render_head_html();
}
@@ -941,6 +948,7 @@ class question_usage_by_activity {
* @return string HTML fragment representing the question.
*/
public function render_question_at_step($slot, $seq, $options, $number = null) {
$options->contextid = $this->context->id;
return $this->get_question_attempt($slot)->render_at_step($seq, $options, $number, $this->preferredbehaviour);
}
@@ -1333,6 +1341,12 @@ class question_attempt {
*/
const PARAM_MARK = 'parammark';
/**
* @var string special value used by manual grading because {@link PARAM_NUMBER}
* converts '' to 0.
*/
const PARAM_FILES = 'paramfiles';
/** @var integer if this attempts is stored in the question_attempts table, the id of that row. */
protected $id = null;
@@ -1666,6 +1680,39 @@ class question_attempt {
return $default;
}
/**
* Get the latest set of files for a particular question type variable of
* type question_attempt::PARAM_FILES.
*
* @param string $name the name of the associated variable.
* @return array of {@link stored_files}.
*/
public function get_last_qt_files($name, $contextid) {
foreach ($this->get_reverse_step_iterator() as $step) {
if ($step->has_qt_var($name)) {
return $step->get_qt_files($name, $contextid);
}
}
return array();
}
/**
* Get the URL of a file that belongs to a response variable of this
* question_attempt.
* @param stored_file $file the file to link to.
* @return string the URL of that file.
*/
public function get_response_file_url(stored_file $file) {
return file_encode_url(new moodle_url('/pluginfile.php'), '/' . implode('/', array(
$file->get_contextid(),
$file->get_component(),
$file->get_filearea(),
$this->usageid,
$this->slot,
$file->get_itemid())) .
$file->get_filepath() . $file->get_filename());
}
/**
* Get the latest value of a particular behaviour variable. That is,
* get the value from the latest step that has it set. Return null if it is
@@ -1997,9 +2044,11 @@ class question_attempt {
} else {
$var = null;
}
if (is_string($var)) {
$var = stripslashes($var);
$var = $var;
}
return $var;
}
@@ -2488,6 +2537,9 @@ class question_attempt_step {
/** @var array name => value pairs. The submitted data. */
private $data;
/** @var array name => array of {@link stored_file}s. Caches the contents of file areas. */
private $files = array();
/**
* You should not need to call this constructor in your own code. Steps are
* normally created by {@link question_attempt} methods like
@@ -2582,6 +2634,30 @@ class question_attempt_step {
$this->data[$name] = $value;
}
/**
* Get the latest set of files for a particular question type variable of
* type question_attempt::PARAM_FILES.
*
* @param string $name the name of the associated variable.
* @return array of {@link stored_files}.
*/
public function get_qt_files($name, $contextid) {
if (array_key_exists($name, $this->files)) {
return $this->files[$name];
}
if (!$this->has_qt_var($name)) {
$this->files[$name] = array();
return array();
}
$fs = get_file_storage();
$this->files[$name] = $fs->get_area_files($contextid, 'question',
'response_' . $name, $this->id, 'sortorder', false);
return $this->files[$name];
}
/**
* Get all the question type variables.
* @param array name => value pairs.
@@ -2697,6 +2773,7 @@ class question_attempt_step {
$step = new question_attempt_step_read_only($data, $record->timecreated, $record->userid);
$step->state = question_state::get($record->state);
$step->id = $record->attemptstepid;
if (!is_null($record->fraction)) {
$step->fraction = $record->fraction + 0;
}
+15 -1
View File
@@ -55,7 +55,11 @@ class qtype_essay_question extends question_with_responses {
}
public function get_expected_data() {
return array('answer' => PARAM_CLEANHTML);
$expecteddata = array('answer' => PARAM_CLEANHTML);
if ($this->attachments != 0) {
$expecteddata['attachments'] = question_attempt::PARAM_FILES;
}
return $expecteddata;
}
public function summarise_response(array $response) {
@@ -80,4 +84,14 @@ class qtype_essay_question extends question_with_responses {
return question_utils::arrays_same_at_key_missing_is_blank(
$prevresponse, $newresponse, 'answer');
}
public function check_file_access($qa, $options, $component, $filearea, $args, $forcedownload) {
if ($component == 'question' && $filearea == 'response_attachments') {
// Response attachments visible if the question has them.
return $this->attachments != 0;
} else {
return parent::check_file_access($qa, $options, $component, $filearea, $args, $forcedownload);
}
}
}
+18 -8
View File
@@ -45,7 +45,7 @@ class qtype_essay_renderer extends qtype_renderer {
$inputname = $qa->get_qt_field_name('answer');
$response = $qa->get_last_qt_var('answer', '');
if (empty($options->readonly)) {
$answer =$responseoutput->response_area_input($inputname,
$answer = $responseoutput->response_area_input($inputname,
$response, $question->responsefieldlines);
} else {
@@ -56,13 +56,13 @@ class qtype_essay_renderer extends qtype_renderer {
$files = '';
if (empty($options->readonly)) {
if ($question->attachments == 1) {
$files = $this->filepicker_input();
$files = $this->filepicker_input($qa, $options);
} else if ($question->attachments != 0) {
$files = $this->filemanager_input();
$files = $this->filemanager_input($qa, $options);
}
} else if ($question->attachments != 0) {
$files = $this->files_read_only();
$files = $this->files_read_only($qa, $options);
}
$result = '';
@@ -71,6 +71,7 @@ class qtype_essay_renderer extends qtype_renderer {
$result .= html_writer::start_tag('div', array('class' => 'ablock'));
$result .= html_writer::tag('div', $answer, array('class' => 'answer'));
$result .= html_writer::tag('div', $files, array('class' => 'attachments'));
$result .= html_writer::end_tag('div');
return $result;
@@ -79,21 +80,30 @@ class qtype_essay_renderer extends qtype_renderer {
/**
* Displays any attached files when the question is in read-only mode.
*/
public function files_read_only() {
return '';
public function files_read_only(question_attempt $qa, question_display_options $options) {
$files = $qa->get_last_qt_files('attachments', $options->contextid);
$output = array();
foreach ($files as $file) {
$mimetype = $file->get_mimetype();
$output[] = html_writer::tag('p', html_writer::link($qa->get_response_file_url($file),
$this->output->pix_icon(file_mimetype_icon($mimetype), $mimetype,
'moodle', array('class' => 'icon')) . ' ' . s($file->get_filename())));
}
return implode($output);
}
/**
* Displays the input control for when the student should upload a single file.
*/
public function filepicker_input() {
public function filepicker_input(question_attempt $qa, question_display_options $options) {
return '';
}
/**
* Displays the input control for when the student should upload a number of files.
*/
public function filemanager_input() {
public function filemanager_input(question_attempt $qa, question_display_options $options) {
return '';
}
}
+1
View File
@@ -11,4 +11,5 @@
}
.que.essay .qtype_essay_response.qtype_essay_editor {
background-color: white;
min-height: 3em;
}