]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-10198 - New code to allow files from quiestion attempts to be stored in moodledat...
authortjhunt <tjhunt>
Wed, 20 Jun 2007 15:12:36 +0000 (15:12 +0000)
committertjhunt <tjhunt>
Wed, 20 Jun 2007 15:12:36 +0000 (15:12 +0000)
mod/quiz/lib.php
question/file.php [new file with mode: 0644]

index 58bcce8fe84787467b2b3720fb43ab6795971db2..b19c27b84533f0f6cb16b92e72e86abc97c14a3b 100644 (file)
@@ -866,4 +866,31 @@ function quiz_delete_userdata($data, $showfeedback=true) {
         notify(get_string('attemptsdeleted','quiz'), 'notifysuccess');
     }
 }
+
+/**
+ * Checks whether the current user is allowed to view a file uploaded in a quiz.
+ * Teachers can view any from their courses, students can only view their own.
+ * 
+ * @param int $attemptid int attempt id
+ * @param int $questionid int question id
+ * @return boolean to indicate access granted or denied  
+ */
+function quiz_check_file_access($attemptid, $questionid) {
+    global $USER;
+    
+    $attempt = get_record("quiz_attempts", 'id', $attemptid);
+    $quiz = get_record("quiz", 'id', $attempt->quiz);
+    $context = get_context_instance(CONTEXT_COURSE, $quiz->course);
+    
+    // access granted if the current user submitted this file
+    if ($attempt->userid == $USER->id) {
+        return true;
+    // access granted if the current user has permission to grade quizzes in this course
+    } else if (has_capability('mod/quiz:viewreports', $context) || has_capability('mod/quiz:grade', $context)) {
+        return true;
+    }
+    
+    // otherwise, this user does not have permission    
+    return false;
+}
 ?>
\ No newline at end of file
diff --git a/question/file.php b/question/file.php
new file mode 100644 (file)
index 0000000..9926fa9
--- /dev/null
@@ -0,0 +1,87 @@
+<?php 
+      // This script fetches files from the dataroot/questionattempt directory
+      // It is based on the top-level file.php
+      //
+      // On a module-by-module basis (currently only implemented for quiz), it checks
+      // whether the user has permission to view the file.
+      //
+      // Syntax:      question/file.php/questionattempt/attemptid/questionid/filename.ext
+      //              question/file.php/questionattempt/attemptid/questionid/filename.ext?forcedownload=1 (download instead of inline)
+      // Workaround:  question/file.php?file=/questionattempt/attemptid/questionid
+      // Test:        question/file.php/testslasharguments 
+
+    require_once('../config.php');
+    require_once('../lib/filelib.php');
+
+    // disable moodle specific debug messages
+    disable_debugging();
+
+    $relativepath = get_file_argument('file.php');
+    $forcedownload = optional_param('forcedownload', 0, PARAM_BOOL);
+    
+    // relative path must start with '/', because of backup/restore!!!
+    if (!$relativepath) {
+        error('No valid arguments supplied or incorrect server configuration');
+    } else if ($relativepath{0} != '/') {
+        error('No valid arguments supplied, path does not start with slash!');
+    }
+
+    $pathname = $CFG->dataroot.$relativepath;
+    
+    // extract relative path components
+    $args = explode('/', trim($relativepath, '/'));
+    if (count($args) == 0) { // always at least courseid, may search for index.html in course root
+        error('No valid arguments supplied');
+    }
+    
+    // security: only allow access to questionattempt directory
+    if ($args[0] != 'questionattempt') {
+        question_attempt_not_found();
+    }
+
+    // security: require login
+    require_login();
+
+    // security: do not return directory node!    
+    if (is_dir($pathname)) {
+        question_attempt_not_found();
+    }
+
+    $lifetime = 0;  // do not cache because students may reupload files
+    
+    // force download for any student-submitted files
+    $forcedownload = 1;
+
+    // security: check that the user has permission to access this file
+    $haspermission = false;
+    if ($attempt = get_record("question_attempts", "id", $args[1])) {
+        $modfile = $CFG->dirroot .'/mod/'. $attempt->modulename .'/lib.php';
+        $modcheckfileaccess = $attempt->modulename .'_check_file_access'; 
+        if (file_exists($modfile)) {
+            @require_once($modfile);
+            if (function_exists($modcheckfileaccess)) {
+                $haspermission = $modcheckfileaccess($args[1], $args[2]);
+            }
+        }
+    }        
+    
+    if ($haspermission) {
+        // check that file exists
+        if (!file_exists($pathname)) {
+            question_attempt_not_found();
+        }
+        
+        // send the file
+        session_write_close(); // unlock session during fileserving
+        $filename = $args[count($args)-1];        
+        send_file($pathname, $filename, $lifetime, $CFG->filteruploadedfiles, false, $forcedownload);
+    } else {
+        question_attempt_not_found();
+    }
+
+    function question_attempt_not_found() {
+        global $CFG;
+        header('HTTP/1.0 404 not found');
+        error(get_string('filenotfound', 'error'), $CFG->wwwroot); //this is not displayed on IIS??
+    }
+?>
\ No newline at end of file