c431950b6622ae433058fc4f72916c0fa4facba5
[moodle.git] / repository / recent / lib.php
1 <?php
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/>.
18 /**
19  * repository_recent class is used to browse recent used files
20  *
21  * @since 2.0
22  * @package moodlecore
23  * @subpackage repository
24  * @copyright 2010 Dongsheng Cai
25  * @author Dongsheng Cai <dongsheng@moodle.com>
26  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27  */
29 define('DEFAULT_RECENT_FILES_NUM', 50);
30 class repository_recent extends repository {
32     /**
33      * Initialize recent plugin
34      * @param int $repositoryid
35      * @param int $context
36      * @param array $options
37      */
38     public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
39         parent::__construct($repositoryid, $context, $options);
40         $number = get_config('recent', 'recentfilesnumber');
41         $number = (int)$number;
42         if (empty($number)) {
43             $this->number = DEFAULT_RECENT_FILES_NUM;
44         } else {
45             $this->number = $number;
46         }
47     }
49     /**
50      * recent plugin doesn't require login, so list all files
51      * @return mixed
52      */
53     public function print_login() {
54         return $this->get_listing();
55     }
57     /**
58      * Not supported by File API yet
59      * @param string $search_text
60      * @return mixed
61      */
62     public function search($search_text) {
63         return array();
64     }
66     private function get_recent_files($limitfrom = 0, $limit = DEFAULT_RECENT_FILES_NUM) {
67         global $USER, $DB;
68         // TODO: should exclude user_draft area files?
69         $sql = 'SELECT * FROM {files} files1
70                 JOIN (SELECT contenthash, filename, MAX(id) AS id
71                 FROM {files}
72                 WHERE userid = ? AND filename != ? AND filearea != ?
73                 GROUP BY contenthash, filename) files2 ON files1.id = files2.id
74                 ORDER BY files1.timemodified DESC';
75         $params = array('userid'=>$USER->id, 'filename'=>'.', 'filearea'=>'user_draft');
76         $rs = $DB->get_recordset_sql($sql, $params, $limitfrom, $limit);
77         $result = array();
78         foreach ($rs as $file_record) {
79             $info = array();
80             $info['contextid'] = $file_record->contextid;
81             $info['itemid'] = $file_record->itemid;
82             $info['filearea'] = $file_record->filearea;
83             $info['filepath'] = $file_record->filepath;
84             $info['filename'] = $file_record->filename;
85             $result[$file_record->pathnamehash] = $info;
86         }
87         $rs->close();
88         return $result;
89     }
91     /**
92      * Get file listing
93      *
94      * @param string $encodedpath
95      * @param string $path not used by this plugin
96      * @return mixed
97      */
98     public function get_listing($encodedpath = '', $page = '') {
99         global $CFG, $USER, $OUTPUT;
100         $ret = array();
101         $ret['dynload'] = true;
102         $ret['nosearch'] = true;
103         $ret['nologin'] = true;
104         $list = array();
105         $files = $this->get_recent_files(0, $this->number);
107         try {
108             foreach ($files as $file) {
109                 $params = base64_encode(serialize($file));
110                 $icon = 'f/'.str_replace('.gif', '', mimeinfo('icon', $file['filename'])) . '-32';
111                 $node = array(
112                     'title' => $file['filename'],
113                     'shorttitle' => $this->get_short_filename($file['filename'], 12),
114                     'size' => 0,
115                     'date' => '',
116                     'source'=> $params,
117                     'thumbnail' => $OUTPUT->pix_url($icon) . '',
118                 );
119                 $list[] = $node;
120             }
121         } catch (Exception $e) {
122             throw new repository_exception('emptyfilelist', 'repository_recent');
123         }
124         $ret['list'] = array_filter($list, array($this, 'filter'));
125         return $ret;
126     }
129     /**
130      * Set repository name
131      *
132      * @return string repository name
133      */
134     public function get_name(){
135         return get_string('pluginname', 'repository_recent');;
136     }
138     public static function get_type_option_names() {
139         return array('recentfilesnumber');
140     }
142     public function type_config_form($mform) {
143         $number = get_config('repository_recent', 'recentfilesnumber');
144         if (empty($number)) {
145             $number = DEFAULT_RECENT_FILES_NUM;
146         }
147         $mform->addElement('text', 'recentfilesnumber', get_string('recentfilesnumber', 'repository_recent'));
148         $mform->setDefault('recentfilesnumber', $number);
149     }
151     /**
152      * This plugin doesn't support to link to external links
153      *
154      * @return int
155      */
156     public function supported_returntypes() {
157         return FILE_INTERNAL;
158     }
159     /**
160      * Copy a file to file area
161      *
162      * @global object $USER
163      * @global object $DB
164      * @param string $encoded The information of file, it is base64 encoded php seriablized data
165      * @param string $new_filename The intended name of file
166      * @param string $new_itemid itemid
167      * @param string $new_filepath the new path in draft area
168      * @return array The information of file
169      */
170     public function copy_to_area($encoded, $new_filearea='user_draft', $new_itemid = '', $new_filepath = '/', $new_filename = '') {
171         global $USER, $DB;
172         $info = array();
173         $fs = get_file_storage();
175         $params = unserialize(base64_decode($encoded));
176         $user_context = get_context_instance(CONTEXT_USER, $USER->id);
178         $contextid  = $params['contextid'];
179         $filearea   = $params['filearea'];
180         $filepath   = $params['filepath'];
181         $filename   = $params['filename'];
182         $fileitemid = $params['itemid'];
184         // XXX:
185         // When user try to pick a file from other filearea, normally file api will use file browse to
186         // operate the files with capability check, but in some areas, users don't have permission to
187         // browse the files (for example, forum_attachment area).
188         //
189         // To get 'recent' plugin working, we need to use lower level file_stoarge class to bypass the
190         // capability check, we will use a better workaround to improve it.
191         if ($stored_file = $fs->get_file($contextid, $filearea, $fileitemid, $filepath, $filename)) {
192             $file_record = array('contextid'=>$user_context->id, 'filearea'=>$new_filearea,
193                 'itemid'=>$new_itemid, 'filepath'=>$new_filepath, 'filename'=>$new_filename);
194             if ($file = $fs->get_file($user_context->id, $new_filearea, $new_itemid, $new_filepath, $new_filename)) {
195                 $file->delete();
196             }
197             $fs->create_file_from_storedfile($file_record, $stored_file);
198         }
200         $info['title']  = $new_filename;
201         $info['itemid'] = $new_itemid;
202         $info['filesize']  = $stored_file->get_filesize();
203         $info['contextid'] = $user_context->id;
205         return $info;
206     }