"MDL-23823 allow users pick same file multi times in html editor"
[moodle.git] / repository / recent / lib.php
CommitLineData
6fbf3c48
DC
1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
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.
9//
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.
14//
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/>.
17
18/**
19 * repository_recent class is used to browse recent used files
20 *
21 * @since 2.0
22 * @package moodlecore
23 * @subpackage repository
955b6e09 24 * @copyright 2010 Dongsheng Cai <dongsheng@moodle.com>
6fbf3c48
DC
25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 */
27
28define('DEFAULT_RECENT_FILES_NUM', 50);
29class repository_recent extends repository {
30
31 /**
e35194be 32 * Initialize recent plugin
6fbf3c48
DC
33 * @param int $repositoryid
34 * @param int $context
35 * @param array $options
36 */
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;
41 if (empty($number)) {
42 $this->number = DEFAULT_RECENT_FILES_NUM;
43 } else {
44 $this->number = $number;
45 }
46 }
47
48 /**
49 * recent plugin doesn't require login, so list all files
50 * @return mixed
51 */
52 public function print_login() {
53 return $this->get_listing();
54 }
55
6fbf3c48 56 private function get_recent_files($limitfrom = 0, $limit = DEFAULT_RECENT_FILES_NUM) {
0f729672
DC
57 // XXX: get current itemid
58 global $USER, $DB, $itemid;
ad336228
DC
59 $sql = 'SELECT * FROM {files} files1
60 JOIN (SELECT contenthash, filename, MAX(id) AS id
c7e4621e 61 FROM {files}
0f729672 62 WHERE (userid = ? AND filename != ?) OR (filearea = ? AND itemid = ?)
ad336228
DC
63 GROUP BY contenthash, filename) files2 ON files1.id = files2.id
64 ORDER BY files1.timemodified DESC';
0f729672 65 $params = array('userid'=>$USER->id, 'filename'=>'.', 'filearea'=>'draft', 'itemid'=>$itemid);
22f944e3 66 $rs = $DB->get_recordset_sql($sql, $params, $limitfrom, $limit);
6fbf3c48
DC
67 $result = array();
68 foreach ($rs as $file_record) {
69 $info = array();
70 $info['contextid'] = $file_record->contextid;
71 $info['itemid'] = $file_record->itemid;
72 $info['filearea'] = $file_record->filearea;
16f61c70 73 $info['component'] = $file_record->component;
6fbf3c48
DC
74 $info['filepath'] = $file_record->filepath;
75 $info['filename'] = $file_record->filename;
76 $result[$file_record->pathnamehash] = $info;
77 }
78 $rs->close();
79 return $result;
80 }
81
82 /**
83 * Get file listing
84 *
85 * @param string $encodedpath
86 * @param string $path not used by this plugin
87 * @return mixed
88 */
89 public function get_listing($encodedpath = '', $page = '') {
90 global $CFG, $USER, $OUTPUT;
91 $ret = array();
92 $ret['dynload'] = true;
93 $ret['nosearch'] = true;
03896eb7 94 $ret['nologin'] = true;
6fbf3c48
DC
95 $list = array();
96 $files = $this->get_recent_files(0, $this->number);
97
98 try {
99 foreach ($files as $file) {
100 $params = base64_encode(serialize($file));
6fbf3c48
DC
101 $node = array(
102 'title' => $file['filename'],
f00340e2 103 'shorttitle' => $this->get_short_filename($file['filename'], 12),
6fbf3c48
DC
104 'size' => 0,
105 'date' => '',
106 'source'=> $params,
ede72522 107 'thumbnail' => $OUTPUT->pix_url(file_extension_icon($file['filename'], 32))->out(false),
6fbf3c48
DC
108 );
109 $list[] = $node;
110 }
111 } catch (Exception $e) {
112 throw new repository_exception('emptyfilelist', 'repository_recent');
113 }
87628a67 114 $ret['list'] = array_filter($list, array($this, 'filter'));
6fbf3c48
DC
115 return $ret;
116 }
117
6fbf3c48 118 public static function get_type_option_names() {
a5adfa26 119 return array('recentfilesnumber', 'pluginname');
6fbf3c48
DC
120 }
121
122 public function type_config_form($mform) {
a5adfa26 123 parent::type_config_form($mform);
6fbf3c48 124 $number = get_config('repository_recent', 'recentfilesnumber');
6fbf3c48
DC
125 if (empty($number)) {
126 $number = DEFAULT_RECENT_FILES_NUM;
127 }
128 $mform->addElement('text', 'recentfilesnumber', get_string('recentfilesnumber', 'repository_recent'));
1e791d83 129 $mform->setDefault('recentfilesnumber', $number);
6fbf3c48
DC
130 }
131
132 /**
133 * This plugin doesn't support to link to external links
134 *
135 * @return int
136 */
137 public function supported_returntypes() {
138 return FILE_INTERNAL;
139 }
acb70a9b 140 /**
c7e4621e 141 * Copy a file to file area
acb70a9b
DC
142 *
143 * @global object $USER
144 * @global object $DB
3b61c7e6
PS
145 * @param string $encoded The information of file, it is base64 encoded php serialized data
146 * @param string $draftitemid itemid
acb70a9b 147 * @param string $new_filename The intended name of file
acb70a9b
DC
148 * @param string $new_filepath the new path in draft area
149 * @return array The information of file
150 */
3b61c7e6 151 public function copy_to_area($encoded, $draftitemid, $new_filepath, $new_filename) {
acb70a9b 152 global $USER, $DB;
955b6e09
DC
153
154 $user_context = get_context_instance(CONTEXT_USER, $USER->id);
155
acb70a9b
DC
156 $fs = get_file_storage();
157
158 $params = unserialize(base64_decode($encoded));
acb70a9b 159
955b6e09
DC
160 $contextid = clean_param($params['contextid'], PARAM_INT);
161 $fileitemid = clean_param($params['itemid'], PARAM_INT);
162 $filename = clean_param($params['filename'], PARAM_FILE);
163 $filepath = clean_param($params['filepath'], PARAM_PATH);;
164 $filearea = clean_param($params['filearea'], PARAM_ALPHAEXT);
16f61c70 165 $component = clean_param($params['component'], PARAM_ALPHAEXT);
acb70a9b
DC
166
167 // XXX:
168 // When user try to pick a file from other filearea, normally file api will use file browse to
169 // operate the files with capability check, but in some areas, users don't have permission to
e35194be 170 // browse the files (for example, forum_attachment area).
acb70a9b
DC
171 //
172 // To get 'recent' plugin working, we need to use lower level file_stoarge class to bypass the
ad336228 173 // capability check, we will use a better workaround to improve it.
16f61c70 174 if ($stored_file = $fs->get_file($contextid, $component, $filearea, $fileitemid, $filepath, $filename)) {
aebe4af8
DC
175 if ($USER->id != $stored_file->get_userid()) {
176 throw new moodle_exception('errornotyourfile', 'repository');
177 }
16f61c70 178 $file_record = array('contextid'=>$user_context->id, 'component'=>'user', 'filearea'=>'draft',
3b61c7e6
PS
179 'itemid'=>$draftitemid, 'filepath'=>$new_filepath, 'filename'=>$new_filename);
180 if ($file = $fs->get_file($user_context->id, 'user', 'draft', $draftitemid, $new_filepath, $new_filename)) {
0f729672
DC
181 $info = array();
182 $info['title'] = $file->get_filename();
183 $info['itemid'] = $file->get_itemid();
184 $info['filesize'] = $file->get_filesize();
185 $info['contextid'] = $file->get_contextid();
186 return $info;
fb0acd86 187 }
acb70a9b
DC
188 $fs->create_file_from_storedfile($file_record, $stored_file);
189 }
190
955b6e09 191 $info = array();
acb70a9b 192 $info['title'] = $new_filename;
3b61c7e6 193 $info['itemid'] = $draftitemid;
acb70a9b
DC
194 $info['filesize'] = $stored_file->get_filesize();
195 $info['contextid'] = $user_context->id;
196
197 return $info;
198 }
6fbf3c48 199}