From b47dc5ffea2e3ca5d9dda9e3e5d5b140a79f4655 Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Fri, 13 Dec 2013 13:53:24 +0100 Subject: [PATCH 1/3] MDL-42212 mod_lesson: Fix callbacks retrieving activity files --- mod/lesson/lib.php | 34 ++++++-- mod/lesson/locallib.php | 169 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+), 5 deletions(-) diff --git a/mod/lesson/lib.php b/mod/lesson/lib.php index ec400821235..7fcbfc93441 100644 --- a/mod/lesson/lib.php +++ b/mod/lesson/lib.php @@ -935,20 +935,44 @@ function lesson_get_file_areas() { * @return file_info_stored */ function lesson_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) { - global $CFG; - if (has_capability('moodle/course:managefiles', $context)) { - // no peaking here for students!! + global $CFG, $DB; + + if (!has_capability('moodle/course:managefiles', $context)) { + // No peaking here for students! return null; } + // Mediafile area does not have sub directories, so let's select the default itemid to prevent + // the user from selecting a directory to access the mediafile content. + if ($filearea == 'mediafile' && is_null($itemid)) { + $itemid = 0; + } + + if (is_null($itemid)) { + require_once(__DIR__ . '/locallib.php'); + return new mod_lesson_file_info($browser, $course, $cm, $context, $areas, $filearea); + } + $fs = get_file_storage(); $filepath = is_null($filepath) ? '/' : $filepath; $filename = is_null($filename) ? '.' : $filename; - $urlbase = $CFG->wwwroot.'/pluginfile.php'; if (!$storedfile = $fs->get_file($context->id, 'mod_lesson', $filearea, $itemid, $filepath, $filename)) { return null; } - return new file_info_stored($browser, $context, $storedfile, $urlbase, $filearea, $itemid, true, true, false); + + $itemname = $filearea; + if ($filearea == 'page_contents') { + $itemname = $DB->get_field('lesson_pages', 'title', array('lessonid' => $cm->instance, 'id' => $itemid)); + $itemname = format_string($itemname, true, array('context' => $context)); + } else { + $areas = lesson_get_file_areas(); + if (isset($areas[$filearea])) { + $itemname = $areas[$filearea]; + } + } + + $urlbase = $CFG->wwwroot . '/pluginfile.php'; + return new file_info_stored($browser, $context, $storedfile, $urlbase, $itemname, $itemid, true, true, false); } diff --git a/mod/lesson/locallib.php b/mod/lesson/locallib.php index 7011be6e293..8e71ac689eb 100644 --- a/mod/lesson/locallib.php +++ b/mod/lesson/locallib.php @@ -2819,3 +2819,172 @@ class lesson_page_type_manager { return $links; } } + +/** + * File browsing support class. + * + * @package mod_lesson + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class mod_lesson_file_info extends file_info { + + /** @var stdClass Course object */ + protected $course; + /** @var stdClass Course module object */ + protected $cm; + /** @var array Available file areas */ + protected $areas; + /** @var string File area to browse */ + protected $filearea; + + /** + * Constructor + * + * @param file_browser $browser file_browser instance + * @param stdClass $course course object + * @param stdClass $cm course module object + * @param stdClass $context module context + * @param array $areas available file areas + * @param string $filearea file area to browse + */ + public function __construct($browser, $course, $cm, $context, $areas, $filearea) { + parent::__construct($browser, $context); + $this->course = $course; + $this->cm = $cm; + $this->areas = $areas; + $this->filearea = $filearea; + } + + /** + * Returns list of standard virtual file/directory identification. + * The difference from stored_file parameters is that null values + * are allowed in all fields + * @return array with keys contextid, filearea, itemid, filepath and filename + */ + public function get_params() { + return array('contextid' => $this->context->id, + 'component' => 'mod_lesson', + 'filearea' => $this->filearea, + 'itemid' => null, + 'filepath' => null, + 'filename' => null); + } + + /** + * Returns localised visible name. + * @return string + */ + public function get_visible_name() { + return $this->areas[$this->filearea]; + } + + /** + * Can I add new files or directories? + * @return bool + */ + public function is_writable() { + return false; + } + + /** + * Is directory? + * @return bool + */ + public function is_directory() { + return true; + } + + /** + * Returns list of children. + * @return array of file_info instances + */ + 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|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 + */ + private function get_filtered_children($extensions = '*', $countonly = false, $returnemptyfolders = false) { + global $DB; + + $params = array( + 'contextid' => $this->context->id, + 'component' => 'mod_lesson', + 'filearea' => $this->filearea + ); + $sql = 'SELECT DISTINCT itemid + FROM {files} + WHERE contextid = :contextid + AND component = :component + AND filearea = :filearea'; + + if (!$returnemptyfolders) { + $sql .= ' AND filename <> :emptyfilename'; + $params['emptyfilename'] = '.'; + } + + list($sql2, $params2) = $this->build_search_files_sql($extensions); + $sql .= ' ' . $sql2; + $params = array_merge($params, $params2); + + if ($countonly !== false) { + $sql .= ' ORDER BY itemid DESC'; + } + + $rs = $DB->get_recordset_sql($sql, $params); + $children = array(); + foreach ($rs as $record) { + if (($child = $this->browser->get_file_info($this->context, 'mod_lesson', $this->filearea, $record->itemid)) + && ($returnemptyfolders || $child->count_non_empty_children($extensions))) { + $children[] = $child; + } + if ($countonly !== false && count($children) >= $countonly) { + break; + } + } + $rs->close(); + if ($countonly !== false) { + return count($children); + } + return $children; + } + + /** + * 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') + * @return array of file_info instances + */ + public function get_non_empty_children($extensions = '*') { + return $this->get_filtered_children($extensions, false); + } + + /** + * Returns the number of children which are either files matching the specified extensions + * or folders containing at least one such file. + * + * @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 = '*', $limit = 1) { + return $this->get_filtered_children($extensions, $limit); + } + + /** + * Returns parent file_info instance + * @return file_info or null for root + */ + public function get_parent() { + return $this->browser->get_file_info($this->context); + } +} From 89133afae6374c6b982b9b7dad2da0deba049020 Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Mon, 16 Dec 2013 06:45:45 +0100 Subject: [PATCH 2/3] MDL-42212 mod_lesson: Localise area names --- mod/lesson/lib.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mod/lesson/lib.php b/mod/lesson/lib.php index 7fcbfc93441..a614f6c51c6 100644 --- a/mod/lesson/lib.php +++ b/mod/lesson/lib.php @@ -906,14 +906,12 @@ function lesson_pluginfile($course, $cm, $context, $filearea, $args, $forcedownl * * @package mod_lesson * @category files - * @todo MDL-31048 localize * @return array a list of available file areas */ function lesson_get_file_areas() { $areas = array(); - $areas['page_contents'] = 'Page contents'; //TODO: localize!!!! - $areas['mediafile'] = 'Media file'; //TODO: localize!!!! - + $areas['page_contents'] = get_string('pagecontents', 'mod_lesson'); + $areas['mediafile'] = get_string('mediafile', 'mod_lesson'); return $areas; } From 545b310c8482e92bee21e6c94b572d473860659b Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Mon, 16 Dec 2013 07:03:12 +0100 Subject: [PATCH 3/3] MDL-42212 mod_lesson: Use autoloading for mod_lesson_file_info --- mod/lesson/classes/file_info.php | 194 +++++++++++++++++++++++++++++++ mod/lesson/lib.php | 1 - mod/lesson/locallib.php | 169 --------------------------- 3 files changed, 194 insertions(+), 170 deletions(-) create mode 100644 mod/lesson/classes/file_info.php diff --git a/mod/lesson/classes/file_info.php b/mod/lesson/classes/file_info.php new file mode 100644 index 00000000000..eb5d1390015 --- /dev/null +++ b/mod/lesson/classes/file_info.php @@ -0,0 +1,194 @@ +. + +/** + * File browsing support. + * + * @package mod_lesson + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +/** + * File browsing support class. + * + * @package mod_lesson + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class mod_lesson_file_info extends file_info { + + /** @var stdClass Course object */ + protected $course; + /** @var stdClass Course module object */ + protected $cm; + /** @var array Available file areas */ + protected $areas; + /** @var string File area to browse */ + protected $filearea; + + /** + * Constructor + * + * @param file_browser $browser file_browser instance + * @param stdClass $course course object + * @param stdClass $cm course module object + * @param stdClass $context module context + * @param array $areas available file areas + * @param string $filearea file area to browse + */ + public function __construct($browser, $course, $cm, $context, $areas, $filearea) { + parent::__construct($browser, $context); + $this->course = $course; + $this->cm = $cm; + $this->areas = $areas; + $this->filearea = $filearea; + } + + /** + * Returns list of standard virtual file/directory identification. + * The difference from stored_file parameters is that null values + * are allowed in all fields + * @return array with keys contextid, filearea, itemid, filepath and filename + */ + public function get_params() { + return array('contextid' => $this->context->id, + 'component' => 'mod_lesson', + 'filearea' => $this->filearea, + 'itemid' => null, + 'filepath' => null, + 'filename' => null); + } + + /** + * Returns localised visible name. + * @return string + */ + public function get_visible_name() { + return $this->areas[$this->filearea]; + } + + /** + * Can I add new files or directories? + * @return bool + */ + public function is_writable() { + return false; + } + + /** + * Is directory? + * @return bool + */ + public function is_directory() { + return true; + } + + /** + * Returns list of children. + * @return array of file_info instances + */ + 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|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 + */ + private function get_filtered_children($extensions = '*', $countonly = false, $returnemptyfolders = false) { + global $DB; + + $params = array( + 'contextid' => $this->context->id, + 'component' => 'mod_lesson', + 'filearea' => $this->filearea + ); + $sql = 'SELECT DISTINCT itemid + FROM {files} + WHERE contextid = :contextid + AND component = :component + AND filearea = :filearea'; + + if (!$returnemptyfolders) { + $sql .= ' AND filename <> :emptyfilename'; + $params['emptyfilename'] = '.'; + } + + list($sql2, $params2) = $this->build_search_files_sql($extensions); + $sql .= ' ' . $sql2; + $params = array_merge($params, $params2); + + if ($countonly !== false) { + $sql .= ' ORDER BY itemid DESC'; + } + + $rs = $DB->get_recordset_sql($sql, $params); + $children = array(); + foreach ($rs as $record) { + if (($child = $this->browser->get_file_info($this->context, 'mod_lesson', $this->filearea, $record->itemid)) + && ($returnemptyfolders || $child->count_non_empty_children($extensions))) { + $children[] = $child; + } + if ($countonly !== false && count($children) >= $countonly) { + break; + } + } + $rs->close(); + if ($countonly !== false) { + return count($children); + } + return $children; + } + + /** + * 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') + * @return array of file_info instances + */ + public function get_non_empty_children($extensions = '*') { + return $this->get_filtered_children($extensions, false); + } + + /** + * Returns the number of children which are either files matching the specified extensions + * or folders containing at least one such file. + * + * @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 = '*', $limit = 1) { + return $this->get_filtered_children($extensions, $limit); + } + + /** + * Returns parent file_info instance + * @return file_info or null for root + */ + public function get_parent() { + return $this->browser->get_file_info($this->context); + } +} diff --git a/mod/lesson/lib.php b/mod/lesson/lib.php index a614f6c51c6..797248149b4 100644 --- a/mod/lesson/lib.php +++ b/mod/lesson/lib.php @@ -947,7 +947,6 @@ function lesson_get_file_info($browser, $areas, $course, $cm, $context, $fileare } if (is_null($itemid)) { - require_once(__DIR__ . '/locallib.php'); return new mod_lesson_file_info($browser, $course, $cm, $context, $areas, $filearea); } diff --git a/mod/lesson/locallib.php b/mod/lesson/locallib.php index 8e71ac689eb..7011be6e293 100644 --- a/mod/lesson/locallib.php +++ b/mod/lesson/locallib.php @@ -2819,172 +2819,3 @@ class lesson_page_type_manager { return $links; } } - -/** - * File browsing support class. - * - * @package mod_lesson - * @copyright 2013 Frédéric Massart - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class mod_lesson_file_info extends file_info { - - /** @var stdClass Course object */ - protected $course; - /** @var stdClass Course module object */ - protected $cm; - /** @var array Available file areas */ - protected $areas; - /** @var string File area to browse */ - protected $filearea; - - /** - * Constructor - * - * @param file_browser $browser file_browser instance - * @param stdClass $course course object - * @param stdClass $cm course module object - * @param stdClass $context module context - * @param array $areas available file areas - * @param string $filearea file area to browse - */ - public function __construct($browser, $course, $cm, $context, $areas, $filearea) { - parent::__construct($browser, $context); - $this->course = $course; - $this->cm = $cm; - $this->areas = $areas; - $this->filearea = $filearea; - } - - /** - * Returns list of standard virtual file/directory identification. - * The difference from stored_file parameters is that null values - * are allowed in all fields - * @return array with keys contextid, filearea, itemid, filepath and filename - */ - public function get_params() { - return array('contextid' => $this->context->id, - 'component' => 'mod_lesson', - 'filearea' => $this->filearea, - 'itemid' => null, - 'filepath' => null, - 'filename' => null); - } - - /** - * Returns localised visible name. - * @return string - */ - public function get_visible_name() { - return $this->areas[$this->filearea]; - } - - /** - * Can I add new files or directories? - * @return bool - */ - public function is_writable() { - return false; - } - - /** - * Is directory? - * @return bool - */ - public function is_directory() { - return true; - } - - /** - * Returns list of children. - * @return array of file_info instances - */ - 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|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 - */ - private function get_filtered_children($extensions = '*', $countonly = false, $returnemptyfolders = false) { - global $DB; - - $params = array( - 'contextid' => $this->context->id, - 'component' => 'mod_lesson', - 'filearea' => $this->filearea - ); - $sql = 'SELECT DISTINCT itemid - FROM {files} - WHERE contextid = :contextid - AND component = :component - AND filearea = :filearea'; - - if (!$returnemptyfolders) { - $sql .= ' AND filename <> :emptyfilename'; - $params['emptyfilename'] = '.'; - } - - list($sql2, $params2) = $this->build_search_files_sql($extensions); - $sql .= ' ' . $sql2; - $params = array_merge($params, $params2); - - if ($countonly !== false) { - $sql .= ' ORDER BY itemid DESC'; - } - - $rs = $DB->get_recordset_sql($sql, $params); - $children = array(); - foreach ($rs as $record) { - if (($child = $this->browser->get_file_info($this->context, 'mod_lesson', $this->filearea, $record->itemid)) - && ($returnemptyfolders || $child->count_non_empty_children($extensions))) { - $children[] = $child; - } - if ($countonly !== false && count($children) >= $countonly) { - break; - } - } - $rs->close(); - if ($countonly !== false) { - return count($children); - } - return $children; - } - - /** - * 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') - * @return array of file_info instances - */ - public function get_non_empty_children($extensions = '*') { - return $this->get_filtered_children($extensions, false); - } - - /** - * Returns the number of children which are either files matching the specified extensions - * or folders containing at least one such file. - * - * @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 = '*', $limit = 1) { - return $this->get_filtered_children($extensions, $limit); - } - - /** - * Returns parent file_info instance - * @return file_info or null for root - */ - public function get_parent() { - return $this->browser->get_file_info($this->context); - } -}