Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion classes/privacy/provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements
\core_privacy\local\request\core_userlist_provider,
\core_privacy\local\metadata\provider,
\core_privacy\local\request\core_userlist_provider,
\core_privacy\local\request\plugin\provider {
/**
* Returns meta data about this system.
Expand Down
1 change: 1 addition & 0 deletions drawchart.php
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ function draw_chart(
$maxlen = $labellen;
}
}
$output = [];
foreach ($labels as $value) {
$output[] = '"' . $value . '"';
}
Expand Down
36 changes: 24 additions & 12 deletions questionnaire.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,16 +133,26 @@ public function get_delete_questions() {
}
}

/**
* Returns a survey record.
*
* @param int $id
* @return false|mixed|stdClass
* @throws dml_exception
*/
private function get_survey(int $id): mixed {
global $DB;
return $DB->get_record('questionnaire_survey', ['id' => $id]);
}

/**
* Adding a survey record to the object.
* @param int $sid
* @param null $survey
*/
public function add_survey($sid = 0, $survey = null) {
global $DB;

if ($sid) {
$this->survey = $DB->get_record('questionnaire_survey', ['id' => $sid]);
$this->survey = $this->get_survey($sid);
} else if (is_object($survey)) {
$this->survey = clone($survey);
}
Expand Down Expand Up @@ -422,7 +432,7 @@ private function update_grades($userid) {
* Function to view an entire responses data.
* @param int $rid
* @param string $referer
* @param string $resps
* @param array $resps
* @param bool $compare
* @param bool $isgroupmember
* @param bool $allresponses
Expand All @@ -432,7 +442,7 @@ private function update_grades($userid) {
public function view_response(
$rid,
$referer = '',
$resps = '',
$resps = [],
$compare = false,
$isgroupmember = false,
$allresponses = false,
Expand Down Expand Up @@ -1865,6 +1875,7 @@ public function survey_update($sdata) {
$errstr = get_string('warning', 'questionnaire') . ' [ : ]'; // TODO: notused!
return(false);
}
$this->survey = $this->get_survey($this->survey->id);
}

return($this->survey->id);
Expand Down Expand Up @@ -3556,7 +3567,7 @@ public function generate_csv(
'0', // 11: slider -> number.
];

if (!$survey = $DB->get_record('questionnaire_survey', ['id' => $this->survey->id])) {
if (!$survey = $this->get_survey($this->survey->id)) {
throw new \moodle_exception('surveynotexists', 'mod_questionnaire');
}

Expand Down Expand Up @@ -4010,11 +4021,11 @@ public function move_question($moveqid, $movetopos) {
*/
public function response_analysis(
$rid,
$resps,
$compare,
$isgroupmember,
$allresponses,
$currentgroupid,
$resps = [],
$compare = false,
$isgroupmember = false,
$allresponses = false,
$currentgroupid = 0,
$filteredsections = null
) {
global $DB, $CFG;
Expand Down Expand Up @@ -4128,6 +4139,7 @@ public function response_analysis(
$allscorepercent = round($alltotalscore / $nbparticipants / $maxtotalscore * 100);

// No need to go further if feedback is global, i.e. only relying on total score.
$sectionlabel = '';
if ($this->survey->feedbacksections == 1) {
$sectionid = $fbsectionsnb[0];
$sectionlabel = $fbsections[$sectionid]->sectionlabel;
Expand Down Expand Up @@ -4214,7 +4226,7 @@ public function response_analysis(
$oppositescore = ' | ' . $score[1] . '%';
$oppositeallscore = ' | ' . $allscore[1] . '%';
}
if ($this->survey->feedbackscores) {
if ($this->survey->feedbackscores && !empty($allscore)) {
$table = $table ?? new html_table();
if ($compare) {
$table->data[] = [$sectionlabel, $score[0] . '%' . $oppositescore, $allscore[0] . '%' . $oppositeallscore];
Expand Down
118 changes: 118 additions & 0 deletions tests/responsetypes_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -486,4 +486,122 @@ public function test_create_old_response_boolean(): void {
$this->assertEmpty($boolresponseresult1);
$this->assertEmpty($boolresponseresult2);
}

/**
* Tests the questionnaire response_analysis method.
*
* @covers \questionnaire::response_analysis
*/
public function test_response_analysis(): void {
global $PAGE, $SESSION, $questionnaire;

$this->resetAfterTest();

// Set settings etc.
set_config('usergraph', '1', 'questionnaire');
$SESSION->questionnaire = new \stdClass();
$SESSION->questionnaire->current_tab = 'myreport';

// Create questinnaire with one boolean response question.
$userid = 1;
$course = $this->getDataGenerator()->create_course();
$generator = $this->getDataGenerator()->get_plugin_generator('mod_questionnaire');
$questionnaire = $generator->create_test_questionnaire(
$course,
QUESYESNO,
['content' => 'Enter yes or no', 'required' => 'y']
);
$question = reset($questionnaire->questions);
$generator->create_question_response($questionnaire, $question, 'y', $userid);

$questionnaire->add_renderer($PAGE->get_renderer('mod_questionnaire'));
$questionnaire->add_page(new output\feedbackpage());

// Add feedback section.
$fbsection = feedback\section::new_section($questionnaire->sid, 'FB section 1');
$feedback = new feedback\sectionfeedback();
$feedback->sectionid = $fbsection->id;
$feedback->feedbacklabel = 'FB label 1';
$feedback->feedbacktext = 'FB text 1';
$feedback->maxscore = 101.0;
$feedback = feedback\sectionfeedback::new_sectionfeedback($feedback);

$survey = clone($questionnaire->survey);
$survey->sid = $questionnaire->survey->id;

// Test options for No Feedback.
$survey->feedbacksections = 0;
$survey->feedbackscores = 0;
$this->do_response_analysis($questionnaire, $survey, $feedback, $userid);

// Test options for Global Feedback.
$survey->feedbacksections = 1;
// Check without scores and chart type.
$survey->feedbackscores = 0;
$survey->chart_type = '';
$this->do_response_analysis($questionnaire, $survey, $feedback, $userid);
// Check with scores and chart type.
$survey->feedbackscores = 1;
$survey->chart_type = 'bipolar';
$this->do_response_analysis($questionnaire, $survey, $feedback, $userid);
// Check with question.
$this->do_response_analysis($questionnaire, $survey, $feedback, $userid, $question, $fbsection);

// Test options for Feedback sections.
$survey->feedbacksections = 2;
// Check without scores and chart type.
$survey->feedbackscores = 0;
$survey->chart_type = '';
$this->do_response_analysis($questionnaire, $survey, $feedback, $userid);
// Check with scores and chart type.
$survey->feedbackscores = 1;
$survey->chart_type = 'hbar';
$this->do_response_analysis($questionnaire, $survey, $feedback, $userid);
// Check with question.
$this->do_response_analysis($questionnaire, $survey, $feedback, $userid, $question, $fbsection);
}

/**
* Runs and checks the response_analysis method.
*
* @param \questionnaire $questionnaire
* @param stdClass $survey
* @param feedback\sectionfeedback $feedback
* @param int $userid
* @param question\question $question
* @param feedback\section $fbsection
*/
private function do_response_analysis(
$questionnaire,
$survey,
$feedback,
$userid,
$question = null,
$fbsection = null
): void {
$questionnaire->survey_update($survey);

if ($fbsection != null) {
if ($question != null) {
// Add question to section score calculation.
$scorecalculation = [$question->id => 1];
$fbsection->set_new_scorecalculation($scorecalculation);
} else {
// Clear section score calculation.
$fbsection->set_new_scorecalculation([]);
}
$fbsection->update();
}

// Get and check responses.
$resps = $questionnaire->get_responses($userid);
$this->assertCount(1, $resps, 'Questionnaire responses');
$rids = array_keys($resps);
$rid = end($rids);

// Get and check response analysis.
$feedbackmessages = $questionnaire->response_analysis($rid, $resps);
$this->assertNotEmpty($feedbackmessages);
$this->assertContains($feedback->feedbacktext, $feedbackmessages, 'Feedback message');
}
}