From ed7e6a735663de70df69d4d759550cbf11383a3d Mon Sep 17 00:00:00 2001 From: Marina Glancy Date: Thu, 20 Sep 2012 15:47:52 +0800 Subject: [PATCH] MDL-33857 Increase performance of queries for Server files repository (small improvements) --- lib/filebrowser/file_info.php | 39 ++++++------ lib/filebrowser/file_info_context_course.php | 59 +++++++++++-------- .../file_info_context_coursecat.php | 54 +++++++++++------ lib/filebrowser/file_info_context_module.php | 20 +++---- lib/filebrowser/file_info_stored.php | 30 +++++++--- mod/book/locallib.php | 17 +++--- mod/data/locallib.php | 17 +++--- mod/forum/locallib.php | 17 +++--- mod/glossary/locallib.php | 17 +++--- mod/imscp/locallib.php | 21 ++++--- mod/workshop/fileinfolib.php | 19 +++--- repository/local/lib.php | 17 +++--- 12 files changed, 183 insertions(+), 144 deletions(-) diff --git a/lib/filebrowser/file_info.php b/lib/filebrowser/file_info.php index 9ad03640947..0900d6847d8 100644 --- a/lib/filebrowser/file_info.php +++ b/lib/filebrowser/file_info.php @@ -143,7 +143,7 @@ abstract class file_info { $nonemptylist[] = $fileinfo; } else { $filename = $fileinfo->get_visible_name(); - $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); + $extension = textlib::strtolower(pathinfo($filename, PATHINFO_EXTENSION)); if (!empty($extension) && in_array('.'.$extension, $extensions)) { $nonemptylist[] = $fileinfo; } @@ -156,7 +156,7 @@ abstract class file_info { * Returns the number of children which are either files matching the specified extensions * or folders containing at least one such file. * - * NOTE: We don't need the exact number of non empty children if it is >=2 + * We usually don't need the exact number of non empty children if it is >=2 (see param $limit) * This function is used by repository_local to evaluate if the folder is empty. But * it also can be used to check if folder has only one subfolder because in some cases * this subfolder can be skipped. @@ -166,27 +166,32 @@ abstract class file_info { * and memory usage on big sites). * * @param string|array $extensions, for example '*' or array('.gif','.jpg') + * @param int $limit stop counting after at least $limit non-empty children are found * @return int */ - public function count_non_empty_children($extensions = '*') { + public function count_non_empty_children($extensions = '*', $limit = 1) { $list = $this->get_children(); $cnt = 0; + // first loop through files foreach ($list as $fileinfo) { - if ($cnt > 1) { - // it only matters if it is 0, 1 or 2+ - return $cnt; - } - if ($fileinfo->is_directory()) { - if ($fileinfo->count_non_empty_children($extensions)) { - $cnt++; + if (!$fileinfo->is_directory()) { + if ($extensions !== '*') { + $filename = $fileinfo->get_visible_name(); + $extension = textlib::strtolower(pathinfo($filename, PATHINFO_EXTENSION)); + if (empty($extension) || !in_array('.'.$extension, $extensions)) { + continue; + } } - } else if ($extensions === '*') { - $cnt++; - } else { - $filename = $fileinfo->get_visible_name(); - $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); - if (!empty($extension) && in_array('.'.$extension, $extensions)) { - $cnt++; + if ((++$cnt) >= $limit) { + return $cnt; + } + } + } + // now loop through directories + foreach ($list as $fileinfo) { + if ($fileinfo->is_directory() && $fileinfo->count_non_empty_children($extensions)) { + if ((++$cnt) >= $limit) { + return $cnt; } } } diff --git a/lib/filebrowser/file_info_context_course.php b/lib/filebrowser/file_info_context_course.php index 0ee7402bd4d..c88740ae389 100644 --- a/lib/filebrowser/file_info_context_course.php +++ b/lib/filebrowser/file_info_context_course.php @@ -357,7 +357,8 @@ class file_info_context_course extends file_info { * Help function to return files matching extensions or their count * * @param string|array $extensions, either '*' or array of lowercase extensions, i.e. array('.gif','.jpg') - * @param bool $countonly if true returns the count of children (0, 1 or 2 if more than 1) + * @param bool|int $countonly if false returns the children, if an int returns just the + * count of children but stops counting when $countonly number of children is reached * @param bool $returnemptyfolders if true returns items that don't have matching files inside * @return array|int array of file_info instances or the count */ @@ -375,8 +376,8 @@ class file_info_context_course extends file_info { if ($child = $this->get_file_info($area[0], $area[1], 0, '/', '.')) { if ($returnemptyfolders || $child->count_non_empty_children($extensions)) { $children[] = $child; - if ($countonly && count($children)>1) { - return 2; + if (($countonly !== false) && count($children)>=$countonly) { + return $countonly; } } } @@ -396,15 +397,15 @@ class file_info_context_course extends file_info { if ($child = $this->browser->get_file_info($modcontext)) { if ($returnemptyfolders || $child->count_non_empty_children($extensions)) { $children[] = $child; - if ($countonly && count($children)>1) { - return 2; + if (($countonly !== false) && count($children)>=$countonly) { + return $countonly; } } } } } - if ($countonly) { + if ($countonly !== false) { return count($children); } return $children; @@ -425,14 +426,12 @@ class file_info_context_course extends file_info { * Returns the number of children which are either files matching the specified extensions * or folders containing at least one such file. * - * NOTE: We don't need the exact number of non empty children if it is >=2 - * In this function 1 is never returned to avoid skipping the single subfolder - * * @param string|array $extensions, for example '*' or array('.gif','.jpg') + * @param int $limit stop counting after at least $limit non-empty children are found * @return int */ - public function count_non_empty_children($extensions = '*') { - return $this->get_filtered_children($extensions, true); + public function count_non_empty_children($extensions = '*', $limit = 1) { + return $this->get_filtered_children($extensions, $limit); } /** @@ -535,7 +534,7 @@ class file_info_area_course_legacy extends file_info_stored { $storedfiles = $fs->get_directory_files($this->context->id, 'course', 'legacy', 0, $this->lf->get_filepath(), false, true, "filepath, filename"); foreach ($storedfiles as $file) { - $extension = strtolower(pathinfo($file->get_filename(), PATHINFO_EXTENSION)); + $extension = textlib::strtolower(pathinfo($file->get_filename(), PATHINFO_EXTENSION)); if ($file->is_directory() || $extensions === '*' || (!empty($extension) && in_array('.'.$extension, $extensions))) { $fileinfo = new file_info_area_course_legacy($this->browser, $this->context, $file, $this->urlbase, $this->topvisiblename, $this->itemidused, $this->readaccess, $this->writeaccess, false); @@ -656,13 +655,11 @@ class file_info_area_course_section extends file_info { * Returns the number of children which are either files matching the specified extensions * or folders containing at least one such file. * - * NOTE: We don't need the exact number of non empty children if it is >=2 - * In this function 1 is never returned to avoid skipping the single subfolder - * * @param string|array $extensions, for example '*' or array('.gif','.jpg') + * @param int $limit stop counting after at least $limit non-empty children are found * @return int */ - public function count_non_empty_children($extensions = '*') { + public function count_non_empty_children($extensions = '*', $limit = 1) { global $DB; $params1 = array( 'courseid' => $this->course->id, @@ -670,7 +667,7 @@ class file_info_area_course_section extends file_info { 'component' => 'course', 'filearea' => 'section', 'emptyfilename' => '.'); - $sql1 = "SELECT 1 from {files} f, {course_sections} cs + $sql1 = "SELECT DISTINCT cs.id FROM {files} f, {course_sections} cs WHERE cs.course = :courseid AND f.contextid = :contextid AND f.component = :component @@ -678,7 +675,15 @@ class file_info_area_course_section extends file_info { AND f.itemid = cs.id AND f.filename <> :emptyfilename"; list($sql2, $params2) = $this->build_search_files_sql($extensions); - return $DB->record_exists_sql($sql1.' '.$sql2, array_merge($params1, $params2)) ? 2 : 0; + $rs = $DB->get_recordset_sql($sql1. ' '. $sql2, array_merge($params1, $params2)); + $cnt = 0; + foreach ($rs as $record) { + if ((++$cnt) >= $limit) { + break; + } + } + $rs->close(); + return $cnt; } /** @@ -796,13 +801,11 @@ class file_info_area_backup_section extends file_info { * Returns the number of children which are either files matching the specified extensions * or folders containing at least one such file. * - * NOTE: We don't need the exact number of non empty children if it is >=2 - * In this function 1 is never returned to avoid skipping the single subfolder - * * @param string|array $extensions, for example '*' or array('.gif','.jpg') + * @param int $limit stop counting after at least $limit non-empty children are found * @return int */ - public function count_non_empty_children($extensions = '*') { + public function count_non_empty_children($extensions = '*', $limit = 1) { global $DB; $params1 = array( 'courseid' => $this->course->id, @@ -810,7 +813,7 @@ class file_info_area_backup_section extends file_info { 'component' => 'backup', 'filearea' => 'section', 'emptyfilename' => '.'); - $sql1 = "SELECT 1 from {files} f, {course_sections} cs + $sql1 = "SELECT DISTINCT cs.id sectionid FROM {files} f, {course_sections} cs WHERE cs.course = :courseid AND f.contextid = :contextid AND f.component = :component @@ -818,7 +821,15 @@ class file_info_area_backup_section extends file_info { AND f.itemid = cs.id AND f.filename <> :emptyfilename"; list($sql2, $params2) = $this->build_search_files_sql($extensions); - return $DB->record_exists_sql($sql1.' '.$sql2, array_merge($params1, $params2)) ? 2 : 0; + $rs = $DB->get_recordset_sql($sql1. ' '. $sql2, array_merge($params1, $params2)); + $cnt = 0; + foreach ($rs as $record) { + if ((++$cnt) >= $limit) { + break; + } + } + $rs->close(); + return $cnt; } /** diff --git a/lib/filebrowser/file_info_context_coursecat.php b/lib/filebrowser/file_info_context_coursecat.php index 97e3d9104c9..e8d542cf898 100644 --- a/lib/filebrowser/file_info_context_coursecat.php +++ b/lib/filebrowser/file_info_context_coursecat.php @@ -192,44 +192,60 @@ class file_info_context_coursecat extends file_info { * Returns the number of children which are either files matching the specified extensions * or folders containing at least one such file. * - * NOTE: We don't need the exact number of non empty children if it is >=2 - * In this function 1 is never returned to avoid skipping the single subfolder - * * @param string|array $extensions, for example '*' or array('.gif','.jpg') + * @param int $limit stop counting after at least $limit non-empty children are found * @return int */ - public function count_non_empty_children($extensions = '*') { + public function count_non_empty_children($extensions = '*', $limit = 1) { global $DB; + $cnt = 0; if (($child = $this->get_area_coursecat_description(0, '/', '.')) - && $child->count_non_empty_children($extensions)) { - return 2; + && $child->count_non_empty_children($extensions) && (++$cnt) >= $limit) { + return $cnt; } - $course_cats = $DB->get_records('course_categories', array('parent'=>$this->category->id), 'sortorder', 'id,visible'); - foreach ($course_cats as $category) { - $context = context_coursecat::instance($category->id); - if (!$category->visible and !has_capability('moodle/category:viewhiddencategories', $context)) { + $rs = $DB->get_recordset_sql('SELECT ctx.id contextid, c.visible + FROM {context} ctx, {course} c + WHERE ctx.instanceid = c.id + AND ctx.contextlevel = :courselevel + AND c.category = :categoryid + ORDER BY c.visible DESC', // retrieve visible courses first + array('categoryid' => $this->category->id, 'courselevel' => CONTEXT_COURSE)); + foreach ($rs as $record) { + $context = context::instance_by_id($record->contextid); + if (!$record->visible and !has_capability('moodle/course:viewhiddencourses', $context)) { continue; } if (($child = $this->browser->get_file_info($context)) - && $child->count_non_empty_children($extensions)) { - return 2; + && $child->count_non_empty_children($extensions) && (++$cnt) >= $limit) { + break; } } + $rs->close(); + if ($cnt >= $limit) { + return $cnt; + } - $courses = $DB->get_records('course', array('category'=>$this->category->id), 'sortorder', 'id,visible'); - foreach ($courses as $course) { - $context = context_course::instance($course->id); - if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $context)) { + $rs = $DB->get_recordset_sql('SELECT ctx.id contextid, cat.visible + FROM {context} ctx, {course_categories} cat + WHERE ctx.instanceid = cat.id + AND ctx.contextlevel = :catlevel + AND cat.parent = :categoryid + ORDER BY cat.visible DESC', // retrieve visible categories first + array('categoryid' => $this->category->id, 'catlevel' => CONTEXT_COURSECAT)); + foreach ($rs as $record) { + $context = context::instance_by_id($record->contextid); + if (!$record->visible and !has_capability('moodle/category:viewhiddencategories', $context)) { continue; } if (($child = $this->browser->get_file_info($context)) - && $child->count_non_empty_children($extensions)) { - return 2; + && $child->count_non_empty_children($extensions) && (++$cnt) >= $limit) { + break; } } + $rs->close(); - return 0; + return $cnt; } /** diff --git a/lib/filebrowser/file_info_context_module.php b/lib/filebrowser/file_info_context_module.php index a873737d53a..5636503968b 100644 --- a/lib/filebrowser/file_info_context_module.php +++ b/lib/filebrowser/file_info_context_module.php @@ -268,7 +268,8 @@ class file_info_context_module extends file_info { * Help function to return files matching extensions or their count * * @param string|array $extensions, either '*' or array of lowercase extensions, i.e. array('.gif','.jpg') - * @param bool $countonly if true returns the count of children (0, 1 or 2 if more than 1) + * @param bool|int $countonly if false returns the children, if an int returns just the + * count of children but stops counting when $countonly number of children is reached * @param bool $returnemptyfolders if true returns items that don't have matching files inside * @return array|int array of file_info instances or the count */ @@ -303,13 +304,13 @@ class file_info_context_module extends file_info { if ($child = $this->get_file_info($area[0], $area[1], null, null, null)) { if ($returnemptyfolders || $child->count_non_empty_children($extensions)) { $children[] = $child; - if ($countonly && count($children)>1) { + if ($countonly !== false && count($children) >= $countonly) { break; } } } } - if ($countonly) { + if ($countonly !== false) { return count($children); } return $children; @@ -319,11 +320,10 @@ class file_info_context_module extends file_info { * Returns list of children which are either files matching the specified extensions * or folders that contain at least one such file. * - * @param string|array $extensions, either '*' or array of lowercase extensions, i.e. array('.gif','.jpg') + * @param string|array $extensions either '*' or array of lowercase extensions, i.e. array('.gif','.jpg') * @return array of file_info instances */ public function get_non_empty_children($extensions = '*') { - global $DB; if ($this->nonemptychildren !== null) { return $this->nonemptychildren; } @@ -335,17 +335,15 @@ class file_info_context_module extends file_info { * Returns the number of children which are either files matching the specified extensions * or folders containing at least one such file. * - * NOTE: We don't need the exact number of non empty children if it is >=2 - * - * @param string|array $extensions, for example '*' or array('.gif','.jpg') + * @param string|array $extensions for example '*' or array('.gif','.jpg') + * @param int $limit stop counting after at least $limit non-empty children are found * @return int */ - public function count_non_empty_children($extensions = '*') { - global $DB; + public function count_non_empty_children($extensions = '*', $limit = 1) { if ($this->nonemptychildren !== null) { return count($this->nonemptychildren); } - return $this->get_filtered_children($extensions, true); + return $this->get_filtered_children($extensions, $limit); } /** diff --git a/lib/filebrowser/file_info_stored.php b/lib/filebrowser/file_info_stored.php index 1c4d2d2a86c..e9caf4cab03 100644 --- a/lib/filebrowser/file_info_stored.php +++ b/lib/filebrowser/file_info_stored.php @@ -368,7 +368,7 @@ class file_info_stored extends file_info { $storedfiles = $fs->get_directory_files($this->context->id, $this->lf->get_component(), $this->lf->get_filearea(), $this->lf->get_itemid(), $this->lf->get_filepath(), false, true, "filepath, filename"); foreach ($storedfiles as $file) { - $extension = strtolower(pathinfo($file->get_filename(), PATHINFO_EXTENSION)); + $extension = textlib::strtolower(pathinfo($file->get_filename(), PATHINFO_EXTENSION)); if ($file->is_directory() || $extensions === '*' || (!empty($extension) && in_array('.'.$extension, $extensions))) { $fileinfo = new file_info_stored($this->browser, $this->context, $file, $this->urlbase, $this->topvisiblename, $this->itemidused, $this->readaccess, $this->writeaccess, false); @@ -385,13 +385,11 @@ class file_info_stored extends file_info { * Returns the number of children which are either files matching the specified extensions * or folders containing at least one such file. * - * NOTE: We don't need the exact number of non empty children if it is >=2 - * In this function 1 is never returned to avoid skipping the single subfolder - * * @param string|array $extensions, for example '*' or array('.gif','.jpg') + * @param int $limit stop counting after at least $limit non-empty children are found * @return int */ - public function count_non_empty_children($extensions = '*') { + public function count_non_empty_children($extensions = '*', $limit = 1) { global $DB; if (!$this->lf->is_directory()) { return 0; @@ -399,7 +397,7 @@ class file_info_stored extends file_info { $filepath = $this->lf->get_filepath(); $length = textlib::strlen($filepath); - $sql = "SELECT 1 + $sql = "SELECT filepath, filename FROM {files} f WHERE f.contextid = :contextid AND f.component = :component AND f.filearea = :filearea AND f.itemid = :itemid AND ".$DB->sql_substr("f.filepath", 1, $length)." = :filepath @@ -410,8 +408,24 @@ class file_info_stored extends file_info { 'itemid' => $this->lf->get_itemid(), 'filepath' => $filepath); list($sql2, $params2) = $this->build_search_files_sql($extensions); - // we don't need to check access to individual files here, since the user can access parent - return $DB->record_exists_sql($sql.' '.$sql2, array_merge($params, $params2)) ? 2 : 0; + $rs = $DB->get_recordset_sql($sql.' '.$sql2, array_merge($params, $params2)); + $children = array(); + foreach ($rs as $record) { + // we don't need to check access to individual files here, since the user can access parent + if ($record->filepath === $filepath) { + $children[] = $record->filename; + } else { + $path = explode('/', textlib::substr($record->filepath, $length)); + if (!in_array($path[0], $children)) { + $children[] = $path[0]; + } + } + if (count($children) >= $limit) { + break; + } + } + $rs->close(); + return count($children); } /** diff --git a/mod/book/locallib.php b/mod/book/locallib.php index eba2e52e9ea..95028054c28 100644 --- a/mod/book/locallib.php +++ b/mod/book/locallib.php @@ -455,7 +455,8 @@ class book_file_info extends file_info { * Help function to return files matching extensions or their count * * @param string|array $extensions, either '*' or array of lowercase extensions, i.e. array('.gif','.jpg') - * @param bool $countonly if true returns the count of children (0, 1 or 2 if more than 1) + * @param bool|int $countonly if false returns the children, if an int returns just the + * count of children but stops counting when $countonly number of children is reached * @param bool $returnemptyfolders if true returns items that don't have matching files inside * @return array|int array of file_info instances or the count */ @@ -479,7 +480,7 @@ class book_file_info extends file_info { list($sql2, $params2) = $this->build_search_files_sql($extensions, 'f'); $sql .= ' '.$sql2; $params = array_merge($params, $params2); - if (!$countonly) { + if ($countonly === false) { $sql .= ' ORDER BY bc.pagenum'; } @@ -491,12 +492,12 @@ class book_file_info extends file_info { $children[] = $child; } } - if ($countonly && count($children)>1) { + if ($countonly !== false && count($children) >= $countonly) { break; } } $rs->close(); - if ($countonly) { + if ($countonly !== false) { return count($children); } return $children; @@ -517,14 +518,12 @@ class book_file_info extends file_info { * Returns the number of children which are either files matching the specified extensions * or folders containing at least one such file. * - * NOTE: We don't need the exact number of non empty children if it is >=2 - * In this function 1 is never returned to avoid skipping the single subfolder - * * @param string|array $extensions, for example '*' or array('.gif','.jpg') + * @param int $limit stop counting after at least $limit non-empty children are found * @return int */ - public function count_non_empty_children($extensions = '*') { - return $this->get_filtered_children($extensions, true); + public function count_non_empty_children($extensions = '*', $limit = 1) { + return $this->get_filtered_children($extensions, $limit); } /** diff --git a/mod/data/locallib.php b/mod/data/locallib.php index 16c25c70582..55a2070761f 100644 --- a/mod/data/locallib.php +++ b/mod/data/locallib.php @@ -500,7 +500,8 @@ class data_file_info_container extends file_info { * Help function to return files matching extensions or their count * * @param string|array $extensions, either '*' or array of lowercase extensions, i.e. array('.gif','.jpg') - * @param bool $countonly if true returns the count of children (0, 1 or 2 if more than 1) + * @param bool|int $countonly if false returns the children, if an int returns just the + * count of children but stops counting when $countonly number of children is reached * @param bool $returnemptyfolders if true returns items that don't have matching files inside * @return array|int array of file_info instances or the count */ @@ -521,7 +522,7 @@ class data_file_info_container extends file_info { list($sql2, $params2) = $this->build_search_files_sql($extensions); $sql .= ' '.$sql2; $params = array_merge($params, $params2); - if (!$countonly) { + if ($countonly === false) { $sql .= ' ORDER BY itemid DESC'; } @@ -531,12 +532,12 @@ class data_file_info_container extends file_info { if ($child = $this->browser->get_file_info($this->context, 'mod_data', $this->filearea, $record->itemid)) { $children[] = $child; } - if ($countonly && count($children)>1) { + if ($countonly !== false && count($children) >= $countonly) { break; } } $rs->close(); - if ($countonly) { + if ($countonly !== false) { return count($children); } return $children; @@ -557,14 +558,12 @@ class data_file_info_container extends file_info { * Returns the number of children which are either files matching the specified extensions * or folders containing at least one such file. * - * NOTE: We don't need the exact number of non empty children if it is >=2 - * In this function 1 is never returned to avoid skipping the single subfolder - * * @param string|array $extensions, for example '*' or array('.gif','.jpg') + * @param int $limit stop counting after at least $limit non-empty children are found * @return int */ - public function count_non_empty_children($extensions = '*') { - return $this->get_filtered_children($extensions, true); + public function count_non_empty_children($extensions = '*', $limit = 1) { + return $this->get_filtered_children($extensions, $limit); } /** diff --git a/mod/forum/locallib.php b/mod/forum/locallib.php index f8840b6dc82..406352ab7fb 100644 --- a/mod/forum/locallib.php +++ b/mod/forum/locallib.php @@ -490,7 +490,8 @@ class forum_file_info_container extends file_info { * Help function to return files matching extensions or their count * * @param string|array $extensions, either '*' or array of lowercase extensions, i.e. array('.gif','.jpg') - * @param bool $countonly if true returns the count of children (0, 1 or 2 if more than 1) + * @param bool|int $countonly if false returns the children, if an int returns just the + * count of children but stops counting when $countonly number of children is reached * @param bool $returnemptyfolders if true returns items that don't have matching files inside * @return array|int array of file_info instances or the count */ @@ -511,7 +512,7 @@ class forum_file_info_container extends file_info { list($sql2, $params2) = $this->build_search_files_sql($extensions); $sql .= ' '.$sql2; $params = array_merge($params, $params2); - if (!$countonly) { + if ($countonly !== false) { $sql .= ' ORDER BY itemid DESC'; } @@ -522,12 +523,12 @@ class forum_file_info_container extends file_info { && ($returnemptyfolders || $child->count_non_empty_children($extensions))) { $children[] = $child; } - if ($countonly && count($children)>1) { + if ($countonly !== false && count($children) >= $countonly) { break; } } $rs->close(); - if ($countonly) { + if ($countonly !== false) { return count($children); } return $children; @@ -548,14 +549,12 @@ class forum_file_info_container extends file_info { * Returns the number of children which are either files matching the specified extensions * or folders containing at least one such file. * - * NOTE: We don't need the exact number of non empty children if it is >=2 - * In this function 1 is never returned to avoid skipping the single subfolder - * * @param string|array $extensions, for example '*' or array('.gif','.jpg') + * @param int $limit stop counting after at least $limit non-empty children are found * @return int */ - public function count_non_empty_children($extensions = '*') { - return $this->get_filtered_children($extensions, true); + public function count_non_empty_children($extensions = '*', $limit = 1) { + return $this->get_filtered_children($extensions, $limit); } /** diff --git a/mod/glossary/locallib.php b/mod/glossary/locallib.php index e8481386b9c..26dee0f6cef 100644 --- a/mod/glossary/locallib.php +++ b/mod/glossary/locallib.php @@ -547,7 +547,8 @@ class glossary_file_info_container extends file_info { * Help function to return files matching extensions or their count * * @param string|array $extensions, either '*' or array of lowercase extensions, i.e. array('.gif','.jpg') - * @param bool $countonly if true returns the count of children (0, 1 or 2 if more than 1) + * @param bool|int $countonly if false returns the children, if an int returns just the + * count of children but stops counting when $countonly number of children is reached * @param bool $returnemptyfolders if true returns items that don't have matching files inside * @return array|int array of file_info instances or the count */ @@ -575,7 +576,7 @@ class glossary_file_info_container extends file_info { list($sql2, $params2) = $this->build_search_files_sql($extensions, 'f'); $sql .= ' '.$sql2; $params = array_merge($params, $params2); - if (!$countonly) { + if ($countonly !== false) { $sql .= ' ORDER BY ge.concept, f.itemid'; } @@ -585,12 +586,12 @@ class glossary_file_info_container extends file_info { if ($child = $this->browser->get_file_info($this->context, 'mod_glossary', $this->filearea, $record->itemid)) { $children[] = $child; } - if ($countonly && count($children)>1) { + if ($countonly !== false && count($children) >= $countonly) { break; } } $rs->close(); - if ($countonly) { + if ($countonly !== false) { return count($children); } return $children; @@ -611,14 +612,12 @@ class glossary_file_info_container extends file_info { * Returns the number of children which are either files matching the specified extensions * or folders containing at least one such file. * - * NOTE: We don't need the exact number of non empty children if it is >=2 - * In this function 1 is never returned to avoid skipping the single subfolder - * * @param string|array $extensions, for example '*' or array('.gif','.jpg') + * @param int $limit stop counting after at least $limit non-empty children are found * @return int */ - public function count_non_empty_children($extensions = '*') { - return $this->get_filtered_children($extensions, true); + public function count_non_empty_children($extensions = '*', $limit = 1) { + return $this->get_filtered_children($extensions, $limit); } /** diff --git a/mod/imscp/locallib.php b/mod/imscp/locallib.php index bff1b0e3cbb..04b16fb159b 100644 --- a/mod/imscp/locallib.php +++ b/mod/imscp/locallib.php @@ -280,7 +280,8 @@ class imscp_file_info extends file_info { * Help function to return files matching extensions or their count * * @param string|array $extensions, either '*' or array of lowercase extensions, i.e. array('.gif','.jpg') - * @param bool $countonly if true returns the count of children (0, 1 or 2 if more than 1) + * @param bool|int $countonly if false returns the children, if an int returns just the + * count of children but stops counting when $countonly number of children is reached * @param bool $returnemptyfolders if true returns items that don't have matching files inside * @return array|int array of file_info instances or the count */ @@ -301,7 +302,7 @@ class imscp_file_info extends file_info { list($sql2, $params2) = $this->build_search_files_sql($extensions); $sql .= ' '.$sql2; $params = array_merge($params, $params2); - if (!$countonly) { + if ($countonly !== false) { $sql .= ' ORDER BY itemid'; } @@ -310,13 +311,13 @@ class imscp_file_info extends file_info { foreach ($rs as $record) { if ($child = $this->browser->get_file_info($this->context, 'mod_imscp', $this->filearea, $record->itemid)) { $children[] = $child; - } - if ($countonly && count($children)>1) { - break; + if ($countonly !== false && count($children) >= $countonly) { + break; + } } } $rs->close(); - if ($countonly) { + if ($countonly !== false) { return count($children); } return $children; @@ -337,14 +338,12 @@ class imscp_file_info extends file_info { * Returns the number of children which are either files matching the specified extensions * or folders containing at least one such file. * - * NOTE: We don't need the exact number of non empty children if it is >=2 - * In this function 1 is never returned to avoid skipping the single subfolder - * * @param string|array $extensions, for example '*' or array('.gif','.jpg') + * @param int $limit stop counting after at least $limit non-empty children are found * @return int */ - public function count_non_empty_children($extensions = '*') { - return $this->get_filtered_children($extensions, true); + public function count_non_empty_children($extensions = '*', $limit = 1) { + return $this->get_filtered_children($extensions, $limit); } /** diff --git a/mod/workshop/fileinfolib.php b/mod/workshop/fileinfolib.php index eb1a3bfdbc1..35afd24cf49 100644 --- a/mod/workshop/fileinfolib.php +++ b/mod/workshop/fileinfolib.php @@ -96,11 +96,13 @@ class workshop_file_info_submissions_container extends file_info { public function get_children() { return $this->get_filtered_children('*', false, true); } + /** * Help function to return files matching extensions or their count * * @param string|array $extensions, either '*' or array of lowercase extensions, i.e. array('.gif','.jpg') - * @param bool $countonly if true returns the count of children (0, 1 or 2 if more than 1) + * @param bool|int $countonly if false returns the children, if an int returns just the + * count of children but stops counting when $countonly number of children is reached * @param bool $returnemptyfolders if true returns items that don't have matching files inside * @return array|int array of file_info instances or the count */ @@ -121,7 +123,7 @@ class workshop_file_info_submissions_container extends file_info { list($sql2, $params2) = $this->build_search_files_sql($extensions); $sql .= ' '.$sql2; $params = array_merge($params, $params2); - if (!$countonly) { + if ($countonly !== false) { $sql .= ' ORDER BY itemid DESC'; } @@ -131,13 +133,13 @@ class workshop_file_info_submissions_container extends file_info { if (($child = $this->browser->get_file_info($this->context, 'mod_workshop', $this->filearea, $record->itemid)) && ($returnemptyfolders || $child->count_non_empty_children($extensions))) { $children[] = $child; - } - if ($countonly && count($children)>1) { - break; + if ($countonly !== false && count($children) >= $countonly) { + break; + } } } $rs->close(); - if ($countonly) { + if ($countonly !== false) { return count($children); } return $children; @@ -162,10 +164,11 @@ class workshop_file_info_submissions_container extends file_info { * In this function 1 is never returned to avoid skipping the single subfolder * * @param string|array $extensions, for example '*' or array('.gif','.jpg') + * @param int $limit stop counting after at least $limit non-empty children are found * @return int */ - public function count_non_empty_children($extensions = '*') { - return $this->get_filtered_children($extensions, true); + public function count_non_empty_children($extensions = '*', $limit = 1) { + return $this->get_filtered_children($extensions, $limit); } /** diff --git a/repository/local/lib.php b/repository/local/lib.php index a0b77a5af26..b41100ce44f 100644 --- a/repository/local/lib.php +++ b/repository/local/lib.php @@ -67,10 +67,7 @@ class repository_local extends repository { } } if (empty($context) && !empty($this->context)) { - list($repositorycontext, $course, $cm) = get_context_info_array($this->context->id); - if (isset($course->id)) { - $context = context_course::instance($course->id); - } + $context = $this->context->get_course_context(false); } if (empty($context)) { $context = context_system::instance(); @@ -85,7 +82,7 @@ class repository_local extends repository { if (!is_array($extensions)) { $extensions = array($extensions); } - $extensions = array_map('strtolower', $extensions); + $extensions = array_map('textlib::strtolower', $extensions); } // build file tree @@ -143,7 +140,7 @@ class repository_local extends repository { /** * Returns all children elements that have one of the specified extensions * - * This function may skip subfolers and recursively add their children + * This function may skip subfolders and recursively add their children * {@link repository_local::can_skip()} * * @param file_info $fileinfo @@ -164,7 +161,7 @@ class repository_local extends repository { } /** - * Wether this folder may be skipped in folder hierarchy + * Whether this folder may be skipped in folder hierarchy * * 1. Skip the name of a single filearea in a module * 2. Skip course categories for non-admins who do not have navshowmycoursecategories setting @@ -176,7 +173,6 @@ class repository_local extends repository { */ private function can_skip(file_info $fileinfo, $extensions, $parent = -1) { global $CFG; - static $skipcategories = null; if (!$fileinfo->is_directory()) { // do not skip files return false; @@ -196,13 +192,14 @@ class repository_local extends repository { $params = $fileinfo->get_params(); if (strlen($params['filearea']) && ($params['filepath'] === '/' || empty($params['filepath'])) && - ($params['filename'] === '.' || empty($params['filename']))) { + ($params['filename'] === '.' || empty($params['filename'])) && + context::instance_by_id($params['contextid'])->contextlevel == CONTEXT_MODULE) { if ($parent === -1) { $parent = $fileinfo->get_parent(); } // This is a filearea inside an activity, it can be skipped if it has no non-empty siblings if ($parent && ($parent instanceof file_info_context_module)) { - if ($parent->count_non_empty_children($extensions) <= 1) { + if ($parent->count_non_empty_children($extensions, 2) <= 1) { return true; } }