From bbf4f440eead3af53eed772c7e68966fb4f6dc31 Mon Sep 17 00:00:00 2001 From: jamiesensei Date: Tue, 25 Nov 2008 12:11:27 +0000 Subject: [PATCH] MDL-15326 "allow for per report capabilities to replace mod/quiz:viewreports" --- lang/en_utf8/quiz.php | 2 + lang/en_utf8/quiz_statistics.php | 2 + lib/accesslib.php | 15 ++++++- mod/quiz/db/access.php | 15 ++++++- mod/quiz/db/install.xml | 6 +-- mod/quiz/db/upgrade.php | 15 +++++++ mod/quiz/lib.php | 3 ++ mod/quiz/report.php | 16 ++++++-- mod/quiz/report/overview/overview_table.php | 6 +-- .../report/overview/overviewsettings_form.php | 2 +- mod/quiz/report/overview/report.php | 10 ++--- mod/quiz/report/reportlib.php | 41 +++++++++++++++++++ mod/quiz/report/statistics/db/access.php | 20 +++++++++ mod/quiz/report/statistics/db/install.xml | 9 +++- mod/quiz/report/statistics/db/upgrade.php | 5 +++ .../report/statistics/statistics_graph.php | 2 +- mod/quiz/report/statistics/version.php | 2 +- mod/quiz/review.php | 1 + mod/quiz/tabs.php | 35 ++++------------ mod/quiz/version.php | 2 +- 20 files changed, 161 insertions(+), 48 deletions(-) create mode 100644 mod/quiz/report/statistics/db/access.php diff --git a/lang/en_utf8/quiz.php b/lang/en_utf8/quiz.php index 34ac45b3b9..cc00cb7f2f 100644 --- a/lang/en_utf8/quiz.php +++ b/lang/en_utf8/quiz.php @@ -253,6 +253,7 @@ You can review this attempt at $a->quizreviewurl.'; $string['emailnotifysubject'] = '$a->studentname has completed quiz $a->quizname'; $string['empty'] = 'Empty'; $string['endtest'] = 'End test ...'; +$string['erroraccessingreport'] = 'You cannot access this report'; $string['errorinquestion'] = 'Error in question'; $string['errormissingquestion'] = 'Error: The system is missing the question with id $a'; $string['errornotnumbers'] = 'Error - answers must be numeric'; @@ -518,6 +519,7 @@ $string['quiz:grade'] = 'Grade quizzes manually'; $string['quiz:ignoretimelimits'] = 'Ignores time limit on quizzes'; $string['quiz:manage'] = 'Manage quizzes'; $string['quiz:preview'] = 'Preview quizzes'; +$string['quiz:regrade'] = 'Regrade quiz attempts'; $string['quiz:view'] = 'View quiz information'; $string['quiz:viewreports'] = 'View quiz reports'; $string['quizavailable'] = 'The quiz is available until: $a'; diff --git a/lang/en_utf8/quiz_statistics.php b/lang/en_utf8/quiz_statistics.php index d8de227c2b..1b38d9bee9 100644 --- a/lang/en_utf8/quiz_statistics.php +++ b/lang/en_utf8/quiz_statistics.php @@ -3,6 +3,8 @@ $string['statistics'] = 'Statistics'; +$string['statistics:view'] = 'View statistics report'; +$string['statistics:componentname'] = 'Quiz statistics report'; $string['statisticsreport'] = 'Statistics report'; $string['calculatefrom'] = 'Calculate statistics from'; diff --git a/lib/accesslib.php b/lib/accesslib.php index d668a63913..8160cced27 100755 --- a/lib/accesslib.php +++ b/lib/accesslib.php @@ -3053,6 +3053,10 @@ function load_capability_def($component) { $defpath = $CFG->dirroot.'/grade/report/'.$compparts[1].'/db/access.php'; $varprefix = $compparts[0].'_'.$compparts[1]; + } else if ($compparts[0] == 'quizreport') { + $defpath = $CFG->dirroot.'/mod/quiz/report/'.$compparts[1].'/db/access.php'; + $varprefix = $compparts[0].'_'.$compparts[1]; + } else { $defpath = $CFG->dirroot.'/'.$component.'/db/access.php'; $varprefix = str_replace('/', '_', $component); @@ -3916,6 +3920,10 @@ function get_capability_string($capabilityname) { $string = get_string($stringname, 'gradereport_'.$componentname); break; + case 'quizreport': + $string = get_string($stringname, 'quiz_'.$componentname); + break; + default: $string = get_string($stringname); break; @@ -3972,7 +3980,12 @@ function get_component_string($component, $contextlevel) { break; case CONTEXT_MODULE: - $string = get_string('modulename', basename($component)); + if (preg_match('|^quizreport/([a-z_]*)|', $component, $matches)){ + $langname = 'quiz_'.$matches[1]; + $string = get_string($matches[1].':componentname', $langname); + } else { + $string = get_string('modulename', basename($component)); + } break; case CONTEXT_BLOCK: diff --git a/mod/quiz/db/access.php b/mod/quiz/db/access.php index 9d5adbb816..41c82d393f 100644 --- a/mod/quiz/db/access.php +++ b/mod/quiz/db/access.php @@ -51,7 +51,7 @@ $mod_quiz_capabilities = array( ) ), - // Manually grade and comment on student attempts at a question, and regrade quizzes. + // Manually grade and comment on student attempts at a question. 'mod/quiz:grade' => array( 'riskbitmask' => RISK_SPAM | RISK_XSS, 'captype' => 'write', @@ -63,6 +63,19 @@ $mod_quiz_capabilities = array( ) ), + // Regrade quizzes. + 'mod/quiz:regrade' => array( + 'riskbitmask' => RISK_SPAM | RISK_XSS, + 'captype' => 'write', + 'contextlevel' => CONTEXT_MODULE, + 'legacy' => array( + 'teacher' => CAP_ALLOW, + 'editingteacher' => CAP_ALLOW, + 'admin' => CAP_ALLOW + ), + 'clonepermissionsfrom' => 'mod/quiz:grade' + ), + // View the quiz reports. 'mod/quiz:viewreports' => array( 'riskbitmask' => RISK_PERSONAL, diff --git a/mod/quiz/db/install.xml b/mod/quiz/db/install.xml index a78bc5c647..0901e614a4 100755 --- a/mod/quiz/db/install.xml +++ b/mod/quiz/db/install.xml @@ -1,5 +1,5 @@ - @@ -112,7 +112,8 @@ - + + @@ -140,7 +141,6 @@ - diff --git a/mod/quiz/db/upgrade.php b/mod/quiz/db/upgrade.php index 1d5ede21df..a72b24718d 100644 --- a/mod/quiz/db/upgrade.php +++ b/mod/quiz/db/upgrade.php @@ -196,6 +196,21 @@ function xmldb_quiz_upgrade($oldversion) { // question type, this is now a no-op. upgrade_mod_savepoint($result, 2008082600, 'quiz'); } + + if ($result && $oldversion < 2008112101) { + + /// Define field lastcron to be added to quiz_report + $table = new xmldb_table('quiz_report'); + $field = new xmldb_field('capability', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null, 'cron'); + + /// Conditionally launch add field lastcron + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + /// quiz savepoint reached + upgrade_mod_savepoint($result, 2008112101, 'quiz'); + } return $result; } diff --git a/mod/quiz/lib.php b/mod/quiz/lib.php index 95f97aa0d1..906879f566 100644 --- a/mod/quiz/lib.php +++ b/mod/quiz/lib.php @@ -1277,7 +1277,10 @@ function quiz_supports($feature) { * @return array all other caps used in module */ function quiz_get_extra_capabilities() { + global $DB; $caps = question_get_all_capabilities(); + $reportcaps = $DB->get_records_select_menu('capabilities', 'name LIKE ?', array('quizreport/%'), 'id,name'); + $caps = array_merge($caps, $reportcaps); $caps[] = 'moodle/site:accessallgroups'; return $caps; } diff --git a/mod/quiz/report.php b/mod/quiz/report.php index f3260013ba..8ef7462852 100644 --- a/mod/quiz/report.php +++ b/mod/quiz/report.php @@ -9,7 +9,7 @@ $id = optional_param('id',0,PARAM_INT); // Course Module ID, or $q = optional_param('q',0,PARAM_INT); // quiz ID - $mode = optional_param('mode', 'overview', PARAM_ALPHA); // Report mode + $mode = optional_param('mode', '', PARAM_ALPHA); // Report mode if ($id) { if (! $cm = get_coursemodule_from_id('quiz', $id)) { @@ -36,10 +36,20 @@ } } + require_login($course, false, $cm); $context = get_context_instance(CONTEXT_MODULE, $cm->id); - require_capability('mod/quiz:viewreports', $context); - + + $reportlist = quiz_report_list($context); + if (count($reportlist)==0){ + print_error('erroraccessingreport', 'quiz'); + } + if ($mode == ''){ + $mode = reset($reportlist);//first element in array + } elseif (!in_array($mode, $reportlist)){ + print_error('erroraccessingreport', 'quiz'); + } + // if no questions have been set up yet redirect to edit.php if (!$quiz->questions and has_capability('mod/quiz:manage', $context)) { redirect('edit.php?cmid='.$cm->id); diff --git a/mod/quiz/report/overview/overview_table.php b/mod/quiz/report/overview/overview_table.php index 99e6dc49d9..31c25d6d9f 100644 --- a/mod/quiz/report/overview/overview_table.php +++ b/mod/quiz/report/overview/overview_table.php @@ -94,7 +94,7 @@ class quiz_report_overview_table extends table_sql { echo ''. get_string('selectnone', 'quiz').' '; echo '  '; - if (has_capability('mod/quiz:grade', $this->context)){ + if (has_capability('mod/quiz:regrade', $this->context)){ echo ''; } echo ''; @@ -317,12 +317,12 @@ class quiz_report_overview_table extends table_sql { } } $this->gradedstatesbyattempt = quiz_get_newgraded_states($attemptids, true, 'qs.id, qs.grade, qs.event, qs.question, qs.attempt'); - if (has_capability('mod/quiz:grade', $this->context)){ + if (has_capability('mod/quiz:regrade', $this->context)){ $this->regradedqs = quiz_get_regraded_qs($attemptids); } } else { $this->gradedstatesbyattempt = quiz_get_newgraded_states($this->sql, true, 'qs.id, qs.grade, qs.event, qs.question, qs.attempt'); - if (has_capability('mod/quiz:grade', $this->context)){ + if (has_capability('mod/quiz:regrade', $this->context)){ $this->regradedqs = quiz_get_regraded_qs($this->sql); } } diff --git a/mod/quiz/report/overview/overviewsettings_form.php b/mod/quiz/report/overview/overviewsettings_form.php index ea778f4fb3..ed2690a64f 100644 --- a/mod/quiz/report/overview/overviewsettings_form.php +++ b/mod/quiz/report/overview/overviewsettings_form.php @@ -37,7 +37,7 @@ class mod_quiz_report_overview_settings extends moodleform { $gm = ''.quiz_get_grading_option_name($this->_customdata['quiz']->grademethod).''; $showattemptsgrp[] =& $mform->createElement('advcheckbox', 'qmfilter', get_string('showattempts', 'quiz_overview'), get_string('optonlygradedattempts', 'quiz_overview', $gm), null, array(0,1)); } - if (has_capability('mod/quiz:grade', $this->_customdata['context'])){ + if (has_capability('mod/quiz:regrade', $this->_customdata['context'])){ $showattemptsgrp[] =& $mform->createElement('advcheckbox', 'regradefilter', get_string('showattempts', 'quiz_overview'), get_string('optonlyregradedattempts', 'quiz_overview'), null, array(0,1)); } if ($showattemptsgrp){ diff --git a/mod/quiz/report/overview/report.php b/mod/quiz/report/overview/report.php index 3f2ebe002c..461fe566d0 100644 --- a/mod/quiz/report/overview/report.php +++ b/mod/quiz/report/overview/report.php @@ -278,7 +278,7 @@ class quiz_overview_report extends quiz_default_report { $headers = array(); if (!$table->is_downloading()) { //do not print notices when downloading //regrade buttons - if (has_capability('mod/quiz:grade', $this->context)){ + if (has_capability('mod/quiz:regrade', $this->context)){ $countregradeneeded = $this->count_regrade_all_needed($quiz, $groupstudents); if ($currentgroup){ $a= new object(); @@ -359,7 +359,7 @@ class quiz_overview_report extends quiz_default_report { $headers[] = $header; } } - if (!$table->is_downloading() && has_capability('mod/quiz:grade', $this->context) && $regradedattempts){ + if (!$table->is_downloading() && has_capability('mod/quiz:regrade', $this->context) && $regradedattempts){ $columns[] = 'regraded'; $headers[] = get_string('regrade', 'quiz_overview'); } @@ -424,7 +424,7 @@ class quiz_overview_report extends quiz_default_report { */ function regrade_all($dry, $quiz, $groupstudents){ global $DB; - if (!has_capability('mod/quiz:grade', $this->context)) { + if (!has_capability('mod/quiz:regrade', $this->context)) { notify(get_string('regradenotallowed', 'quiz')); return true; } @@ -507,7 +507,7 @@ class quiz_overview_report extends quiz_default_report { } function regrade_all_needed($quiz, $groupstudents){ global $DB; - if (!has_capability('mod/quiz:grade', $this->context)) { + if (!has_capability('mod/quiz:regrade', $this->context)) { notify(get_string('regradenotallowed', 'quiz')); return; } @@ -636,7 +636,7 @@ class quiz_overview_report extends quiz_default_report { } function regrade_selected_attempts($quiz, $attemptids, $groupstudents){ global $DB; - require_capability('mod/quiz:grade', $this->context); + require_capability('mod/quiz:regrade', $this->context); if ($groupstudents){ list($usql, $params) = $DB->get_in_or_equal($groupstudents); $where = "qa.userid $usql AND "; diff --git a/mod/quiz/report/reportlib.php b/mod/quiz/report/reportlib.php index 71a167945d..54feb712ea 100644 --- a/mod/quiz/report/reportlib.php +++ b/mod/quiz/report/reportlib.php @@ -343,4 +343,45 @@ function quiz_report_scale_sumgrades_as_percentage($rawgrade, $quiz, $round = tr } return $grade.'%'; } +/** + * Returns an array of reports to which the current user has access to. + * Reports are ordered as they should be for display in tabs. + */ +function quiz_report_list($context){ + global $DB; + static $reportlist = null; + if (!is_null($reportlist)){ + return $reportlist; + } + $reports = $DB->get_records('quiz_report', null, 'displayorder DESC', 'name, capability'); + + $reportdirs = get_list_of_plugins("mod/quiz/report"); + //order the reports tab in descending order of displayorder + $reportcaps = array(); + if ($reports){ + foreach ($reports as $key => $obj) { + if (in_array($obj->name, $reportdirs)) { + $reportcaps[$obj->name]=$obj->capability; + } + } + } + + //add any other reports on the end + foreach ($reportdirs as $reportname) { + if (!isset($reportcaps[$reportname])) { + $reportcaps[$reportname]= null; + } + } + $reportlist = array(); + foreach ($reportcaps as $name => $capability){ + if (empty($capability)){ + $capability = 'mod/quiz:viewreports'; + } + if ($has = has_capability($capability, $context)){ + $reportlist[] = $name; + } + } + return $reportlist; +} + ?> diff --git a/mod/quiz/report/statistics/db/access.php b/mod/quiz/report/statistics/db/access.php new file mode 100644 index 0000000000..b9c3839772 --- /dev/null +++ b/mod/quiz/report/statistics/db/access.php @@ -0,0 +1,20 @@ + array( + 'captype' => 'read', + 'contextlevel' => CONTEXT_MODULE, + 'legacy' => array( + 'teacher' => CAP_ALLOW, + 'editingteacher' => CAP_ALLOW, + 'admin' => CAP_ALLOW + ), + 'clonepermissionsfrom' => 'mod/quiz:viewreports' + ) +); +?> + diff --git a/mod/quiz/report/statistics/db/install.xml b/mod/quiz/report/statistics/db/install.xml index 6610052e61..d6812e7eac 100644 --- a/mod/quiz/report/statistics/db/install.xml +++ b/mod/quiz/report/statistics/db/install.xml @@ -1,5 +1,5 @@ - @@ -64,4 +64,11 @@ + + + + + + + \ No newline at end of file diff --git a/mod/quiz/report/statistics/db/upgrade.php b/mod/quiz/report/statistics/db/upgrade.php index a889be710c..ef98018365 100644 --- a/mod/quiz/report/statistics/db/upgrade.php +++ b/mod/quiz/report/statistics/db/upgrade.php @@ -134,6 +134,11 @@ function xmldb_quizreport_statistics_upgrade($oldversion) { } } } + + + if ($result && $oldversion < 2008112100) { + $result = $result && $DB->set_field('quiz_report', 'capability', 'quizreport/statistics:view', array('name'=>'statistics')); + } return $result; } diff --git a/mod/quiz/report/statistics/statistics_graph.php b/mod/quiz/report/statistics/statistics_graph.php index e922c01057..9283d07425 100644 --- a/mod/quiz/report/statistics/statistics_graph.php +++ b/mod/quiz/report/statistics/statistics_graph.php @@ -32,7 +32,7 @@ if ($quizstatistics->groupid){ } } $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id); -require_capability('mod/quiz:viewreports', $modcontext); +require_capability('quizreport/statistics:view', $modcontext); $line = new graph(800,600); $line->parameter['title'] = ''; diff --git a/mod/quiz/report/statistics/version.php b/mod/quiz/report/statistics/version.php index 53af2cdaad..26143c45e5 100644 --- a/mod/quiz/report/statistics/version.php +++ b/mod/quiz/report/statistics/version.php @@ -1,4 +1,4 @@ version = 2008111000; // The (date) version of this module +$plugin->version = 2008112100; // The (date) version of this module ?> \ No newline at end of file diff --git a/mod/quiz/review.php b/mod/quiz/review.php index 7316a0ad6a..130f79ec75 100644 --- a/mod/quiz/review.php +++ b/mod/quiz/review.php @@ -9,6 +9,7 @@ require_once(dirname(__FILE__) . '/../../config.php'); require_once($CFG->dirroot . '/mod/quiz/locallib.php'); + require_once($CFG->dirroot . '/mod/quiz/report/reportlib.php'); $attemptid = required_param('attempt', PARAM_INT); $page = optional_param('page', 0, PARAM_INT); diff --git a/mod/quiz/tabs.php b/mod/quiz/tabs.php index 1f49a514d9..bcb22d86d4 100644 --- a/mod/quiz/tabs.php +++ b/mod/quiz/tabs.php @@ -49,44 +49,25 @@ if (has_capability('mod/quiz:manage', $context)) { if ($currenttab == 'info' && count($row) == 1) { // Don't show only an info tab (e.g. to students). } else { + //$reports is passed in from report.php $tabs[] = $row; } if ($currenttab == 'reports' and isset($mode)) { $activated[] = 'reports'; - // Standard reports we want to show first. - $reportrs = $DB->get_recordset('quiz_report', null, 'displayorder DESC', 'id, name'); - // Reports that are restricted by capability. - $reportrestrictions = array( - 'regrade' => 'mod/quiz:grade', - 'grading' => 'mod/quiz:grade' - ); - $reportdirs = get_list_of_plugins("mod/quiz/report"); - //order the reports tab in descending order of displayorder - $reportlist = array(); - foreach ($reportrs as $key => $rs) { - if (in_array($rs->name, $reportdirs)) { - $reportlist[]=$rs->name; - } - } - //add any other reports on the end - foreach ($reportdirs as $report) { - if (!in_array($report, $reportlist)) { - $reportlist[]=$report; - } - } $row = array(); $currenttab = ''; + + $reportlist = quiz_report_list($context); + foreach ($reportlist as $report) { - if (!isset($reportrestrictions[$report]) || has_capability($reportrestrictions[$report], $context)) { - $row[] = new tabobject($report, "$CFG->wwwroot/mod/quiz/report.php?q=$quiz->id&mode=$report", - get_string($report, 'quiz_'.$report)); - if ($report == $mode) { - $currenttab = $report; - } + $row[] = new tabobject($report, "$CFG->wwwroot/mod/quiz/report.php?q=$quiz->id&mode=$report", + get_string($report, 'quiz_'.$report)); + if ($report == $mode) { + $currenttab = $report; } } $tabs[] = $row; diff --git a/mod/quiz/version.php b/mod/quiz/version.php index b964a6f4ef..dc5a66bfab 100644 --- a/mod/quiz/version.php +++ b/mod/quiz/version.php @@ -5,7 +5,7 @@ // This fragment is called by moodle_needs_upgrading() and /admin/index.php //////////////////////////////////////////////////////////////////////////////// -$module->version = 2008082600; // The (date) version of this module +$module->version = 2008112101; // The (date) version of this module $module->requires = 2008072401; // Requires this Moodle version $module->cron = 0; // How often should cron check this module (seconds)? -- 2.39.5