diff --git a/classes/question/rate.php b/classes/question/rate.php index d3d4d2d1..8bbeb3f2 100644 --- a/classes/question/rate.php +++ b/classes/question/rate.php @@ -319,8 +319,21 @@ protected function question_survey_display($response, $descendantsdata, $blankqu if ($this->osgood_rate_scale()) { list($content, $contentright) = array_merge(preg_split('/[|]/', $content), array(' ')); } - $cols[] = ['colstyle' => 'text-align: '.$textalign.';', - 'coltext' => format_text($content, FORMAT_HTML, ['noclean' => true]).' ']; + if ($choice->is_other_choice()) { + $othertext = $choice->other_choice_display(); + $oname = $cid . '_qother'; + $oid = $cid . '-other'; + $odata = isset($response->answers[$this->id][$cid]) ? $response->answers[$this->id][$cid]->value : ''; + if (isset($odata)) { + $ovalue = stripslashes($odata); + } + $content = $othertext; + $cols[] = ['oname' => $oname, 'oid' => $oid, 'ovalue' => $ovalue,'colstyle' => 'text-align: '.$textalign.';', + 'coltext' => format_text($content, FORMAT_HTML, ['noclean' => true]).' ']; + } else { + $cols[] = ['colstyle' => 'text-align: '.$textalign.';', + 'coltext' => format_text($content, FORMAT_HTML, ['noclean' => true]).' ']; + } $bg = 'c0 raterow'; if (($nbchoices > 1) && !$this->no_duplicate_choices() && !$blankquestionnaire) { @@ -488,6 +501,12 @@ protected function response_survey_display($response) { if ($this->osgood_rate_scale()) { list($content, $contentright) = array_merge(preg_split('/[|]/', $content), array(' ')); } + if ($choice->is_other_choice()) { + $content = $choice->other_choice_display(); + if (isset($response->answers[$this->id][$cid]->otheresponse)) { + $rowobj->othercontent = $response->answers[$this->id][$cid]->otheresponse; + } + } $rowobj->content = format_text($content, FORMAT_HTML, ['noclean' => true]).' '; $bg = 'c0'; $cols = []; diff --git a/classes/responsetype/answer/answer.php b/classes/responsetype/answer/answer.php index 63de9f23..430e9ea5 100644 --- a/classes/responsetype/answer/answer.php +++ b/classes/responsetype/answer/answer.php @@ -45,20 +45,25 @@ class answer { /** @var string $value The value of this response (if applicable). */ public $value; + /** @var string $value The other value of this response (if applicable). */ + public $otheresponse; + /** * Answer constructor. * @param null $id * @param null $responseid * @param null $questionid * @param null $choiceid + * @param null $otheresponse * @param null $value */ - public function __construct($id = null, $responseid = null, $questionid = null, $choiceid = null, $value = null) { + public function __construct($id = null, $responseid = null, $questionid = null, $choiceid = null, $value = null, $otheresponse = null) { $this->id = $id; $this->responseid = $responseid; $this->questionid = $questionid; $this->choiceid = $choiceid; $this->value = $value; + $this->otheresponse = $otheresponse; } /** @@ -80,6 +85,6 @@ public static function create_from_data($answerdata) { } return new answer($answerdata['id'], $answerdata['responseid'], $answerdata['questionid'], $answerdata['choiceid'], - $answerdata['value']); + $answerdata['value'], $answerdata['otheresponse']); } } diff --git a/classes/responsetype/rank.php b/classes/responsetype/rank.php index 1e0c1f40..62b3ca95 100644 --- a/classes/responsetype/rank.php +++ b/classes/responsetype/rank.php @@ -132,6 +132,14 @@ public function insert_response($responsedata) { $record->choice_id = $answer->choiceid; $record->rankvalue = $answer->value; $resid = $DB->insert_record(static::response_table(), $record); + if (isset($responsedata->{$answer->choiceid . '_qother'})) { + $otherrecord = new \stdClass(); + $otherrecord->response_id = $response->id; + $otherrecord->question_id = $this->question->id; + $otherrecord->choice_id = $answer->choiceid; + $otherrecord->response = $responsedata->{$answer->choiceid . '_qother'}; + $DB->insert_record('questionnaire_response_other', $otherrecord); + } } } return $resid; @@ -153,7 +161,7 @@ public function get_results($rids=false, $anonymous=false) { $rsql = ' AND response_id ' . $rsql; } - $select = 'question_id=' . $this->question->id . ' AND content NOT LIKE \'!other%\' ORDER BY id ASC'; + $select = 'question_id=' . $this->question->id . ' ORDER BY id ASC'; if ($rows = $DB->get_records_select('questionnaire_quest_choice', $select)) { foreach ($rows as $row) { $this->counts[$row->content] = new \stdClass(); @@ -201,16 +209,25 @@ public function get_results($rids=false, $anonymous=false) { GROUP BY c2.id) a ON a.id = c.id order by c.id"; $results = $DB->get_records_sql($sql, array_merge(array($this->question->id, $this->question->id), $params)); - if (!empty ($rankvalue)) { - foreach ($results as $key => $result) { - if (isset($value[$key])) { - $result->averagevalue = $value[$key] / $result->num; + if (!empty($results)) { + $choiceids = array_keys($results); + $otherresultcontent = self::get_other_choice($choiceids); + if (!empty ($rankvalue)) { + foreach ($results as $key => $result) { + if (isset($value[$key])) { + $result->averagevalue = $value[$key] / $result->num; + } } } } // Reindex by 'content'. Can't do this from the query as it won't work with MS-SQL. foreach ($results as $key => $result) { $results[$result->content] = $result; + if ($result->id) { + if (isset($otherresultcontent[$result->id])) { + $results[$result->content]->content = $otherresultcontent[$result->id]; + } + } unset($results[$key]); } return $results; @@ -224,17 +241,63 @@ public function get_results($rids=false, $anonymous=false) { WHERE c2.question_id = ? AND a2.question_id = ? AND a2.choice_id = c2.id AND a2.rankvalue >= 0{$rsql} GROUP BY c2.id) a ON a.id = c.id"; $results = $DB->get_records_sql($sql, array_merge(array($this->question->id, $this->question->id), $params)); + if (!empty($results)) { + $choiceids = array_keys($results); + $otherresultcontent = self::get_other_choice($choiceids); + } + // Formula to calculate the best ranking order. $nbresponses = count($rids); foreach ($results as $key => $result) { - $result->average = ($result->sum + ($nbresponses - $result->num) * ($this->length + 1)) / $nbresponses; + if (isset($this->length)) { + $result->average = ($result->sum + ($nbresponses - $result->num) * ($this->length + 1)) / $nbresponses; + } else { + $result->average = ($result->sum + ($nbresponses - $result->num) * 1 ) / $nbresponses; + } $results[$result->content] = $result; + if (isset($otherresultcontent[$result->id])) { + $results[$result->content]->content = $otherresultcontent[$result->id]; + } unset($results[$key]); } return $results; } } + /** + * @param $choiceids + * @return array + */ + public function get_other_choice($choiceids) { + global $DB; + list($othersql, $params) = $DB->get_in_or_equal($choiceids); + $osql = "SELECT ro.*,rr.rankvalue FROM {questionnaire_response_other} ro + INNER JOIN {".static::response_table()."} rr ON ro.choice_id = rr.choice_id + AND ro.question_id = rr.question_id AND rr.response_id = ro.response_id + WHERE ro.choice_id $othersql + "; + $otheresults = $DB->get_records_sql($osql, $params); + $otherresultcontent = []; + if (!empty($otheresults)) { + foreach ($otheresults as $key => $oresult) { + if (array_key_last($otheresults) == $key) { + if (isset($otherresultcontent[$oresult->choice_id])) { + $otherresultcontent[$oresult->choice_id] .= $oresult->response . '(' . $oresult->rankvalue . ')'; + } else { + $otherresultcontent[$oresult->choice_id] = $oresult->response . '(' . $oresult->rankvalue . ')'; + } + } else { + if (isset($otherresultcontent[$oresult->choice_id])) { + $otherresultcontent[$oresult->choice_id] .= $oresult->response . '(' . $oresult->rankvalue . '), '; + } else { + $otherresultcontent[$oresult->choice_id] = $oresult->response . '(' . $oresult->rankvalue . '), '; + } + } + } + } + return $otherresultcontent; + } + /** * Provide the feedback scores for all requested response id's. This should be provided only by questions that provide feedback. * @param array $rids @@ -415,9 +478,11 @@ public static function response_answers_by_question($rid) { global $DB; $answers = []; - $sql = 'SELECT id, response_id as responseid, question_id as questionid, choice_id as choiceid, rankvalue as value ' . - 'FROM {' . static::response_table() .'} ' . - 'WHERE response_id = ? '; + $sql = 'SELECT r.id, r.response_id as responseid, r.question_id as questionid, r.choice_id as choiceid, r.rankvalue as value, rt.response as otheresponse ' . + 'FROM {' . static::response_table() .'} r ' . + 'LEFT JOIN {questionnaire_response_other} rt ON rt.choice_id = r.choice_id + AND r.question_id = rt.question_id AND r.response_id = rt.response_id' . + ' WHERE r.response_id = ? '; $records = $DB->get_records_sql($sql, [$rid]); foreach ($records as $record) { $answers[$record->questionid][$record->choiceid] = answer\answer::create_from_data($record); @@ -635,6 +700,9 @@ private function mkresavg($sort, $stravgvalue='') { $content = $contents->text; } } + if (\mod_questionnaire\question\choice\choice::content_other_choice_display($content)) { + $content = \mod_questionnaire\question\choice\choice::content_other_choice_display($content); + } if ($osgood) { $choicecol1 = new \stdClass(); $choicecol1->width = $header1->width; @@ -892,6 +960,10 @@ private function mkrescount($rids, $rows, $sort) { // Ensure there are two bits of content. list($content, $contentright) = array_merge(preg_split('/[|]/', $content), array(' ')); $header = reset($pagetags->totals->headers); + $responsetxt = \mod_questionnaire\question\choice\choice::content_other_choice_display($content); + if (isset($rows[$content]) && $responsetxt) { + $content = $responsetxt . $rows[$content]->content; + } $totalcols[] = (object)['align' => $header->align, 'text' => format_text($content, FORMAT_HTML, ['noclean' => true])]; } else { @@ -900,6 +972,10 @@ private function mkrescount($rids, $rows, $sort) { if ($contents->modname) { $content = $contents->text; } + $responsetxt = \mod_questionnaire\question\choice\choice::content_other_choice_display($content); + if (isset($rows[$content]) && $responsetxt) { + $content = $responsetxt . $rows[$content]->content; + } $header = reset($pagetags->totals->headers); $totalcols[] = (object)['align' => $header->align, 'text' => format_text($content, FORMAT_HTML, ['noclean' => true])]; diff --git a/templates/question_rate.mustache b/templates/question_rate.mustache index 069dd6e2..fc9c1e0d 100644 --- a/templates/question_rate.mustache +++ b/templates/question_rate.mustache @@ -138,6 +138,7 @@