diff --git a/drawchart.php b/drawchart.php
index ab50fe83..3a7d9f31 100644
--- a/drawchart.php
+++ b/drawchart.php
@@ -64,6 +64,7 @@ function draw_chart($feedbacktype, $labels, $groupname,
// We do not have labels other than global in this feedback type.
if ($feedbacktype == 'global') {
+ $globallabel = (string) $globallabel;
$labels = array($globallabel);
}
diff --git a/lang/en/questionnaire.php b/lang/en/questionnaire.php
index e28d9352..d9cd756c 100644
--- a/lang/en/questionnaire.php
+++ b/lang/en/questionnaire.php
@@ -709,3 +709,13 @@
$string['crontask'] = 'Questionnaire cleanup job';
$string['nopermissions'] = 'Sorry, but you do not currently have permissions to view this page or perform this action.';
$string['unanswered'] = 'Unanswered';
+
+// Expanded Exception messages.
+$string['groupaccessdenied'] = 'You do not belong to a group allowed to view these responses.';
+$string['noresponsesavailable'] = 'There are no responses available to view at this time.';
+$string['cannotviewduetorestrictions'] = 'You cannot view responses due to questionnaire restrictions or required completion.';
+$string['questionnaireneotopen'] = 'This questionnaire will open on {$a}.';
+$string['questionnaireclosed'] = 'This questionnaire closed on {$a}.';
+$string['mustcompletebeforeviewing'] = 'You must complete this questionnaire before viewing any responses.';
+$string['missingcapability'] = 'You do not have the required capability (mod/questionnaire:readallresponses) to view these responses.';
+$string['privateorTemplateError'] = 'This questionnaire is private or a template and cannot be accessed for responses.';
diff --git a/lib.php b/lib.php
index 8b2c5fc8..89a74147 100644
--- a/lib.php
+++ b/lib.php
@@ -718,8 +718,8 @@ function questionnaire_extend_settings_navigation(settings_navigation $settings,
// If questionnaire is set to separate groups, prevent user who is not member of any group
// and is not a non-editing teacher to view All responses.
- if ($questionnaire->can_view_all_responses($usernumresp)) {
-
+ $viewallresponses = $questionnaire->can_view_all_responses($usernumresp);
+ if (!empty($viewallresponses) && $viewallresponses->allowed) {
$url = '/mod/questionnaire/report.php';
$node = navigation_node::create(get_string('viewallresponses', 'questionnaire'),
new moodle_url($url, array('instance' => $questionnaire->id, 'action' => 'vall')),
diff --git a/questionnaire.class.php b/questionnaire.class.php
index 5fd3bebe..fc4ab4a2 100644
--- a/questionnaire.class.php
+++ b/questionnaire.class.php
@@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
+use core_reportbuilder\external\columns\sort\get;
use mod_questionnaire\feedback\section;
defined('MOODLE_INTERNAL') || die();
@@ -712,37 +713,99 @@ public function can_view_response($rid) {
*
* @param null|int $usernumresp
* @param bool $isviewreport
- * @return bool
+ * @return object
+ * @throws \coding_exception
+ * @throws \dml_exception
*/
public function can_view_all_responses($usernumresp = null, $isviewreport = false) {
global $USER, $SESSION;
$owner = $this->is_survey_owner();
$numresp = $this->count_submissions();
+
if ($usernumresp === null) {
$usernumresp = $this->count_submissions($USER->id);
}
- // Number of Responses in currently selected group (or all participants etc.).
+ // If the user has not submitted any responses, then they cannot view responses.
if (isset($SESSION->questionnaire->numselectedresps)) {
$numselectedresps = $SESSION->questionnaire->numselectedresps;
} else {
$numselectedresps = $numresp;
}
- // If questionnaire is set to separate groups, prevent user who is not member of any group
- // to view All responses.
- $canviewgroups = true;
- $canviewallgroups = has_capability('moodle/site:accessallgroups', $this->context);
+ // Verify that the user belongs to a group that can view the questionnaire.
$groupmode = groups_get_activity_groupmode($this->cm, $this->course);
- if ($groupmode == 1) {
+ $canviewallgroups = has_capability('moodle/site:accessallgroups', $this->context);
+ $canviewgroups = true;
+
+ // If the questionnaire is not owned by the course, then we cannot view responses.
+ if ($groupmode == SEPARATEGROUPS) {
$canviewgroups = groups_has_membership($this->cm, $USER->id);
+ if (!$canviewgroups && !$canviewallgroups) {
+ return (object)[
+ 'allowed' => false,
+ 'reason' => get_string('groupaccessdenied', 'mod_questionnaire'),
+ ];
+ }
+ }
+
+ // If the questionnaire is not open yet, or has been closed, then we cannot view responses.
+ if (empty($this->is_open())) {
+ return (object)[
+ 'allowed' => false,
+ 'reason' => get_string('questionnaireneotopen', 'mod_questionnaire', userdate($this->open))
+ ];
+ }
+ if (!empty($this->is_closed())) {
+ return (object)[
+ 'allowed' => false,
+ 'reason' => get_string('questionnaireclosed', 'mod_questionnaire', userdate($this->close))
+ ];
+ }
+
+ // Verify that the user has the capability to read all responses.
+ if ($this->resume == 1 && $usernumresp == 0) {
+ return (object)[
+ 'allowed' => false,
+ 'reason' => get_string('mustcompletebeforeviewing', 'mod_questionnaire')
+ ];
+ }
+
+ // Verify that the user has the capability to read all responses.
+ if (!has_capability('mod/questionnaire:readallresponses', $this->context)) {
+ return (object)[
+ 'allowed' => false,
+ 'reason' => get_string('missingcapability', 'mod_questionnaire')
+ ];
+ }
+
+ // Verify that there are responses to view.
+ if (($numresp <= 0 || $numselectedresps <= 0) && !$isviewreport) {
+ return (object)[
+ 'allowed' => false,
+ 'reason' => get_string('noresponsesavailable', 'mod_questionnaire')
+ ];
}
$grouplogic = $canviewgroups || $canviewallgroups;
- $respslogic = ($numresp > 0) && ($numselectedresps > 0) || $isviewreport;
- return $this->can_view_all_responses_anytime($grouplogic, $respslogic) ||
- $this->can_view_all_responses_with_restrictions($usernumresp, $grouplogic, $respslogic);
+ $respslogic = ($numresp > 0 && $numselectedresps > 0) || $isviewreport;
+
+ // If the user can view all responses any time, then they can view them.
+ if ($this->can_view_all_responses_anytime($grouplogic, $respslogic)) {
+ return (object)['allowed' => true];
+ }
+
+ // If the user can't view all responses with restrictions.
+ if (!$this->can_view_all_responses_with_restrictions($usernumresp, $grouplogic, $respslogic)) {
+ return (object)[
+ 'allowed' => false,
+ 'reason' => get_string('cannotviewduetorestrictions', 'mod_questionnaire')
+ ];
+ }
+
+ // If we got here, then the user can view the responses.
+ return (object)['allowed' => true];
}
/**
diff --git a/report.php b/report.php
index 5c81c84a..d7727ac5 100755
--- a/report.php
+++ b/report.php
@@ -88,9 +88,16 @@
// If you can't view the questionnaire, or can't view a specified response, error out.
$context = context_module::instance($cm->id);
-if (!$questionnaire->can_view_all_responses(null, true) && !$individualresponse) {
+$viewallresponses = $questionnaire->can_view_all_responses(null, true);
+if (!$viewallresponses->allowed && !$individualresponse) {
// Should never happen, unless called directly by a snoop...
- throw new \moodle_exception('nopermissions', 'mod_questionnaire');
+ throw new \moodle_exception(
+ 'nopermissions',
+ 'mod_questionnaire',
+ $CFG->wwwroot.'/mod/questionnaire/view.php?id='.$cm->id,
+ $viewallresponses->reason ?? get_string('viewallresponses', 'mod_questionnaire'),
+ 'mod/questionnaire:readallresponses'
+ );
}
$questionnaire->canviewallgroups = has_capability('moodle/site:accessallgroups', $context);
diff --git a/version.php b/version.php
index 43f382ac..ffa48dfa 100644
--- a/version.php
+++ b/version.php
@@ -25,10 +25,9 @@
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2022121601.01; // The current module version (Date: YYYYMMDDXX).
-$plugin->requires = 2024042200.00; // Moodle version (4.4.0).
+$plugin->version = 2022121601.02; // The current module version (Date: YYYYMMDDXX).
+$plugin->requires = 2024042200.00; // Moodle version (4.4.0).
$plugin->component = 'mod_questionnaire';
-
-$plugin->release = '4.4.0 (Build - 2024082900)';
+$plugin->release = '4.5.0 (Build - 2024082901)';
$plugin->maturity = MATURITY_BETA;
diff --git a/view.php b/view.php
index c0181ce5..df0e95ff 100644
--- a/view.php
+++ b/view.php
@@ -142,7 +142,8 @@
'" class="btn btn-primary">' . $titletext . '');
}
-if ($questionnaire->can_view_all_responses($usernumresp)) {
+$viewallresponses = $questionnaire->can_view_all_responses($usernumresp);
+if ($viewallresponses->allowed) {
$argstr = 'instance='.$questionnaire->id.'&group='.$currentgroupid;
$questionnaire->page->add_to_page('allresponses',
''.