MDL-33857 Increase performance of queries for Server files repository (small improvements)

This commit is contained in:
Marina Glancy 2012-09-20 15:47:52 +08:00
parent b8de262139
commit 43aadf0401
12 changed files with 183 additions and 144 deletions

View File

@ -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;
}
}
}

View File

@ -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;
}
/**

View File

@ -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;
}
/**

View File

@ -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);
}
/**

View File

@ -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);
}
/**

View File

@ -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);
}
/**

View File

@ -499,7 +499,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
*/
@ -520,7 +521,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';
}
@ -530,12 +531,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;
@ -556,14 +557,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);
}
/**

View File

@ -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);
}
/**

View File

@ -553,7 +553,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
*/
@ -581,7 +582,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';
}
@ -591,12 +592,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;
@ -617,14 +618,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);
}
/**

View File

@ -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);
}
/**

View File

@ -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);
}
/**

View File

@ -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;
}
}