浏览代码

Updated student view:
- Properly shows submission name, grades, comment and file;

function mod_gradeimporter_pluginfile added to lib.php:
- Enables file serving through pluginfile url

Bernardo 2 年之前
父节点
当前提交
d975f19d5a
共有 6 个文件被更改,包括 242 次插入93 次删除
  1. 71 19
      forms/submission_form_functions.php
  2. 40 69
      lib.php
  3. 95 0
      libs/student_viewlib.php
  4. 28 0
      libs/testlib.php
  5. 6 1
      submission.php
  6. 2 4
      view.php

+ 71 - 19
forms/submission_form_functions.php

@@ -14,7 +14,7 @@
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
-function create_submission($data, $gradeimporterid, $userid) {
+function create_submission ($data, $gradeimporterid, $userid) {
     global $DB;
     $timenow = time();
     if (empty($data->id)) {
@@ -47,34 +47,57 @@ function create_submission($data, $gradeimporterid, $userid) {
 
 
 
-function store_files($context, $cm, $data) {
+function store_files ($context, $cm, $data) {
+    global $CFG;
     $fs = get_file_storage();
     $files = $fs->get_area_files($context->id, 'mod_gradeimporter',
                                 'submissionfiles', $data->id
                             );
     foreach ($files as $file) {
-        $extension = explode(".", $file->get_filename())[1];
-        if ($extension == 'csv') {
+        if ($file->get_mimetype() == 'text/csv') {
             read_csv($file->get_content(), $context, $data);
             return;
         }
+        if ($file->get_mimetype() == 'application/zip') {
+            // If it is a .zip file, extract files from the zip
+            $zipfiles = read_zip($file, $context, $fs);
+            // Search a .csv file
+            foreach ($zipfiles as $file) {
+
+                if ($file->get_mimetype() == 'text/csv') {
+                    // If csv is found, pass it to read_csv()
+                    read_csv($file->get_content(), $context, $data, $zipfiles);
+                    // Only expects one csv so doesn't look for another
+                }
+            }
+            // Finished processing files from zip, so delete temp copies
+            $fs->delete_area_files($context->id, 'mod_gradeimporter', 'unpacktemp', 0);
+        }
     }
 }
 
-function read_csv($content, $context, $data) {
+function read_csv ($content, $context, $data, $zipfiles = null) {
+
     $csv = prepare_csv($content);
     foreach ($csv as $feedback) {
+        $feedbackid = store_feedback($feedback, $context->id, $data->id);
         if ($feedback['file'] != "") {
             // If feedback has associated file, insert it into pluginfile
-            $feedbackfilepath = store_feedback_file($feedback, $context, $data, $filepath);
+            foreach ($zipfiles as $file) {
+                // Search in zipfiles to find same name then feedback['file']
+                if ($feedback['file'] == $file->get_filename()) {
+                    $feedbackfileinfo = store_feedback_file($feedback, $context, $data, $file, $feedbackid);
+                    break;
+                }
+            }
+            // Already used all files, so delete extra copies
+
         }
-        echo "Before store_feedback</br>";
-        store_feedback($feedback, $context->id, $data->id);
-        echo "After store_feedback</br>";
+
     }
 }
 
-function prepare_csv($content) {
+function prepare_csv ($content) {
     $csvlines = explode(PHP_EOL, $content);
     $csv = array();
     foreach ($csvlines as $line) {
@@ -93,7 +116,7 @@ function prepare_csv($content) {
     return $outputcsv;
 }
 
-function store_feedback($feedback, $contextid, $submissionid) {
+function store_feedback ($feedback, $contextid, $submissionid) {
     global $DB;
     // Prepare data to submit to gradeimporter_feedback table
     $entry = new stdClass();
@@ -116,7 +139,7 @@ function store_feedback($feedback, $contextid, $submissionid) {
 
 }
 
-function store_feedback_file($feedback, $context, $data, $filepath) {
+function store_feedback_file ($feedback, $context, $submission, $filetostore, $feedbackid) {
     // Prepare file
     $fs = get_file_storage();
     $fileinfo = array(
@@ -124,14 +147,43 @@ function store_feedback_file($feedback, $context, $data, $filepath) {
         'component' => 'mod_gradeimporter',
         'filearea' => 'submissionfiles',
         'itemid' => 0,
-        'filepath' => "/$data->id/{$feedback[id]}/",
-        'filename' => $feedback['file'],
-        'timecreated' => time(),
-        'timemodified' => time()
+        'filepath' => "/",
+        'filename' => $filetostore->get_filename(),
+        'timecreated' => time(), 'timemodified' => time()
     );
 
-    // Move file from temp to pluginfile
-    $fs->create_file_from_pathname($fileinfo, $filepath);
+    $fileinfo = $fs->create_file_from_storedfile($fileinfo, $filetostore);
+
+    return $fileinfo;
+}
+
+function read_zip ($file, $context, $fs) {
+    global $CFG;
+    // Get file packer to unpack zip
+    $packer = get_file_packer('application/zip');
+
+    // Clear area_files if it has been used before
+    $fs->delete_area_files($context->id,
+                            'mod_gradeimporter',
+                            'unpacktemp'
+                        );
+
+    // Extract to temp areafiles
+    $file->extract_to_storage($packer,
+                                $context->id,
+                                'mod_gradeimporter',
+                                'unpacktemp',
+                                0,
+                                $CFG->tempdir,
+                                false
+                            );
+
+    // Get extracted files from unpacktemp area file
+    $tempfiles = $fs->get_area_files($context->id,
+                                    'mod_gradeimporter',
+                                    'unpacktemp'
+                        );
 
-    return $fileinfo['filepath'];
+    // Returns an array of files object
+    return $tempfiles;
 }

+ 40 - 69
lib.php

@@ -112,76 +112,47 @@ function gradeimporter_delete_instance($data) {
     return true;
 }
 
-function gradeimporter_check_for_zips($context, $cm, $submission) {
-    global $DB;
+function mod_gradeimporter_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options=array()) {
+    // Check the contextlevel is as expected - if your plugin is a block, this becomes CONTEXT_BLOCK, etc.
+    if ($context->contextlevel != CONTEXT_MODULE) {
+        return false;
+    }
+    // Make sure the filearea is one of those used by the plugin.
+    if ($filearea !== 'submissionfiles') {
+        return false;
+    }
+
+    // Make sure the user is logged in and has access to the module
+    // (plugins that are not course modules should leave out the 'cm' part).
+    require_login($course, true, $cm);
+
+    // Check the relevant capabilities - these may vary depending on the filearea being accessed.
+    if (!has_capability('mod/gradeimporter:view', $context)) {
+        return false;
+    }
+
+    // Leave this line out if you set the itemid to null in make_pluginfile_url (set $itemid to 0 instead).
+    $itemid = array_shift($args); // The first item in the $args array.
+
+    // Use the itemid to retrieve any relevant data records and perform any security checks to see if the
+    // user really does have access to the file in question.
 
+    // Extract the filename / filepath from the $args array.
+    $filename = array_pop($args); // The last item in the $args array.
+    if (!$args) {
+        $filepath = '/'; // If $args is empty => the path is '/'
+    } else {
+        $filepath = '/'.implode('/', $args).'/'; // If $args contains elements of the filepath
+    }
+
+    // Retrieve the file from the Files API.
     $fs = get_file_storage();
-    $files = $fs->get_area_files($context->id, 'mod_gradeimporter',
-                                'submission', $submission->id,
-                                "itemid, filepath, filename", false);
-
-    foreach ($files as $storedfile) {
-        if ($storedfile->get_mimetype() == 'application/zip') {
-            // Unpack zip
-            $packer = get_file_packer('application/zip');
-            $fs->delete_area_files($context->id, 'mod_gradeimporter', 'unpacktemp', 0);
-            $storedfile->extract_to_storage($packer, $context->id, 'mod_gradeimporter',
-                                            'unpacktemp', 0, "item, filepath, filename", false
-                                        );
-            $tempfiles = $fs->get_area_files($context->id, 'mod_gradeimporter', 'unpacktemp',
-                                            0, "itemid, filepath, filename", false);
-            if (count($tempfiles) > 0) {
-                $storedfile->delete(); // Delete the zip
-
-                foreach ($tempfiles as $storedfile) {
-                    if ($storedfile->get_mimetype() == 'text/csv') {
-                        $csvdata = $storedfile->get_content();
-                        $csvlines = explode(PHP_EOL, $csvdata);
-                        $csv = array();
-                        foreach ($csvlines as $line) {
-                            $csv[] = str_getcsv($line);
-                        }
-                        // array_map('str_getcsv', $storedfile->get_content() );
-                        array_walk($csv, function (&$a) use ($csv) { // Adds first row as keys
-                            $a = array_combine($csv[0], $a);
-                        });
-                        array_shift($csv); // Remove column header
-                        for ($i = 0; $i < count($csv); $i++) {
-                            foreach ($tempfiles as $storedfile) {
-                                if ($storedfile->get_filename() == $csv[$i]['file']) {
-                                    $dbentry = new stdClass();
-                                    $dbentry->id = null;
-                                    $dbentry->submissionid  = $submission->id;
-                                    $dbentry->studentid     = $csv[$i]['id'];
-                                    $dbentry->grade        = $csv[$i]['grade'];
-                                    $dbentry->comment      = $csv[$i]['comment'];
-                                    $dbentry->fileid      = $submission->id;
-                                    $dbentry->usermodified = 0;
-                                    $dbentry->timecreated   = time();
-                                    $dbentry->timemodified   = time();
-                                    $dbentry->contextid   = $context->id;
-                                    $dbentry->name    = $csv[$i]['file'];
-
-                                    $dbentry->id = $DB->insert_record('gradeimporter_feedback', $dbentry);
-
-                                    $fileinfo = array(
-                                        'contextid' => $context->id,
-                                        'component' => 'mod_gradeimporter',
-                                        'filearea' => 'gradeimporter_feedback',
-                                        'itemid' => $dbentry->id,
-                                        'filepath' => '/',
-                                        'filename' => $csv[$i]['file']
-                                    );
-
-                                    $fs->create_file_from_storedfile($fileinfo, $storedfile);
-                                    break;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            $fs->delete_area_files($context->id, 'mod_gradeimporter', 'unpacktemp', 0);
-        }
+    $file = $fs->get_file($context->id, 'mod_gradeimporter', $filearea, $itemid, $filepath, $filename);
+    if (!$file) {
+        echo "didnt find the file";
+        return false; // The file does not exist.
     }
+
+    // We can now send the file back to the browser - in this case with a cache lifetime of 1 day and no filtering.
+    send_stored_file($file, 86400, 0, $forcedownload, $options);
 }

+ 95 - 0
libs/student_viewlib.php

@@ -0,0 +1,95 @@
+<?php
+// This file is part of
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+function query_feedbacks($cmid, $gradeimporterid) {
+    global $DB, $USER, $CFG;
+
+    // Get moodle table prefix, usually 'mdl_'
+    $tp = $CFG->prefix;
+
+    // Build database query to fetch feedbacks for the student
+    $query = " SELECT
+                /* gst.name as typename,
+                gst.id as typeid,
+                gst.description as typedescription, */
+                gf.id as id,
+                gs.name as submissionname,
+                gs.id as submissionid,
+                gf.grade as grade,
+                gf.comment as comment,
+                gf.name as filename,
+                gs.description as submissiondescription,
+                gs.position as position
+                FROM {$tp}gradeimporter_feedback as gf
+                JOIN {$tp}gradeimporter_submission as gs
+                    ON gf.submissionid = gs.id
+                /* JOIN {$tp}gradeimporter_submissiontype as gst
+                    ON gs.type = gst.id */
+                WHERE gs.gradeimporterid = {$gradeimporterid}
+                    AND gf.studentid = {$USER->id}
+                    AND gs.visibility = 1
+            ";
+    // Query database to find students feedbacks
+    $records = $DB->get_records_sql($query);
+
+    // Return query result
+    return $records;
+}
+
+function make_feedback_table ($feedbacks, $cmid) {
+    $table = new html_table();
+    $table->head = array(get_string('type', 'gradeimporter'),
+                    get_string('submission', 'gradeimporter'),
+                    get_string('grade', 'gradeimporter'),
+                    get_string('comment', 'gradeimporter'),
+                    get_string('file', 'gradeimporter')
+                );
+    $table->aling = array('center', 'center', 'center', 'center', 'center');
+
+    if (count($feedbacks)) {
+        // If feedbacks is not an empty list
+        foreach ($feedbacks as $type => $feedback) {
+            $rowvalues = array('type_name',
+                                $feedback->submissionname,
+                                $feedback->grade,
+                                $feedback->comment,
+                                get_file($feedback, $cmid)
+                            );
+
+            $row = new html_table_row($rowvalues);
+            $table->data[] = $row;
+        }
+    }
+    echo html_writer::table($table);
+}
+
+function get_file ($feedback, $cmid) {
+    global $CFG;
+    $fs = get_file_storage();
+    $context = context_module::instance($cmid);
+
+    $url = moodle_url::make_pluginfile_url($context->id,
+                                            'mod_gradeimporter',
+                                            'submissionfiles',
+                                            0,
+                                            "/",
+                                            $feedback->filename,
+                                            true
+                                        );
+
+    // Return pluginfile url, will use function mod_gradeimporter_pluginfile at lib.php to serve the file
+    return "<a href='{$url}'>$feedback->filename</a>";
+
+}

+ 28 - 0
libs/testlib.php

@@ -0,0 +1,28 @@
+<?php
+// This file is part of
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+// This cannot go to production
+
+function reset_submissions($contextid) {
+
+    global $DB;
+    // Remove data from gradeimporter_submission and gradeimporter_feedback tables
+    $DB->delete_records('gradeimporter_submission');
+    $DB->delete_records('gradeimporter_feedback');
+    // Delete feedbackfiles
+    $fs = get_file_storage();
+    $fs->delete_area_files($contextid, 'mod_gradeimporter', 'submissionfiles');
+}

+ 6 - 1
submission.php

@@ -18,6 +18,9 @@ require_once('../../config.php');
 require_once('locallib.php');
 require_once('lib.php');
 
+// Test libs
+require_once('libs/testlib.php'); // Remove when going to production
+
 require_once('forms/submission_form.php'); // Requires Form class File
 require_once('forms/submission_form_functions.php'); // Require functions file for submission form
 
@@ -81,6 +84,8 @@ if ($mform->is_cancelled()) {
     echo("form is cancelled");
 } else if ($formdata = $mform->get_data()) {
 
+    reset_submissions($context->id); // Remove when going to production
+
     $entry = create_submission($formdata, $gradeimporter->id, $USER->id);
 
     // Gets file manager content
@@ -91,7 +96,7 @@ if ($mform->is_cancelled()) {
     store_files($context, $cm, $entry);
     // When complete redirect to view.php
     // uncomment later
-    // redirect("view.php?id=$cm->id&edit=1");
+    redirect("view.php?id=$cm->id&edit=1");
     // In this case you process validated data. $mform->get_data() returns data posted in form.
 } else {
     // This branch is executed if the form is submitted but the data doesn't validate and the form should be redisplayed

+ 2 - 4
view.php

@@ -18,12 +18,10 @@ require_once(dirname(dirname(dirname(__FILE__))).'/config.php');
 require_once(dirname(__FILE__).'/lib.php');
 require_once($CFG->libdir.'/filelib.php');
 require_once('locallib.php');
-require_once('libs/viewlib.php');
-
+require_once('libs/student_viewlib.php');
 
   global $DB;
 
-
   $id = optional_param('id', 0, PARAM_INT); // Course_module ID.
   $g  = optional_param('g', 0, PARAM_INT);  // Gradeimporter instance ID, should be named as the first character of the module.
   $action = optional_param('action', 0, PARAM_INT);
@@ -130,7 +128,7 @@ if (has_capability('mod/gradeimporter:edit', $context)) {
 
     // Query database to find student feedbacks
     $feedbacks = query_feedbacks($cm->id, $gradeimporter->id);
-    make_feedback_table($feedbacks);
+    make_feedback_table($feedbacks, $cm->id);
 }
 
 // Finishes the page!