3 // This file is part of Moodle - http://moodle.org/
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
19 * repository_recent class is used to browse recent used files
23 * @subpackage repository
24 * @copyright 2010 Dongsheng Cai <dongsheng@moodle.com>
25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
28 define('DEFAULT_RECENT_FILES_NUM', 50);
29 class repository_recent extends repository {
32 * Initialize recent plugin
33 * @param int $repositoryid
35 * @param array $options
37 public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
38 parent::__construct($repositoryid, $context, $options);
39 $number = get_config('recent', 'recentfilesnumber');
40 $number = (int)$number;
42 $this->number = DEFAULT_RECENT_FILES_NUM;
44 $this->number = $number;
49 * recent plugin doesn't require login, so list all files
52 public function print_login() {
53 return $this->get_listing();
56 private function get_recent_files($limitfrom = 0, $limit = DEFAULT_RECENT_FILES_NUM) {
58 // TODO: should exclude user_draft area files?
59 $sql = 'SELECT * FROM {files} files1
60 JOIN (SELECT contenthash, filename, MAX(id) AS id
62 WHERE userid = ? AND filename != ? AND filearea != ?
63 GROUP BY contenthash, filename) files2 ON files1.id = files2.id
64 ORDER BY files1.timemodified DESC';
65 $params = array('userid'=>$USER->id, 'filename'=>'.', 'filearea'=>'user_draft');
66 $rs = $DB->get_recordset_sql($sql, $params, $limitfrom, $limit);
68 foreach ($rs as $file_record) {
70 $info['contextid'] = $file_record->contextid;
71 $info['itemid'] = $file_record->itemid;
72 $info['filearea'] = $file_record->filearea;
73 $info['component'] = $file_record->component;
74 $info['filepath'] = $file_record->filepath;
75 $info['filename'] = $file_record->filename;
76 $result[$file_record->pathnamehash] = $info;
85 * @param string $encodedpath
86 * @param string $path not used by this plugin
89 public function get_listing($encodedpath = '', $page = '') {
90 global $CFG, $USER, $OUTPUT;
92 $ret['dynload'] = true;
93 $ret['nosearch'] = true;
94 $ret['nologin'] = true;
96 $files = $this->get_recent_files(0, $this->number);
99 foreach ($files as $file) {
100 $params = base64_encode(serialize($file));
101 $icon = 'f/'.str_replace('.gif', '', mimeinfo('icon', $file['filename'])) . '-32';
103 'title' => $file['filename'],
104 'shorttitle' => $this->get_short_filename($file['filename'], 12),
108 'thumbnail' => $OUTPUT->pix_url($icon) . '',
112 } catch (Exception $e) {
113 throw new repository_exception('emptyfilelist', 'repository_recent');
115 $ret['list'] = array_filter($list, array($this, 'filter'));
121 * Set repository name
123 * @return string repository name
125 public function get_name(){
126 return get_string('pluginname', 'repository_recent');;
129 public static function get_type_option_names() {
130 return array('recentfilesnumber');
133 public function type_config_form($mform) {
134 $number = get_config('repository_recent', 'recentfilesnumber');
135 if (empty($number)) {
136 $number = DEFAULT_RECENT_FILES_NUM;
138 $mform->addElement('text', 'recentfilesnumber', get_string('recentfilesnumber', 'repository_recent'));
139 $mform->setDefault('recentfilesnumber', $number);
143 * This plugin doesn't support to link to external links
147 public function supported_returntypes() {
148 return FILE_INTERNAL;
151 * Copy a file to file area
153 * @global object $USER
155 * @param string $encoded The information of file, it is base64 encoded php seriablized data
156 * @param string $new_filename The intended name of file
157 * @param string $new_itemid itemid
158 * @param string $new_filepath the new path in draft area
159 * @return array The information of file
161 public function copy_to_area($encoded, $new_filearea='draft', $new_itemid = '', $new_filepath = '/', $new_filename = '') {
164 $user_context = get_context_instance(CONTEXT_USER, $USER->id);
166 $fs = get_file_storage();
168 $params = unserialize(base64_decode($encoded));
170 $contextid = clean_param($params['contextid'], PARAM_INT);
171 $fileitemid = clean_param($params['itemid'], PARAM_INT);
172 $filename = clean_param($params['filename'], PARAM_FILE);
173 $filepath = clean_param($params['filepath'], PARAM_PATH);;
174 $filearea = clean_param($params['filearea'], PARAM_ALPHAEXT);
175 $component = clean_param($params['component'], PARAM_ALPHAEXT);
178 // When user try to pick a file from other filearea, normally file api will use file browse to
179 // operate the files with capability check, but in some areas, users don't have permission to
180 // browse the files (for example, forum_attachment area).
182 // To get 'recent' plugin working, we need to use lower level file_stoarge class to bypass the
183 // capability check, we will use a better workaround to improve it.
184 if ($stored_file = $fs->get_file($contextid, $component, $filearea, $fileitemid, $filepath, $filename)) {
185 $file_record = array('contextid'=>$user_context->id, 'component'=>'user', 'filearea'=>'draft',
186 'itemid'=>$new_itemid, 'filepath'=>$new_filepath, 'filename'=>$new_filename);
187 if ($file = $fs->get_file($user_context->id, 'user', 'draft', $new_itemid, $new_filepath, $new_filename)) {
190 $fs->create_file_from_storedfile($file_record, $stored_file);
194 $info['title'] = $new_filename;
195 $info['itemid'] = $new_itemid;
196 $info['filesize'] = $stored_file->get_filesize();
197 $info['contextid'] = $user_context->id;