]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-15326 "allow for per report capabilities to replace mod/quiz:viewreports"
authorjamiesensei <jamiesensei>
Tue, 25 Nov 2008 12:11:27 +0000 (12:11 +0000)
committerjamiesensei <jamiesensei>
Tue, 25 Nov 2008 12:11:27 +0000 (12:11 +0000)
20 files changed:
lang/en_utf8/quiz.php
lang/en_utf8/quiz_statistics.php
lib/accesslib.php
mod/quiz/db/access.php
mod/quiz/db/install.xml
mod/quiz/db/upgrade.php
mod/quiz/lib.php
mod/quiz/report.php
mod/quiz/report/overview/overview_table.php
mod/quiz/report/overview/overviewsettings_form.php
mod/quiz/report/overview/report.php
mod/quiz/report/reportlib.php
mod/quiz/report/statistics/db/access.php [new file with mode: 0644]
mod/quiz/report/statistics/db/install.xml
mod/quiz/report/statistics/db/upgrade.php
mod/quiz/report/statistics/statistics_graph.php
mod/quiz/report/statistics/version.php
mod/quiz/review.php
mod/quiz/tabs.php
mod/quiz/version.php

index 34ac45b3b9bb5dbc2ea1482ea5abc283ca44d511..cc00cb7f2f2f026952f4556612827e475447ffa1 100644 (file)
@@ -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';
index d8de227c2b484e4126c647077ebcc2e4813ddb4a..1b38d9bee976045fe9b2e55847ae8bfef340b722 100644 (file)
@@ -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';
 
index d668a63913242d8c52745fcf4a9e1992b2cce68c..8160cced27efa9d7e1bd6eab30e16debe04a590c 100755 (executable)
@@ -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:
index 9d5adbb8162e329550e3efdfef46fd0b1bf06c4b..41c82d393fd32ea2d492045381c840868cf1646b 100644 (file)
@@ -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,
index a78bc5c6475663acded937a81c0d2428b64dc404..0901e614a47380e109eee3192b19e4aaca6de326 100755 (executable)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="mod/quiz/db" VERSION="20080725" COMMENT="XMLDB file for Moodle mod/quiz"
+<XMLDB PATH="mod/quiz/db" VERSION="20081121" COMMENT="XMLDB file for Moodle mod/quiz"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
 >
         <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="name of the report, same as the directory name" PREVIOUS="id" NEXT="displayorder"/>
         <FIELD NAME="displayorder" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="display order for report tabs" PREVIOUS="name" NEXT="lastcron"/>
         <FIELD NAME="lastcron" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="displayorder" NEXT="cron"/>
-        <FIELD NAME="cron" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="0 if there is no cron for this report (default) or the time between crons otherwise." PREVIOUS="lastcron"/>
+        <FIELD NAME="cron" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="0 if there is no cron for this report (default) or the time between crons otherwise." PREVIOUS="lastcron" NEXT="capability"/>
+        <FIELD NAME="capability" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" ENUM="false" PREVIOUS="cron"/>
       </FIELDS>
       <KEYS>
         <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
       <SENTENCES>
         <SENTENCE TEXT="(name, displayorder) VALUES ('overview', '10000')" />
         <SENTENCE TEXT="(name, displayorder) VALUES ('responses', '9000')" />
-        <SENTENCE TEXT="(name, displayorder) VALUES ('statistics', '8000')" />
         <SENTENCE TEXT="(name, displayorder) VALUES ('grading', '6000')" />
       </SENTENCES>
     </STATEMENT>
index 1d5ede21df37d50fcaf298f9224189d56e31c912..a72b24718d4688fbe3d1d83964c1335d0ac5ac9d 100644 (file)
@@ -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;
 }
index 95f97aa0d10cb121b4d699a3590176ff5993f79a..906879f566c34910090938ad4a9579087bc896d4 100644 (file)
@@ -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;
 }
index f3260013ba6da47bf4f8eff178859255d4c7f69d..8ef746285272d8cc0754340e76f87dd2629ccffa 100644 (file)
@@ -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)) {
         }
     }
 
+    
     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);
index 99e6dc49d9954737345ea47b2df0f31c74f28646..31c25d6d9f8d259a1d8333c84508ae2c8dd52636 100644 (file)
@@ -94,7 +94,7 @@ class quiz_report_overview_table extends table_sql {
                 echo '<a href="javascript:deselect_all_in(\'DIV\',null,\'tablecontainer\');">'.
                         get_string('selectnone', 'quiz').'</a> ';
                 echo '&nbsp;&nbsp;';
-                if (has_capability('mod/quiz:grade', $this->context)){
+                if (has_capability('mod/quiz:regrade', $this->context)){
                     echo '<input type="submit" name="regrade" value="'.get_string('regradeselected', 'quiz_overview').'"/>';
                 }
                 echo '<input type="submit" onclick="return confirm(\''.$strreallydel.'\');" name="delete" value="'.get_string('deleteselected', 'quiz_overview').'"/>';
@@ -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);
             }
         }
index ea778f4fb39c2b3ecb69f8fdfe0055aaabdbbc1e..ed2690a64f37d5c80cf0ebd20395bb9d5cffd3e3 100644 (file)
@@ -37,7 +37,7 @@ class mod_quiz_report_overview_settings extends moodleform {
             $gm = '<span class="highlight">'.quiz_get_grading_option_name($this->_customdata['quiz']->grademethod).'</span>';
             $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){
index 3f2ebe002c571afb4676625db66e9ab8f7fe7bf6..461fe566d091c57dab6d8ddfffe553f96be0f086 100644 (file)
@@ -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 ";
index 71a167945de5fa0c3ca4228f01c8cb95396da28f..54feb712eafc24541fdbb8b8f36f71ac1927c28b 100644 (file)
@@ -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 (file)
index 0000000..b9c3839
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Capability definitions for the quiz statistics report.
+ *
+ * For naming conventions, see lib/db/access.php.
+ */
+$quizreport_statistics_capabilities = array(
+    'quizreport/statistics:view' => array(
+        'captype' => 'read',
+        'contextlevel' => CONTEXT_MODULE,
+        'legacy' => array(
+            'teacher' => CAP_ALLOW,
+            'editingteacher' => CAP_ALLOW,
+            'admin' => CAP_ALLOW
+        ),
+        'clonepermissionsfrom' =>  'mod/quiz:viewreports'
+    )
+);
+?>
+
index 6610052e6132680f827a816e1694bf2433b73f12..d6812e7eacd9dfcaaec52077d31bd0610e574b94 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="mod/quiz/report/statistics/db" VERSION="20081110" COMMENT="XMLDB file for Moodle mod/quiz/report/statistics"
+<XMLDB PATH="mod/quiz/report/statistics/db" VERSION="20081118" COMMENT="XMLDB file for Moodle mod/quiz/report/statistics"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../../../../lib/xmldb/xmldb.xsd"
 >
       </KEYS>
     </TABLE>
   </TABLES>
+  <STATEMENTS>
+    <STATEMENT NAME="insert quiz_report" TYPE="insert" TABLE="quiz_report" COMMENT="Initial insert of records on table quiz_report">
+      <SENTENCES>
+        <SENTENCE TEXT="(name, displayorder, cron, capability) VALUES ('statistics', 8000, 18000, 'quizreport/statistics:view')" />
+      </SENTENCES>
+    </STATEMENT>
+  </STATEMENTS>
 </XMLDB>
\ No newline at end of file
index a889be710c3981fddcbf2fec181dc4f47c5b3b00..ef980183651d99c8d0f08c46ccc195cb63887884 100644 (file)
@@ -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;
 }
 
index e922c0105790111ec325a666206781ba737b615a..9283d074256fd3d3fc9da8a8f0a3543c4e924c9c 100644 (file)
@@ -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']   = '';
index 53af2cdaad1b03c0a5526fe164df4ca0cd0d2e5a..26143c45e592a8aeb64b77fe17b6c5a9b84fc0b9 100644 (file)
@@ -1,4 +1,4 @@
 <?php
-$plugin->version  = 2008111000;   // The (date) version of this module
+$plugin->version  = 2008112100;   // The (date) version of this module
 
 ?>
\ No newline at end of file
index 7316a0ad6a5fa10a7304e18c2edae2b3821b082e..130f79ec7518b5a3e53aa548469aa36756ac000e 100644 (file)
@@ -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);
index 1f49a514d99fa0bebc113f5e568c2fa7e229f3cc..bcb22d86d47cee27c811e6ece14bfadfd514fe52 100644 (file)
@@ -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&amp;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&amp;mode=$report",
+                                get_string($report, 'quiz_'.$report));
+        if ($report == $mode) {
+            $currenttab = $report;
         }
     }
     $tabs[] = $row;
index b964a6f4ef5e8783bff83ba582dd92dc85bebadd..dc5a66bfabaee55ddd871430004ac8bc755f9948 100644 (file)
@@ -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)?