Skip to content

Commit de7e244

Browse files
committed
Make the file upload work with required setting, fix delete of records
1 parent 5fe7dce commit de7e244

File tree

3 files changed

+76
-15
lines changed

3 files changed

+76
-15
lines changed

classes/question/file.php

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,20 +70,25 @@ protected function responseclass() {
7070
/**
7171
* Survey display output.
7272
*
73-
* @param \stdClass $formdata
73+
* @param response $response
7474
* @param object $descendantsdata
7575
* @param bool $blankquestionnaire
7676
* @return string
7777
*/
78-
protected function question_survey_display($formdata, $descendantsdata, $blankquestionnaire = false) {
78+
protected function question_survey_display($response, $descendantsdata, $blankquestionnaire = false) {
7979
global $CFG, $PAGE;
8080
require_once($CFG->libdir . '/filelib.php');
81+
8182
$elname = 'q' . $this->id;
82-
$draftitemid = file_get_submitted_draft_itemid($elname);
83-
$component = 'mod_questionnaire';
83+
// Make sure there is a response, fetch the draft id from the original request.
84+
if (isset($response->answers[$this->id]) && !empty($response->answers[$this->id]) && isset($_REQUEST[$elname . 'draft'])) {
85+
$draftitemid = (int)$_REQUEST[$elname . 'draft'];
86+
} else {
87+
$draftitemid = file_get_submitted_draft_itemid($elname);
88+
}
8489
$options = self::get_file_manager_option();
8590
if ($draftitemid > 0) {
86-
file_prepare_draft_area($draftitemid, $this->context->id, $component, 'file', $this->id, $options);
91+
file_prepare_draft_area($draftitemid, $this->context->id, 'mod_questionnaire', 'file', $this->id, $options);
8792
} else {
8893
$draftitemid = file_get_unused_draft_itemid();
8994
}
@@ -101,14 +106,40 @@ protected function question_survey_display($formdata, $descendantsdata, $blankqu
101106
);
102107
$fm = new form_filemanager((object) $fmoptions);
103108
$output = $PAGE->get_renderer('core', 'files');
104-
$html = $output->render($fm);
105109

106-
$html .= '<input value="' . $draftitemid . '" name="' . $elname . '" type="hidden" />';
107-
$html .= '<input value="" id="' . $this->id . '" type="hidden" />';
110+
$html = '<div class="form-filemanager" data-fieldtype="filemanager">' .
111+
$output->render($fm) .
112+
'<input type="hidden" name="' . $elname . '" value="' . $draftitemid . '" />' .
113+
'<input type="hidden" name="' . $elname . 'draft" value="' . $draftitemid . '" />' .
114+
'</div>';
108115

109116
return $html;
110117
}
111118

119+
/**
120+
* Check question's form data for complete response.
121+
* @param \stdClass $responsedata The data entered into the response.
122+
* @return bool
123+
*/
124+
public function response_complete($responsedata) {
125+
$answered = false;
126+
// If $responsedata is a response object, look through the answers.
127+
if (is_a($responsedata, 'mod_questionnaire\responsetype\response\response') &&
128+
isset($responsedata->answers[$this->id]) && !empty($responsedata->answers[$this->id])
129+
) {
130+
$answer = reset($responsedata->answers[$this->id]);
131+
$answered = ((int)$answer->value > 0);
132+
// If $responsedata is webform data, check that it is not empty.
133+
} else if (isset($responsedata->{'q'.$this->id})) {
134+
$draftitemid = (int)$responsedata->{'q' . $this->id};
135+
if ($draftitemid > 0) {
136+
$info = file_get_draft_area_info($draftitemid);
137+
$answered = $info['filecount'] > 0;
138+
}
139+
}
140+
return !($this->required() && ($this->deleted == 'n') && !$answered);
141+
}
142+
112143
/**
113144
* Get file manager options
114145
*

classes/responsetype/file.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ public static function answers_from_webform($responsedata, $question) {
5555
$file = reset($files);
5656
$record->value = $file->get_id();
5757
$answers[] = answer\answer::create_from_data($record);
58+
} else {
59+
self::delete_old_response((int)$question->id, (int)$record->responseid);
5860
}
5961
}
6062
return $answers;
@@ -114,11 +116,34 @@ public static function response_answers_by_question($rid) {
114116
return $answers;
115117
}
116118

119+
/**
120+
* Delete old entries from the questionnaire_response_file table and also the corresponding entries
121+
* in the files table.
122+
* @param int $question_id
123+
* @param int $response_id
124+
* @return void
125+
* @throws \dml_exception
126+
*/
127+
public static function delete_old_response(int $question_id, int $response_id) {
128+
global $DB;
129+
// Check, if we have an old response file from a former attempt.
130+
$record = $DB->get_record(static::response_table(), [
131+
'response_id' => $response_id,
132+
'question_id' => $question_id,
133+
]);
134+
if ($record) {
135+
// Old record found, then delete all referenced entries in the files table and then delete this entry.
136+
$DB->delete_records('files', ['component' => 'mod_questionnaire', 'itemid' => $record->itemid]);
137+
$DB->delete_records(self::response_table(), ['id' => $record->id]);
138+
}
139+
}
140+
117141
/**
118142
* Insert a provided response to the question.
119143
*
120144
* @param \mod_questionnaire\responsetype\response\response|\stdClass $responsedata
121145
* @return bool|int
146+
* @throws \dml_exception
122147
*/
123148
public function insert_response($responsedata) {
124149
global $DB;
@@ -135,6 +160,9 @@ public function insert_response($responsedata) {
135160
$record->question_id = $this->question->id;
136161
$record->fileid = intval(clean_text($response->answers[$this->question->id][0]->value));
137162

163+
// Delete any previous attempts.
164+
self::delete_old_response((int)$this->question->id, (int)$response->id);
165+
138166
// When saving the draft file, the itemid was the same as the draftitemid. This must now be
139167
// corrected to the primary key that is questionaire_response_file.id to have a correct reference.
140168
$recordid = $DB->insert_record(static::response_table(), $record);

locallib.php

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -317,13 +317,14 @@ function questionnaire_delete_response($response, $questionnaire='') {
317317
}
318318

319319
// Delete all of the response data for a response.
320-
$DB->delete_records('questionnaire_response_bool', array('response_id' => $rid));
321-
$DB->delete_records('questionnaire_response_date', array('response_id' => $rid));
322-
$DB->delete_records('questionnaire_resp_multiple', array('response_id' => $rid));
323-
$DB->delete_records('questionnaire_response_other', array('response_id' => $rid));
324-
$DB->delete_records('questionnaire_response_rank', array('response_id' => $rid));
325-
$DB->delete_records('questionnaire_resp_single', array('response_id' => $rid));
326-
$DB->delete_records('questionnaire_response_text', array('response_id' => $rid));
320+
$DB->delete_records('questionnaire_response_bool', ['response_id' => $rid]);
321+
$DB->delete_records('questionnaire_response_date', ['response_id' => $rid]);
322+
$DB->delete_records('questionnaire_resp_multiple', ['response_id' => $rid]);
323+
$DB->delete_records('questionnaire_response_other', ['response_id' => $rid]);
324+
$DB->delete_records('questionnaire_response_rank', ['response_id' => $rid]);
325+
$DB->delete_records('questionnaire_resp_single', ['response_id' => $rid]);
326+
$DB->delete_records('questionnaire_response_text', ['response_id' => $rid]);
327+
$DB->delete_records('questionnaire_response_file', ['response_id' => $rid]);
327328

328329
$status = $status && $DB->delete_records('questionnaire_response', array('id' => $rid));
329330

@@ -354,6 +355,7 @@ function questionnaire_delete_responses($qid) {
354355
$DB->delete_records('questionnaire_response_rank', ['question_id' => $qid]);
355356
$DB->delete_records('questionnaire_resp_single', ['question_id' => $qid]);
356357
$DB->delete_records('questionnaire_response_text', ['question_id' => $qid]);
358+
$DB->delete_records('questionnaire_response_file', ['question_id' => $qid]);
357359

358360
return true;
359361
}

0 commit comments

Comments
 (0)