MDL-38852 repository_s3: fix missing setType calls
[moodle.git] / repository / s3 / 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  * This plugin is used to access s3 files
20  *
21  * @since 2.0
22  * @package    repository_s3
23  * @copyright  2010 Dongsheng Cai {@link http://dongsheng.org}
24  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25  */
26 require_once($CFG->dirroot . '/repository/lib.php');
27 require_once($CFG->dirroot . '/repository/s3/S3.php');
29 /**
30  * This is a repository class used to browse Amazon S3 content.
31  *
32  * @since 2.0
33  * @package    repository_s3
34  * @copyright  2009 Dongsheng Cai {@link http://dongsheng.org}
35  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36  */
37 class repository_s3 extends repository {
39     /**
40      * Constructor
41      * @param int $repositoryid
42      * @param object $context
43      * @param array $options
44      */
45     public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
46         parent::__construct($repositoryid, $context, $options);
47         $this->access_key = get_config('s3', 'access_key');
48         $this->secret_key = get_config('s3', 'secret_key');
49         $this->s = new S3($this->access_key, $this->secret_key);
50         $this->s->setExceptions(true);
51     }
53     /**
54      * Extracts the Bucket and URI from the path
55      *
56      * @param string $path path in this format 'bucket/path/to/folder/and/file'
57      * @return array including bucket and uri
58      */
59     protected function explode_path($path) {
60         $parts = explode('/', $path, 2);
61         if (isset($parts[1]) && $parts[1] !== '') {
62             list($bucket, $uri) = $parts;
63         } else {
64             $bucket = $parts[0];
65             $uri = '';
66         }
67         return array($bucket, $uri);
68     }
70     /**
71      * Get S3 file list
72      *
73      * @param string $path
74      * @return array The file list and options
75      */
76     public function get_listing($path = '', $page = '') {
77         global $CFG, $OUTPUT;
78         if (empty($this->access_key)) {
79             throw new moodle_exception('needaccesskey', 'repository_s3');
80         }
82         $list = array();
83         $list['list'] = array();
84         $list['path'] = array(
85             array('name' => get_string('pluginname', 'repository_s3'), 'path' => '')
86         );
88         // the management interface url
89         $list['manage'] = false;
90         // dynamically loading
91         $list['dynload'] = true;
92         // the current path of this list.
93         // set to true, the login link will be removed
94         $list['nologin'] = true;
95         // set to true, the search button will be removed
96         $list['nosearch'] = true;
98         $tree = array();
100         if (empty($path)) {
101             try {
102                 $buckets = $this->s->listBuckets();
103             } catch (S3Exception $e) {
104                 throw new moodle_exception('errorwhilecommunicatingwith', 'repository', '', $this->get_name());
105             }
106             foreach ($buckets as $bucket) {
107                 $folder = array(
108                     'title' => $bucket,
109                     'children' => array(),
110                     'thumbnail' => $OUTPUT->pix_url(file_folder_icon(90))->out(false),
111                     'path' => $bucket
112                     );
113                 $tree[] = $folder;
114             }
115         } else {
116             $files = array();
117             $folders = array();
118             list($bucket, $uri) = $this->explode_path($path);
120             try {
121                 $contents = $this->s->getBucket($bucket, $uri, null, null, '/', true);
122             } catch (S3Exception $e) {
123                 throw new moodle_exception('errorwhilecommunicatingwith', 'repository', '', $this->get_name());
124             }
125             foreach ($contents as $object) {
127                 // If object has a prefix, it is a 'CommonPrefix', which we consider a folder
128                 if (isset($object['prefix'])) {
129                     $title = rtrim($object['prefix'], '/');
130                 } else {
131                     $title = $object['name'];
132                 }
134                 // Removes the prefix (folder path) from the title
135                 if (strlen($uri) > 0) {
136                     $title = substr($title, strlen($uri));
137                     // Check if title is empty and not zero
138                     if (empty($title) && !is_numeric($title)) {
139                         // Amazon returns the prefix itself, we skip it
140                         continue;
141                     }
142                 }
144                 // This is a so-called CommonPrefix, we consider it as a folder
145                 if (isset($object['prefix'])) {
146                     $folders[] = array(
147                         'title' => $title,
148                         'children' => array(),
149                         'thumbnail'=> $OUTPUT->pix_url(file_folder_icon(90))->out(false),
150                         'path' => $bucket . '/' . $object['prefix']
151                     );
152                 } else {
153                     $files[] = array(
154                         'title' => $title,
155                         'size' => $object['size'],
156                         'datemodified' => $object['time'],
157                         'source' => $bucket . '/' . $object['name'],
158                         'thumbnail' => $OUTPUT->pix_url(file_extension_icon($title, 90))->out(false)
159                     );
160                 }
161             }
162             $tree = array_merge($folders, $files);
163         }
165         $trail = '';
166         if (!empty($path)) {
167             $parts = explode('/', $path);
168             if (count($parts) > 1) {
169                 foreach ($parts as $part) {
170                     if (!empty($part)) {
171                         $trail .= $part . '/';
172                         $list['path'][] = array('name' => $part, 'path' => $trail);
173                     }
174                 }
175             } else {
176                 $list['path'][] = array('name' => $path, 'path' => $path);
177             }
178         }
180         $list['list'] = $tree;
182         return $list;
183     }
185     /**
186      * Download S3 files to moodle
187      *
188      * @param string $filepath
189      * @param string $file The file path in moodle
190      * @return array The local stored path
191      */
192     public function get_file($filepath, $file = '') {
193         list($bucket, $uri) = $this->explode_path($filepath);
194         $path = $this->prepare_file($file);
195         try {
196             $this->s->getObject($bucket, $uri, $path);
197         } catch (S3Exception $e) {
198             throw new moodle_exception('errorwhilecommunicatingwith', 'repository', '', $this->get_name());
199         }
200         return array('path' => $path);
201     }
203     /**
204      * Return the source information
205      *
206      * @param stdClass $filepath
207      * @return string
208      */
209     public function get_file_source_info($filepath) {
210         return 'Amazon S3: ' . $filepath;
211     }
213     /**
214      * S3 doesn't require login
215      *
216      * @return bool
217      */
218     public function check_login() {
219         return true;
220     }
222     /**
223      * S3 doesn't provide search
224      *
225      * @return bool
226      */
227     public function global_search() {
228         return false;
229     }
231     public static function get_type_option_names() {
232         return array('access_key', 'secret_key', 'pluginname');
233     }
235     public static function type_config_form($mform, $classname = 'repository') {
236         parent::type_config_form($mform);
237         $strrequired = get_string('required');
238         $mform->addElement('text', 'access_key', get_string('access_key', 'repository_s3'));
239         $mform->setType('access_key', PARAM_RAW_TRIMMED);
240         $mform->addElement('text', 'secret_key', get_string('secret_key', 'repository_s3'));
241         $mform->setType('secret_key', PARAM_RAW_TRIMMED);
242         $mform->addRule('access_key', $strrequired, 'required', null, 'client');
243         $mform->addRule('secret_key', $strrequired, 'required', null, 'client');
244     }
246     /**
247      * S3 plugins doesn't support return links of files
248      *
249      * @return int
250      */
251     public function supported_returntypes() {
252         return FILE_INTERNAL;
253     }
255     /**
256      * Is this repository accessing private data?
257      *
258      * @return bool
259      */
260     public function contains_private_data() {
261         return false;
262     }