[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * This file contains the definition for the library class for file feedback plugin 19 * 20 * 21 * @package assignfeedback_file 22 * @copyright 2012 NetSpot {@link http://www.netspot.com.au} 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 /** 29 * library class for importing feedback files from a zip 30 * 31 * @package assignfeedback_file 32 * @copyright 2012 NetSpot {@link http://www.netspot.com.au} 33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 */ 35 class assignfeedback_file_zip_importer { 36 37 /** 38 * Is this filename valid (contains a unique participant ID) for import? 39 * 40 * @param assign $assignment - The assignment instance 41 * @param stored_file $fileinfo - The fileinfo 42 * @param array $participants - A list of valid participants for this module indexed by unique_id 43 * @param stdClass $user - Set to the user that matches by participant id 44 * @param assign_plugin $plugin - Set to the plugin that exported the file 45 * @param string $filename - Set to truncated filename (prefix stripped) 46 * @return true If the participant Id can be extracted and this is a valid user 47 */ 48 public function is_valid_filename_for_import($assignment, $fileinfo, $participants, & $user, & $plugin, & $filename) { 49 if ($fileinfo->is_directory()) { 50 return false; 51 } 52 53 // Ignore hidden files. 54 if (strpos($fileinfo->get_filename(), '.') === 0) { 55 return false; 56 } 57 // Ignore hidden files. 58 if (strpos($fileinfo->get_filename(), '~') === 0) { 59 return false; 60 } 61 62 $info = explode('_', $fileinfo->get_filepath() . $fileinfo->get_filename(), 5); 63 64 if (count($info) < 5) { 65 return false; 66 } 67 68 $participantid = $info[1]; 69 $filename = $info[4]; 70 $plugin = $assignment->get_plugin_by_type($info[2], $info[3]); 71 72 if (!is_numeric($participantid)) { 73 return false; 74 } 75 76 if (!$plugin) { 77 return false; 78 } 79 80 // Convert to int. 81 $participantid += 0; 82 83 if (empty($participants[$participantid])) { 84 return false; 85 } 86 87 $user = $participants[$participantid]; 88 return true; 89 } 90 91 /** 92 * Does this file exist in any of the current files supported by this plugin for this user? 93 * 94 * @param assign $assignment - The assignment instance 95 * @param stdClass $user The user matching this uploaded file 96 * @param assign_plugin $plugin The matching plugin from the filename 97 * @param string $filename The parsed filename from the zip 98 * @param stored_file $fileinfo The info about the extracted file from the zip 99 * @return bool - True if the file has been modified or is new 100 */ 101 public function is_file_modified($assignment, $user, $plugin, $filename, $fileinfo) { 102 $sg = null; 103 104 if ($plugin->get_subtype() == 'assignsubmission') { 105 $sg = $assignment->get_user_submission($user->id, false); 106 } else if ($plugin->get_subtype() == 'assignfeedback') { 107 $sg = $assignment->get_user_grade($user->id, false); 108 } else { 109 return false; 110 } 111 112 if (!$sg) { 113 return true; 114 } 115 foreach ($plugin->get_files($sg, $user) as $pluginfilename => $file) { 116 if ($pluginfilename == $filename) { 117 // Extract the file and compare hashes. 118 $contenthash = ''; 119 if (is_array($file)) { 120 $content = reset($file); 121 $contenthash = sha1($content); 122 } else { 123 $contenthash = $file->get_contenthash(); 124 } 125 if ($contenthash != $fileinfo->get_contenthash()) { 126 return true; 127 } else { 128 return false; 129 } 130 } 131 } 132 return true; 133 } 134 135 /** 136 * Delete all temp files used when importing a zip 137 * 138 * @param int $contextid - The context id of this assignment instance 139 * @return bool true if all files were deleted 140 */ 141 public function delete_import_files($contextid) { 142 global $USER; 143 144 $fs = get_file_storage(); 145 146 return $fs->delete_area_files($contextid, 147 'assignfeedback_file', 148 ASSIGNFEEDBACK_FILE_IMPORT_FILEAREA, 149 $USER->id); 150 } 151 152 /** 153 * Extract the uploaded zip to a temporary import area for this user 154 * 155 * @param stored_file $zipfile The uploaded file 156 * @param int $contextid The context for this assignment 157 * @return bool - True if the files were unpacked 158 */ 159 public function extract_files_from_zip($zipfile, $contextid) { 160 global $USER; 161 162 $feedbackfilesupdated = 0; 163 $feedbackfilesadded = 0; 164 $userswithnewfeedback = array(); 165 166 // Unzipping a large zip file is memory intensive. 167 raise_memory_limit(MEMORY_EXTRA); 168 169 $packer = get_file_packer('application/zip'); 170 core_php_time_limit::raise(ASSIGNFEEDBACK_FILE_MAXFILEUNZIPTIME); 171 172 return $packer->extract_to_storage($zipfile, 173 $contextid, 174 'assignfeedback_file', 175 ASSIGNFEEDBACK_FILE_IMPORT_FILEAREA, 176 $USER->id, 177 'import'); 178 179 } 180 181 /** 182 * Get the list of files extracted from the uploaded zip 183 * 184 * @param int $contextid 185 * @return array of stored_files 186 */ 187 public function get_import_files($contextid) { 188 global $USER; 189 190 $fs = get_file_storage(); 191 $files = $fs->get_directory_files($contextid, 192 'assignfeedback_file', 193 ASSIGNFEEDBACK_FILE_IMPORT_FILEAREA, 194 $USER->id, 195 '/import/', true); // Get files recursive (all levels). 196 197 $keys = array_keys($files); 198 199 return $files; 200 } 201 202 /** 203 * Process an uploaded zip file 204 * 205 * @param assign $assignment - The assignment instance 206 * @param assign_feedback_file $fileplugin - The file feedback plugin 207 * @return string - The html response 208 */ 209 public function import_zip_files($assignment, $fileplugin) { 210 global $CFG, $PAGE, $DB; 211 212 core_php_time_limit::raise(ASSIGNFEEDBACK_FILE_MAXFILEUNZIPTIME); 213 $packer = get_file_packer('application/zip'); 214 215 $feedbackfilesupdated = 0; 216 $feedbackfilesadded = 0; 217 $userswithnewfeedback = array(); 218 $contextid = $assignment->get_context()->id; 219 220 $fs = get_file_storage(); 221 $files = $this->get_import_files($contextid); 222 223 $currentgroup = groups_get_activity_group($assignment->get_course_module(), true); 224 $allusers = $assignment->list_participants($currentgroup, false); 225 $participants = array(); 226 foreach ($allusers as $user) { 227 $participants[$assignment->get_uniqueid_for_user($user->id)] = $user; 228 } 229 230 foreach ($files as $unzippedfile) { 231 // Set the timeout for unzipping each file. 232 $user = null; 233 $plugin = null; 234 $filename = ''; 235 236 if ($this->is_valid_filename_for_import($assignment, $unzippedfile, $participants, $user, $plugin, $filename)) { 237 if ($this->is_file_modified($assignment, $user, $plugin, $filename, $unzippedfile)) { 238 $grade = $assignment->get_user_grade($user->id, true); 239 240 // In 3.1 the download structure of the submission files changed so that each student had their own 241 // separate folder, the files were not renamed and the folder structure was kept. It is possible that 242 // a user downloaded the submission files in 3.0 (or earlier) and edited the zip to add feedback and 243 // in that time the site was updated to 3.1, the following code means that we will still support the 244 // old file structure. For more information please see - MDL-52489. 245 $path = pathinfo($filename); 246 if ($path['dirname'] == '.') { // Old structure as students are not in separate folders. 247 $basename = $filename; 248 $dirname = "/"; 249 $dirnamewslash = "/"; 250 } else { 251 $basename = $path['basename']; 252 $dirname = $path['dirname']; 253 $dirnamewslash = $dirname . "/"; 254 } 255 256 if ($oldfile = $fs->get_file($contextid, 257 'assignfeedback_file', 258 ASSIGNFEEDBACK_FILE_FILEAREA, 259 $grade->id, 260 $dirname, 261 $basename)) { 262 // Update existing feedback file. 263 $oldfile->replace_file_with($unzippedfile); 264 $feedbackfilesupdated++; 265 } else { 266 // Create a new feedback file. 267 $newfilerecord = new stdClass(); 268 $newfilerecord->contextid = $contextid; 269 $newfilerecord->component = 'assignfeedback_file'; 270 $newfilerecord->filearea = ASSIGNFEEDBACK_FILE_FILEAREA; 271 $newfilerecord->filename = $basename; 272 $newfilerecord->filepath = $dirnamewslash; 273 $newfilerecord->itemid = $grade->id; 274 $fs->create_file_from_storedfile($newfilerecord, $unzippedfile); 275 $feedbackfilesadded++; 276 } 277 $userswithnewfeedback[$user->id] = 1; 278 279 // Update the number of feedback files for this user. 280 $fileplugin->update_file_count($grade); 281 282 // Update the last modified time on the grade which will trigger student notifications. 283 $assignment->notify_grade_modified($grade); 284 } 285 } 286 } 287 288 require_once($CFG->dirroot . '/mod/assign/feedback/file/renderable.php'); 289 $importsummary = new assignfeedback_file_import_summary($assignment->get_course_module()->id, 290 count($userswithnewfeedback), 291 $feedbackfilesadded, 292 $feedbackfilesupdated); 293 294 $assignrenderer = $assignment->get_renderer(); 295 $renderer = $PAGE->get_renderer('assignfeedback_file'); 296 297 $o = ''; 298 299 $o .= $assignrenderer->render(new assign_header($assignment->get_instance(), 300 $assignment->get_context(), 301 false, 302 $assignment->get_course_module()->id, 303 get_string('uploadzipsummary', 'assignfeedback_file'))); 304 305 $o .= $renderer->render($importsummary); 306 307 $o .= $assignrenderer->render_footer(); 308 return $o; 309 } 310 311 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |