Commit | Line | Data |
---|---|---|
4317f92f | 1 | <?php |
10d53fd3 DC |
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 | ||
67233725 DC |
17 | /** |
18 | * This plugin is used to access files on server file system | |
19 | * | |
20 | * @since 2.0 | |
21 | * @package repository_filesystem | |
22 | * @copyright 2010 Dongsheng Cai {@link http://dongsheng.org} | |
23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
24 | */ | |
25 | require_once($CFG->dirroot . '/repository/lib.php'); | |
26 | require_once($CFG->libdir . '/filelib.php'); | |
27 | ||
fdcf5320 | 28 | /** |
29 | * repository_filesystem class | |
67233725 | 30 | * |
fdcf5320 | 31 | * Create a repository from your local filesystem |
32 | * *NOTE* for security issue, we use a fixed repository path | |
33 | * which is %moodledata%/repository | |
34 | * | |
d078f6d3 | 35 | * @package repository |
67233725 | 36 | * @copyright 2009 Dongsheng Cai {@link http://dongsheng.org} |
d078f6d3 | 37 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
fdcf5320 | 38 | */ |
520de343 | 39 | class repository_filesystem extends repository { |
67233725 DC |
40 | |
41 | /** | |
42 | * Constructor | |
43 | * | |
44 | * @param int $repositoryid repository ID | |
45 | * @param int $context context ID | |
46 | * @param array $options | |
47 | */ | |
447c7a19 | 48 | public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) { |
fdcf5320 | 49 | global $CFG; |
520de343 | 50 | parent::__construct($repositoryid, $context, $options); |
c122f484 | 51 | $root = $CFG->dataroot . '/repository/'; |
873f2e0f | 52 | $subdir = $this->get_option('fs_path'); |
c122f484 FM |
53 | |
54 | $this->root_path = $root; | |
55 | if (!empty($subdir)) { | |
56 | $this->root_path .= $subdir . '/'; | |
57 | } | |
58 | ||
e437618b | 59 | if (!empty($options['ajax'])) { |
fdcf5320 | 60 | if (!is_dir($this->root_path)) { |
8512eebe | 61 | $created = mkdir($this->root_path, $CFG->directorypermissions, true); |
520de343 | 62 | $ret = array(); |
63 | $ret['msg'] = get_string('invalidpath', 'repository_filesystem'); | |
64 | $ret['nosearch'] = true; | |
93e9aa27 | 65 | if ($options['ajax'] && !$created) { |
fdcf5320 | 66 | echo json_encode($ret); |
67 | exit; | |
520de343 | 68 | } |
69 | } | |
520de343 | 70 | } |
71 | } | |
72 | public function get_listing($path = '', $page = '') { | |
390baf46 | 73 | global $CFG, $OUTPUT; |
520de343 | 74 | $list = array(); |
75 | $list['list'] = array(); | |
76 | // process breacrumb trail | |
77 | $list['path'] = array( | |
5bdf63cc | 78 | array('name'=>get_string('root', 'repository_filesystem'), 'path'=>'') |
520de343 | 79 | ); |
80 | $trail = ''; | |
81 | if (!empty($path)) { | |
82 | $parts = explode('/', $path); | |
83 | if (count($parts) > 1) { | |
84 | foreach ($parts as $part) { | |
4a9aff79 | 85 | if (!empty($part)) { |
86 | $trail .= ('/'.$part); | |
87 | $list['path'][] = array('name'=>$part, 'path'=>$trail); | |
88 | } | |
520de343 | 89 | } |
90 | } else { | |
91 | $list['path'][] = array('name'=>$path, 'path'=>$path); | |
92 | } | |
93 | $this->root_path .= ($path.'/'); | |
94 | } | |
520de343 | 95 | $list['manage'] = false; |
520de343 | 96 | $list['dynload'] = true; |
520de343 | 97 | $list['nologin'] = true; |
520de343 | 98 | $list['nosearch'] = true; |
7355640a MG |
99 | // retrieve list of files and directories and sort them |
100 | $fileslist = array(); | |
101 | $dirslist = array(); | |
520de343 | 102 | if ($dh = opendir($this->root_path)) { |
103 | while (($file = readdir($dh)) != false) { | |
104 | if ( $file != '.' and $file !='..') { | |
7355640a MG |
105 | if (is_file($this->root_path.$file)) { |
106 | $fileslist[] = $file; | |
520de343 | 107 | } else { |
7355640a | 108 | $dirslist[] = $file; |
520de343 | 109 | } |
110 | } | |
111 | } | |
112 | } | |
2f1e464a PS |
113 | core_collator::asort($fileslist, core_collator::SORT_STRING); |
114 | core_collator::asort($dirslist, core_collator::SORT_STRING); | |
7355640a MG |
115 | // fill the $list['list'] |
116 | foreach ($dirslist as $file) { | |
117 | if (!empty($path)) { | |
118 | $current_path = $path . '/'. $file; | |
119 | } else { | |
120 | $current_path = $file; | |
121 | } | |
122 | $list['list'][] = array( | |
123 | 'title' => $file, | |
124 | 'children' => array(), | |
125 | 'datecreated' => filectime($this->root_path.$file), | |
126 | 'datemodified' => filemtime($this->root_path.$file), | |
127 | 'thumbnail' => $OUTPUT->pix_url(file_folder_icon(90))->out(false), | |
128 | 'path' => $current_path | |
129 | ); | |
130 | } | |
131 | foreach ($fileslist as $file) { | |
2ef39ca4 | 132 | $node = array( |
7355640a MG |
133 | 'title' => $file, |
134 | 'source' => $path.'/'.$file, | |
135 | 'size' => filesize($this->root_path.$file), | |
136 | 'datecreated' => filectime($this->root_path.$file), | |
137 | 'datemodified' => filemtime($this->root_path.$file), | |
138 | 'thumbnail' => $OUTPUT->pix_url(file_extension_icon($file, 90))->out(false), | |
139 | 'icon' => $OUTPUT->pix_url(file_extension_icon($file, 24))->out(false) | |
140 | ); | |
2ef39ca4 MG |
141 | if (file_extension_in_typegroup($file, 'image') && ($imageinfo = @getimagesize($this->root_path. $file))) { |
142 | // This means it is an image and we can return dimensions and try to generate thumbnail/icon. | |
143 | $token = $node['datemodified']. $node['size']; // To prevent caching by browser. | |
144 | $node['realthumbnail'] = $this->get_thumbnail_url($path. '/'. $file, 'thumb', $token)->out(false); | |
145 | $node['realicon'] = $this->get_thumbnail_url($path. '/'. $file, 'icon', $token)->out(false); | |
146 | $node['image_width'] = $imageinfo[0]; | |
147 | $node['image_height'] = $imageinfo[1]; | |
148 | } | |
149 | $list['list'][] = $node; | |
7355640a | 150 | } |
fb4ee704 | 151 | $list['list'] = array_filter($list['list'], array($this, 'filter')); |
520de343 | 152 | return $list; |
153 | } | |
2ef39ca4 | 154 | |
520de343 | 155 | public function check_login() { |
156 | return true; | |
157 | } | |
520de343 | 158 | public function print_login() { |
159 | return true; | |
160 | } | |
520de343 | 161 | public function global_search() { |
162 | return false; | |
163 | } | |
67233725 | 164 | |
951d2d55 DC |
165 | /** |
166 | * Return file path | |
167 | * @return array | |
168 | */ | |
520de343 | 169 | public function get_file($file, $title = '') { |
170 | global $CFG; | |
171 | if ($file{0} == '/') { | |
172 | $file = $this->root_path.substr($file, 1, strlen($file)-1); | |
951d2d55 DC |
173 | } else { |
174 | $file = $this->root_path.$file; | |
520de343 | 175 | } |
176 | // this is a hack to prevent move_to_file deleteing files | |
177 | // in local repository | |
178 | $CFG->repository_no_delete = true; | |
85b5ed5d | 179 | return array('path'=>$file, 'url'=>''); |
520de343 | 180 | } |
181 | ||
d6453211 DC |
182 | /** |
183 | * Return the source information | |
184 | * | |
185 | * @param stdClass $filepath | |
186 | * @return string|null | |
187 | */ | |
188 | public function get_file_source_info($filepath) { | |
189 | return $filepath; | |
190 | } | |
191 | ||
520de343 | 192 | public function logout() { |
193 | return true; | |
194 | } | |
195 | ||
196 | public static function get_instance_option_names() { | |
93e9aa27 | 197 | return array('fs_path'); |
520de343 | 198 | } |
199 | ||
b2f8adf4 | 200 | public function set_option($options = array()) { |
201 | $options['fs_path'] = clean_param($options['fs_path'], PARAM_PATH); | |
202 | $ret = parent::set_option($options); | |
203 | return $ret; | |
204 | } | |
8e5af6cf | 205 | |
4a126f17 | 206 | public static function instance_config_form($mform) { |
49d20def | 207 | global $CFG, $PAGE; |
0601e0ee | 208 | if (has_capability('moodle/site:config', context_system::instance())) { |
49d20def DC |
209 | $path = $CFG->dataroot . '/repository/'; |
210 | if (!is_dir($path)) { | |
8512eebe | 211 | mkdir($path, $CFG->directorypermissions, true); |
93e9aa27 | 212 | } |
49d20def DC |
213 | if ($handle = opendir($path)) { |
214 | $fieldname = get_string('path', 'repository_filesystem'); | |
215 | $choices = array(); | |
216 | while (false !== ($file = readdir($handle))) { | |
217 | if (is_dir($path.$file) && $file != '.' && $file!= '..') { | |
218 | $choices[$file] = $file; | |
219 | $fieldname = ''; | |
220 | } | |
221 | } | |
222 | if (empty($choices)) { | |
223 | $mform->addElement('static', '', '', get_string('nosubdir', 'repository_filesystem', $path)); | |
6b172cdc | 224 | $mform->addElement('hidden', 'fs_path', ''); |
8fb59b10 | 225 | $mform->setType('fs_path', PARAM_PATH); |
49d20def DC |
226 | } else { |
227 | $mform->addElement('select', 'fs_path', $fieldname, $choices); | |
228 | $mform->addElement('static', null, '', get_string('information','repository_filesystem', $path)); | |
229 | } | |
230 | closedir($handle); | |
873f2e0f | 231 | } |
49d20def DC |
232 | } else { |
233 | $mform->addElement('static', null, '', get_string('nopermissions', 'error', get_string('configplugin', 'repository_filesystem'))); | |
234 | return false; | |
93e9aa27 | 235 | } |
93e9aa27 | 236 | } |
8e5af6cf | 237 | |
49d20def DC |
238 | public static function create($type, $userid, $context, $params, $readonly=0) { |
239 | global $PAGE; | |
0601e0ee | 240 | if (has_capability('moodle/site:config', context_system::instance())) { |
49d20def DC |
241 | return parent::create($type, $userid, $context, $params, $readonly); |
242 | } else { | |
0601e0ee | 243 | require_capability('moodle/site:config', context_system::instance()); |
49d20def DC |
244 | return false; |
245 | } | |
246 | } | |
6b172cdc DC |
247 | public static function instance_form_validation($mform, $data, $errors) { |
248 | if (empty($data['fs_path'])) { | |
249 | $errors['fs_path'] = get_string('invalidadminsettingname', 'error', 'fs_path'); | |
250 | } | |
251 | return $errors; | |
252 | } | |
67233725 DC |
253 | |
254 | /** | |
255 | * User cannot use the external link to dropbox | |
256 | * | |
257 | * @return int | |
258 | */ | |
259 | public function supported_returntypes() { | |
260 | return FILE_INTERNAL | FILE_REFERENCE; | |
261 | } | |
262 | ||
96221c60 MG |
263 | /** |
264 | * Return reference file life time | |
265 | * | |
266 | * @param string $ref | |
267 | * @return int | |
268 | */ | |
269 | public function get_reference_file_lifetime($ref) { | |
270 | // Does not cost us much to synchronise within our own filesystem, set to 1 minute | |
271 | return 60; | |
272 | } | |
273 | ||
274 | /** | |
275 | * Return human readable reference information | |
276 | * | |
277 | * @param string $reference value of DB field files_reference.reference | |
278 | * @param int $filestatus status of the file, 0 - ok, 666 - source missing | |
279 | * @return string | |
280 | */ | |
281 | public function get_reference_details($reference, $filestatus = 0) { | |
282 | $details = $this->get_name().': '.$reference; | |
283 | if ($filestatus) { | |
284 | return get_string('lostsource', 'repository', $details); | |
285 | } else { | |
286 | return $details; | |
287 | } | |
288 | } | |
289 | ||
67233725 | 290 | /** |
0b2bfbd1 | 291 | * Returns information about file in this repository by reference |
67233725 | 292 | * |
0b2bfbd1 MG |
293 | * Returns null if file not found or is not readable |
294 | * | |
67233725 | 295 | * @param stdClass $reference file reference db record |
0b2bfbd1 | 296 | * @return stdClass|null contains one of the following: |
63d8ccef MG |
297 | * - 'filesize' if file should not be copied to moodle filepool |
298 | * - 'filepath' if file should be copied to moodle filepool | |
67233725 DC |
299 | */ |
300 | public function get_file_by_reference($reference) { | |
301 | $ref = $reference->reference; | |
302 | if ($ref{0} == '/') { | |
303 | $filepath = $this->root_path.substr($ref, 1, strlen($ref)-1); | |
304 | } else { | |
305 | $filepath = $this->root_path.$ref; | |
306 | } | |
0b2bfbd1 | 307 | if (file_exists($filepath) && is_readable($filepath)) { |
63d8ccef MG |
308 | if (file_extension_in_typegroup($filepath, 'web_image')) { |
309 | // return path to image files so it will be copied into moodle filepool | |
310 | // we need the file in filepool to generate an image thumbnail | |
311 | return (object)array('filepath' => $filepath); | |
312 | } else { | |
313 | // return just the file size so file will NOT be copied into moodle filepool | |
314 | return (object)array( | |
315 | 'filesize' => filesize($filepath) | |
316 | ); | |
317 | } | |
0b2bfbd1 MG |
318 | } else { |
319 | return null; | |
320 | } | |
67233725 DC |
321 | } |
322 | ||
323 | /** | |
0b2bfbd1 MG |
324 | * Repository method to serve the referenced file |
325 | * | |
326 | * @see send_stored_file | |
67233725 | 327 | * |
0b2bfbd1 | 328 | * @param stored_file $storedfile the file that contains the reference |
67233725 DC |
329 | * @param int $lifetime Number of seconds before the file should expire from caches (default 24 hours) |
330 | * @param int $filter 0 (default)=no filtering, 1=all files, 2=html files only | |
331 | * @param bool $forcedownload If true (default false), forces download of file rather than view in browser/plugin | |
332 | * @param array $options additional options affecting the file serving | |
333 | */ | |
334 | public function send_file($storedfile, $lifetime=86400 , $filter=0, $forcedownload=false, array $options = null) { | |
335 | $reference = $storedfile->get_reference(); | |
336 | if ($reference{0} == '/') { | |
337 | $file = $this->root_path.substr($reference, 1, strlen($reference)-1); | |
338 | } else { | |
339 | $file = $this->root_path.$reference; | |
340 | } | |
0b2bfbd1 MG |
341 | if (is_readable($file)) { |
342 | $filename = $storedfile->get_filename(); | |
343 | if ($options && isset($options['filename'])) { | |
344 | $filename = $options['filename']; | |
345 | } | |
346 | $dontdie = ($options && isset($options['dontdie'])); | |
347 | send_file($file, $filename, $lifetime , $filter, false, $forcedownload, '', $dontdie); | |
348 | } else { | |
349 | send_file_not_found(); | |
350 | } | |
67233725 | 351 | } |
31581ae6 FM |
352 | |
353 | /** | |
354 | * Is this repository accessing private data? | |
355 | * | |
356 | * @return bool | |
357 | */ | |
358 | public function contains_private_data() { | |
359 | return false; | |
360 | } | |
2ef39ca4 MG |
361 | |
362 | /** | |
363 | * Returns url of thumbnail file. | |
364 | * | |
365 | * @param string $filepath current path in repository (dir and filename) | |
366 | * @param string $thumbsize 'thumb' or 'icon' | |
367 | * @param string $token identifier of the file contents - to prevent browser from caching changed file | |
368 | * @return moodle_url | |
369 | */ | |
370 | protected function get_thumbnail_url($filepath, $thumbsize, $token) { | |
371 | return moodle_url::make_pluginfile_url($this->context->id, 'repository_filesystem', $thumbsize, $this->id, | |
372 | '/'. trim($filepath, '/'). '/', $token); | |
373 | } | |
374 | ||
375 | /** | |
376 | * Returns the stored thumbnail file, generates it if not present. | |
377 | * | |
378 | * @param string $filepath current path in repository (dir and filename) | |
379 | * @param string $thumbsize 'thumb' or 'icon' | |
380 | * @return null|stored_file | |
381 | */ | |
382 | public function get_thumbnail($filepath, $thumbsize) { | |
383 | global $CFG; | |
384 | ||
385 | $filepath = trim($filepath, '/'); | |
386 | $origfile = $this->root_path. $filepath; | |
387 | // As thumbnail filename we use original file content hash. | |
388 | if (!($filecontents = @file_get_contents($origfile))) { | |
389 | // File is not found or is not readable. | |
390 | return null; | |
391 | } | |
392 | $filename = sha1($filecontents); | |
393 | unset($filecontents); | |
394 | ||
395 | // Try to get generated thumbnail for this file. | |
396 | $fs = get_file_storage(); | |
397 | if (!($file = $fs->get_file(SYSCONTEXTID, 'repository_filesystem', $thumbsize, $this->id, '/'. $filepath. '/', $filename))) { | |
398 | // Thumbnail not found. Generate and store thumbnail. | |
399 | require_once($CFG->libdir. '/gdlib.php'); | |
400 | if ($thumbsize === 'thumb') { | |
401 | $size = 90; | |
402 | } else { | |
403 | $size = 24; | |
404 | } | |
405 | if (!$data = @generate_image_thumbnail($origfile, $size, $size)) { | |
406 | // Generation failed. | |
407 | return null; | |
408 | } | |
409 | $record = array( | |
410 | 'contextid' => SYSCONTEXTID, | |
411 | 'component' => 'repository_filesystem', | |
412 | 'filearea' => $thumbsize, | |
413 | 'itemid' => $this->id, | |
414 | 'filepath' => '/'. $filepath. '/', | |
415 | 'filename' => $filename, | |
416 | ); | |
417 | $file = $fs->create_file_from_string($record, $data); | |
418 | } | |
419 | return $file; | |
420 | } | |
421 | ||
422 | /** | |
423 | * Cron for particular repository instance. Removes thumbnails for deleted/modified files. | |
424 | */ | |
425 | public function cron() { | |
426 | global $DB; | |
427 | // Get all records for generated thumbnails (we don't use files api because we don't | |
428 | // need creating instances of stored_file unless file is to be deleted). | |
429 | $sql = "SELECT id, contextid, component, filearea, itemid, filepath, filename, contenthash | |
430 | FROM {files} f WHERE f.contextid = :contextid | |
431 | AND f.component = :component | |
432 | AND (f.filearea = :filearea1 OR f.filearea = :filearea2) | |
433 | AND itemid = :itemid"; | |
434 | $filesraw = $DB->get_records_sql($sql, array( | |
435 | 'contextid' => SYSCONTEXTID, | |
436 | 'component' => 'repository_filesystem', | |
437 | 'filearea1' => 'thumb', | |
438 | 'filearea2' => 'icon', | |
439 | 'itemid' => $this->id, | |
440 | )); | |
441 | // Group found files by filepath ('filepath' in Moodle file storage is dir+name in filesystem repository). | |
442 | $files = array(); | |
443 | foreach ($filesraw as $filerecord) { | |
444 | if (!isset($files[$filerecord->filepath])) { | |
445 | $files[$filerecord->filepath] = array(); | |
446 | } | |
447 | $files[$filerecord->filepath][] = $filerecord; | |
448 | } | |
449 | $filesraw = null; | |
450 | ||
451 | // Loop through all files and make sure the original exists and has the same contenthash. | |
452 | $deletedcount = 0; | |
453 | foreach ($files as $filepath => $filerecords) { | |
454 | if ($filecontents = @file_get_contents($this->root_path. trim($filepath, '/'))) { | |
455 | // 'filename' in Moodle file storage is contenthash of the file in filesystem repository. | |
456 | $filename = sha1($filecontents); | |
457 | foreach ($filerecords as $filerecord) { | |
458 | if ($filerecord->filename !== $filename && $filerecord->filename !== '.') { | |
459 | // Contenthash does not match, this is an old thumbnail. | |
460 | $deletedcount++; | |
461 | get_file_storage()->get_file_instance($filerecord)->delete(); | |
462 | } | |
463 | } | |
464 | } else { | |
465 | // Thumbnail exist but file not. | |
466 | foreach ($filerecords as $filerecord) { | |
467 | if ($filerecord->filename !== '.') { | |
468 | $deletedcount++; | |
469 | } | |
470 | get_file_storage()->get_file_instance($filerecord)->delete(); | |
471 | } | |
472 | } | |
473 | } | |
474 | if ($deletedcount) { | |
475 | mtrace(" instance {$this->id}: deleted $deletedcount thumbnails"); | |
476 | } | |
477 | } | |
478 | } | |
479 | ||
480 | /** | |
481 | * Generates and sends the thumbnail for an image in filesystem. | |
482 | * | |
483 | * @param stdClass $course course object | |
484 | * @param stdClass $cm course module object | |
485 | * @param stdClass $context context object | |
486 | * @param string $filearea file area | |
487 | * @param array $args extra arguments | |
488 | * @param bool $forcedownload whether or not force download | |
489 | * @param array $options additional options affecting the file serving | |
490 | * @return bool | |
491 | */ | |
492 | function repository_filesystem_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options=array()) { | |
493 | global $OUTPUT; | |
494 | // Allowed filearea is either thumb or icon - size of the thumbnail. | |
495 | if ($filearea !== 'thumb' && $filearea !== 'icon') { | |
496 | return false; | |
497 | } | |
498 | ||
499 | // As itemid we pass repository instance id. | |
500 | $itemid = array_shift($args); | |
501 | // Filename is some token that we can ignore (used only to make sure browser does not serve cached copy when file is changed). | |
502 | array_pop($args); | |
503 | // As filepath we use full filepath (dir+name) of the file in this instance of filesystem repository. | |
504 | $filepath = implode('/', $args); | |
505 | ||
506 | // Make sure file exists in the repository and is accessible. | |
507 | $repo = repository::get_repository_by_id($itemid, $context); | |
508 | $repo->check_capability(); | |
509 | // Find stored or generated thumbnail. | |
510 | if (!($file = $repo->get_thumbnail($filepath, $filearea))) { | |
511 | // Generation failed, redirect to default icon for file extension. | |
512 | redirect($OUTPUT->pix_url(file_extension_icon($file, 90))); | |
513 | } | |
514 | send_stored_file($file, 360, 0, $forcedownload, $options); | |
520de343 | 515 | } |
2ef39ca4 MG |
516 | |
517 | /** | |
518 | * Cron callback for repository_filesystem. Deletes the thumbnails for deleted or changed files. | |
519 | */ | |
520 | function repository_filesystem_cron() { | |
521 | global $DB; | |
522 | // Find all repository instances ids that have generated thumbnails. | |
523 | $sql = "SELECT DISTINCT itemid FROM {files} f WHERE f.contextid = :contextid | |
524 | AND f.component = :component | |
525 | AND (f.filearea = :filearea1 OR f.filearea = :filearea2)"; | |
526 | $itemids = $DB->get_fieldset_sql($sql, array( | |
527 | 'contextid' => SYSCONTEXTID, | |
528 | 'component' => 'repository_filesystem', | |
529 | 'filearea1' => 'thumb', | |
530 | 'filearea2' => 'icon' | |
531 | )); | |
532 | $instances = repository::get_instances(array('type' => 'filesystem')); | |
533 | foreach ($itemids as $itemid) { | |
534 | if (!isset($instances[$itemid])) { | |
535 | // Instance was deleted. | |
536 | $fs = get_file_storage(); | |
537 | $fs->delete_area_files(SYSCONTEXTID, 'repository_filesystem', 'thumb', $itemid); | |
538 | $fs->delete_area_files(SYSCONTEXTID, 'repository_filesystem', 'icon', $itemid); | |
539 | mtrace(" instance $itemid does not exist: deleted all thumbnails"); | |
540 | } else { | |
541 | // Instance has some generated thumbnails, check that they are not outdated. | |
542 | $instances[$itemid]->cron(); | |
543 | } | |
544 | } | |
545 | } |