PageRenderTime 56ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/repository/recent/lib.php

https://github.com/tcubansk/moodle
PHP | 236 lines | 143 code | 19 blank | 74 comment | 9 complexity | 2c9d7fab7571babc0363d2bc0dab9b7e MD5 | raw file
  1. <?php
  2. // This file is part of Moodle - http://moodle.org/
  3. //
  4. // Moodle is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // Moodle is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  16. /**
  17. * repository_recent class is used to browse recent used files
  18. *
  19. * @since 2.0
  20. * @package repository
  21. * @subpackage recent
  22. * @copyright 2010 Dongsheng Cai <dongsheng@moodle.com>
  23. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24. */
  25. define('DEFAULT_RECENT_FILES_NUM', 50);
  26. class repository_recent extends repository {
  27. /**
  28. * Initialize recent plugin
  29. * @param int $repositoryid
  30. * @param int $context
  31. * @param array $options
  32. */
  33. public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
  34. parent::__construct($repositoryid, $context, $options);
  35. $number = get_config('recent', 'recentfilesnumber');
  36. $number = (int)$number;
  37. if (empty($number)) {
  38. $this->number = DEFAULT_RECENT_FILES_NUM;
  39. } else {
  40. $this->number = $number;
  41. }
  42. }
  43. /**
  44. * recent plugin doesn't require login, so list all files
  45. * @return mixed
  46. */
  47. public function print_login() {
  48. return $this->get_listing();
  49. }
  50. private function get_recent_files($limitfrom = 0, $limit = DEFAULT_RECENT_FILES_NUM) {
  51. // XXX: get current itemid
  52. global $USER, $DB, $itemid;
  53. $sql = 'SELECT files1.*
  54. FROM {files} files1
  55. JOIN (
  56. SELECT contenthash, filename, MAX(id) AS id
  57. FROM {files}
  58. WHERE userid = :userid
  59. AND filename != :filename
  60. AND ((filearea = :filearea1 AND itemid = :itemid) OR filearea != :filearea2)
  61. GROUP BY contenthash, filename
  62. ) files2 ON files1.id = files2.id
  63. ORDER BY files1.timemodified DESC';
  64. $params = array(
  65. 'userid' => $USER->id,
  66. 'filename' => '.',
  67. 'filearea1' => 'draft',
  68. 'itemid' => $itemid,
  69. 'filearea2' => 'draft');
  70. $rs = $DB->get_recordset_sql($sql, $params, $limitfrom, $limit);
  71. $result = array();
  72. foreach ($rs as $file_record) {
  73. $info = array();
  74. $info['contextid'] = $file_record->contextid;
  75. $info['itemid'] = $file_record->itemid;
  76. $info['filearea'] = $file_record->filearea;
  77. $info['component'] = $file_record->component;
  78. $info['filepath'] = $file_record->filepath;
  79. $info['filename'] = $file_record->filename;
  80. $result[$file_record->pathnamehash] = $info;
  81. }
  82. $rs->close();
  83. return $result;
  84. }
  85. /**
  86. * Get file listing
  87. *
  88. * @param string $encodedpath
  89. * @param string $path not used by this plugin
  90. * @return mixed
  91. */
  92. public function get_listing($encodedpath = '', $page = '') {
  93. global $OUTPUT;
  94. $ret = array();
  95. $ret['dynload'] = true;
  96. $ret['nosearch'] = true;
  97. $ret['nologin'] = true;
  98. $list = array();
  99. $files = $this->get_recent_files(0, $this->number);
  100. try {
  101. foreach ($files as $file) {
  102. $params = base64_encode(serialize($file));
  103. // Check that file exists and accessible
  104. $filesize = $this->get_file_size($params);
  105. if (!empty($filesize)) {
  106. $node = array(
  107. 'title' => $file['filename'],
  108. 'size' => $filesize,
  109. 'date' => '',
  110. 'source'=> $params,
  111. 'thumbnail' => $OUTPUT->pix_url(file_extension_icon($file['filename'], 32))->out(false),
  112. );
  113. $list[] = $node;
  114. }
  115. }
  116. } catch (Exception $e) {
  117. throw new repository_exception('emptyfilelist', 'repository_recent');
  118. }
  119. $ret['list'] = array_filter($list, array($this, 'filter'));
  120. return $ret;
  121. }
  122. public static function get_type_option_names() {
  123. return array('recentfilesnumber', 'pluginname');
  124. }
  125. public static function type_config_form($mform, $classname = 'repository') {
  126. parent::type_config_form($mform, $classname);
  127. $number = get_config('repository_recent', 'recentfilesnumber');
  128. if (empty($number)) {
  129. $number = DEFAULT_RECENT_FILES_NUM;
  130. }
  131. $mform->addElement('text', 'recentfilesnumber', get_string('recentfilesnumber', 'repository_recent'));
  132. $mform->setDefault('recentfilesnumber', $number);
  133. }
  134. /**
  135. * This plugin doesn't support to link to external links
  136. *
  137. * @return int
  138. */
  139. public function supported_returntypes() {
  140. return FILE_INTERNAL;
  141. }
  142. /**
  143. * This function overwrite the default implement to copying file using file_storage
  144. *
  145. * @global object $USER
  146. * @global object $DB
  147. * @param string $encoded The information of file, it is base64 encoded php serialized data
  148. * @param string $draftitemid itemid
  149. * @param string $new_filename The intended name of file
  150. * @param string $new_filepath the new path in draft area
  151. * @return array The information of file
  152. */
  153. public function copy_to_area($encoded, $draftitemid, $new_filepath, $new_filename) {
  154. global $USER, $DB;
  155. $user_context = get_context_instance(CONTEXT_USER, $USER->id);
  156. $fs = get_file_storage();
  157. $params = unserialize(base64_decode($encoded));
  158. $contextid = clean_param($params['contextid'], PARAM_INT);
  159. $fileitemid = clean_param($params['itemid'], PARAM_INT);
  160. $filename = clean_param($params['filename'], PARAM_FILE);
  161. $filepath = clean_param($params['filepath'], PARAM_PATH);;
  162. $filearea = clean_param($params['filearea'], PARAM_AREA);
  163. $component = clean_param($params['component'], PARAM_COMPONENT);
  164. // XXX:
  165. // When user try to pick a file from other filearea, normally file api will use file browse to
  166. // operate the files with capability check, but in some areas, users don't have permission to
  167. // browse the files (for example, forum_attachment area).
  168. //
  169. // To get 'recent' plugin working, we need to use lower level file_stoarge class to bypass the
  170. // capability check, we will use a better workaround to improve it.
  171. if ($stored_file = $fs->get_file($contextid, $component, $filearea, $fileitemid, $filepath, $filename)) {
  172. // verify user id
  173. if ($USER->id != $stored_file->get_userid()) {
  174. throw new moodle_exception('errornotyourfile', 'repository');
  175. }
  176. $file_record = array('contextid'=>$user_context->id, 'component'=>'user', 'filearea'=>'draft',
  177. 'itemid'=>$draftitemid, 'filepath'=>$new_filepath, 'filename'=>$new_filename, 'sortorder'=>0);
  178. // test if file already exists
  179. if (repository::draftfile_exists($draftitemid, $new_filepath, $new_filename)) {
  180. // create new file
  181. $unused_filename = repository::get_unused_filename($draftitemid, $new_filepath, $new_filename);
  182. $file_record['filename'] = $unused_filename;
  183. // create a tmp file
  184. $fs->create_file_from_storedfile($file_record, $stored_file);
  185. $event = array();
  186. $event['event'] = 'fileexists';
  187. $event['newfile'] = new stdClass;
  188. $event['newfile']->filepath = $new_filepath;
  189. $event['newfile']->filename = $unused_filename;
  190. $event['newfile']->url = moodle_url::make_draftfile_url($draftitemid, $new_filepath, $unused_filename)->out();
  191. $event['existingfile'] = new stdClass;
  192. $event['existingfile']->filepath = $new_filepath;
  193. $event['existingfile']->filename = $new_filename;
  194. $event['existingfile']->url = moodle_url::make_draftfile_url($draftitemid, $new_filepath, $new_filename)->out();;
  195. return $event;
  196. } else {
  197. $fs->create_file_from_storedfile($file_record, $stored_file);
  198. $info = array();
  199. $info['title'] = $new_filename;
  200. $info['itemid'] = $draftitemid;
  201. $info['filesize'] = $stored_file->get_filesize();
  202. $info['url'] = moodle_url::make_draftfile_url($draftitemid, $new_filepath, $new_filename)->out();;
  203. $info['contextid'] = $user_context->id;
  204. return $info;
  205. }
  206. }
  207. return false;
  208. }
  209. /**
  210. * Does this repository used to browse moodle files?
  211. *
  212. * @return boolean
  213. */
  214. public function has_moodle_files() {
  215. return true;
  216. }
  217. }