diff --git a/lib/filebrowser/file_info.php b/lib/filebrowser/file_info.php index 0c294f67f02..52ba8b1fc6a 100644 --- a/lib/filebrowser/file_info.php +++ b/lib/filebrowser/file_info.php @@ -128,6 +128,19 @@ abstract class file_info { return true; } + /** + * Is this info area and is it "empty"? Are there any files in subfolders? + * + * This is used mostly in repositories to reduce the + * number of empty folders. This method may be very slow, + * use with care. + * + * @return bool + */ + public function is_empty_area() { + return false; + } + /** * Returns file size in bytes, null for directories * @return int bytes or null if not known diff --git a/lib/filebrowser/file_info_context_course.php b/lib/filebrowser/file_info_context_course.php index 26f95a0d897..20a39ebfdfa 100644 --- a/lib/filebrowser/file_info_context_course.php +++ b/lib/filebrowser/file_info_context_course.php @@ -320,8 +320,6 @@ class file_info_area_course_legacy extends file_info_stored { * @return string url */ public function get_url($forcedownload=false, $https=false) { - global $CFG; - if (!$this->is_readable()) { return null; } @@ -412,6 +410,16 @@ class file_info_area_course_section extends file_info { return false; } + /** + * Is this empty area? + * + * @return bool + */ + public function is_empty_area() { + $fs = get_file_storage(); + return $fs->is_area_empty($this->context->id, 'course', 'section'); + } + /** * Is directory? * @return bool @@ -501,6 +509,16 @@ class file_info_area_backup_section extends file_info { return false; } + /** + * Is this empty area? + * + * @return bool + */ + public function is_empty_area() { + $fs = get_file_storage(); + return $fs->is_area_empty($this->context->id, 'backup', 'section'); + } + /** * Is directory? * @return bool diff --git a/lib/filebrowser/file_info_context_module.php b/lib/filebrowser/file_info_context_module.php index 739eea9686d..45b2d5af9a8 100644 --- a/lib/filebrowser/file_info_context_module.php +++ b/lib/filebrowser/file_info_context_module.php @@ -171,6 +171,34 @@ class file_info_context_module extends file_info { return false; } + /** + * Is this empty area? + * + * @return bool + */ + public function is_empty_area() { + if ($child = $this->get_area_backup(0, '/', '.')) { + if (!$child->is_empty_area()) { + return false; + } + } + if ($child = $this->get_area_intro(0, '/', '.')) { + if (!$child->is_empty_area()) { + return false; + } + } + + foreach ($this->areas as $area=>$desctiption) { + if ($child = $this->get_file_info('mod_'.$this->modname, $area, null, null, null)) { + if (!$child->is_empty_area()) { + return false; + } + } + } + + return true; + } + /** * Is directory? * @return bool diff --git a/lib/filebrowser/file_info_stored.php b/lib/filebrowser/file_info_stored.php index 5cf165e6f8a..708ea11612b 100644 --- a/lib/filebrowser/file_info_stored.php +++ b/lib/filebrowser/file_info_stored.php @@ -78,7 +78,7 @@ class file_info_stored extends file_info { */ public function get_params() { return array('contextid'=>$this->context->id, - 'component' =>$this->lf->get_component(), + 'component'=>$this->lf->get_component(), 'filearea' =>$this->lf->get_filearea(), 'itemid' =>$this->lf->get_itemid(), 'filepath' =>$this->lf->get_filepath(), @@ -127,9 +127,9 @@ class file_info_stored extends file_info { $contextid = $this->lf->get_contextid(); $component = $this->lf->get_component(); $filearea = $this->lf->get_filearea(); + $itemid = $this->lf->get_itemid(); $filepath = $this->lf->get_filepath(); $filename = $this->lf->get_filename(); - $itemid = $this->lf->get_itemid(); if ($this->itemidused) { $path = '/'.$contextid.'/'.$component.'/'.$filearea.'/'.$itemid.$filepath.$filename; @@ -155,6 +155,21 @@ class file_info_stored extends file_info { return $this->writeaccess; } + /** + * Is this top of empty area? + * + * @return bool + */ + public function is_empty_area() { + if ($this->lf->get_filepath() === '/' and $this->lf->get_filename() === '.') { + // test the emptiness only in the top most level, it does not make sense at lower levels + $fs = get_file_storage(); + return $fs->is_area_empty($this->lf->get_contextid(), $this->lf->get_component(), $this->lf->get_filearea(), $this->lf->get_itemid()); + } else { + return false; + } + } + /** * Returns file size in bytes, null for directories * @return int bytes or null if not known diff --git a/lib/filestorage/file_storage.php b/lib/filestorage/file_storage.php index 974bce86543..8c20c277beb 100644 --- a/lib/filestorage/file_storage.php +++ b/lib/filestorage/file_storage.php @@ -213,6 +213,39 @@ class file_storage { return $this->get_file_by_hash($pathnamehash); } + /** + * Are there any files (or directories) + * @param int $contextid + * @param string $component + * @param string $filearea + * @param bool|int $itemid tem id or false if all items + * @param bool $ignoredirs + * @return bool empty + */ + public function is_area_empty($contextid, $component, $filearea, $itemid = false, $ignoredirs = true) { + global $DB; + + $params = array('contextid'=>$contextid, 'component'=>$component, 'filearea'=>$filearea); + $where = "contextid = :contextid AND component = :component AND filearea = :filearea"; + + if ($itemid !== false) { + $params['itemid'] = $itemid; + $where .= " AND itemid = :itemid"; + } + + if ($ignoredirs) { + $sql = "SELECT 'x' + FROM {files} + WHERE $where AND filename <> '.'"; + } else { + $sql = "SELECT 'x' + FROM {files} + WHERE $where AND (filename <> '.' OR filepath <> '/')"; + } + + return !$DB->record_exists_sql($sql, $params); + } + /** * Returns all area files (optionally limited by itemid) * @@ -224,7 +257,7 @@ class file_storage { * @param bool $includedirs * @return array of stored_files indexed by pathanmehash */ - public function get_area_files($contextid, $component, $filearea, $itemid=false, $sort="sortorder, itemid, filepath, filename", $includedirs = true) { + public function get_area_files($contextid, $component, $filearea, $itemid = false, $sort="sortorder, itemid, filepath, filename", $includedirs = true) { global $DB; $conditions = array('contextid'=>$contextid, 'component'=>$component, 'filearea'=>$filearea); diff --git a/repository/local/lib.php b/repository/local/lib.php index 478ba2b5a72..91b0d45289a 100755 --- a/repository/local/lib.php +++ b/repository/local/lib.php @@ -95,6 +95,9 @@ class repository_local extends repository { $children = $fileinfo->get_children(); foreach ($children as $child) { if ($child->is_directory()) { + if ($child->is_empty_area()) { + continue; + } $params = $child->get_params(); $subdir_children = $child->get_children(); //if (empty($subdir_children)) {