MDL-38852 repository_s3: fix missing setType calls
[moodle.git] / repository / s3 / lib.php
CommitLineData
4317f92f 1<?php
d2c98296
DC
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
d2c98296 18/**
67233725 19 * This plugin is used to access s3 files
d2c98296
DC
20 *
21 * @since 2.0
67233725
DC
22 * @package repository_s3
23 * @copyright 2010 Dongsheng Cai {@link http://dongsheng.org}
d078f6d3 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
d2c98296 25 */
67233725 26require_once($CFG->dirroot . '/repository/lib.php');
12ca7133 27require_once($CFG->dirroot . '/repository/s3/S3.php');
2e1cfc6e 28
67233725
DC
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 */
2e1cfc6e 37class repository_s3 extends repository {
d2c98296
DC
38
39 /**
40 * Constructor
41 * @param int $repositoryid
42 * @param object $context
43 * @param array $options
44 */
447c7a19 45 public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
2e1cfc6e 46 parent::__construct($repositoryid, $context, $options);
47 $this->access_key = get_config('s3', 'access_key');
48 $this->secret_key = get_config('s3', 'secret_key');
2e1cfc6e 49 $this->s = new S3($this->access_key, $this->secret_key);
1fefd1ff 50 $this->s->setExceptions(true);
2e1cfc6e 51 }
d2c98296 52
b061530d
FM
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 }
69
d2c98296
DC
70 /**
71 * Get S3 file list
72 *
73 * @param string $path
74 * @return array The file list and options
75 */
58eb9b9f 76 public function get_listing($path = '', $page = '') {
390baf46 77 global $CFG, $OUTPUT;
d2c98296 78 if (empty($this->access_key)) {
1fefd1ff 79 throw new moodle_exception('needaccesskey', 'repository_s3');
d2c98296 80 }
b061530d 81
2e1cfc6e 82 $list = array();
83 $list['list'] = array();
b061530d
FM
84 $list['path'] = array(
85 array('name' => get_string('pluginname', 'repository_s3'), 'path' => '')
86 );
87
2e1cfc6e 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;
b061530d 97
2e1cfc6e 98 $tree = array();
b061530d 99
2e1cfc6e 100 if (empty($path)) {
1fefd1ff
FM
101 try {
102 $buckets = $this->s->listBuckets();
103 } catch (S3Exception $e) {
104 throw new moodle_exception('errorwhilecommunicatingwith', 'repository', '', $this->get_name());
105 }
2e1cfc6e 106 foreach ($buckets as $bucket) {
107 $folder = array(
108 'title' => $bucket,
109 'children' => array(),
b061530d
FM
110 'thumbnail' => $OUTPUT->pix_url(file_folder_icon(90))->out(false),
111 'path' => $bucket
2e1cfc6e 112 );
113 $tree[] = $folder;
114 }
115 } else {
b061530d
FM
116 $files = array();
117 $folders = array();
118 list($bucket, $uri) = $this->explode_path($path);
119
1fefd1ff
FM
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 }
b061530d
FM
125 foreach ($contents as $object) {
126
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 }
133
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 }
143
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']
2e1cfc6e 151 );
b061530d
FM
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 }
164
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);
2e1cfc6e 177 }
178 }
179
180 $list['list'] = $tree;
181
182 return $list;
183 }
d2c98296
DC
184
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 */
68a7c9a6 192 public function get_file($filepath, $file = '') {
b061530d 193 list($bucket, $uri) = $this->explode_path($filepath);
a53d4f45 194 $path = $this->prepare_file($file);
1fefd1ff
FM
195 try {
196 $this->s->getObject($bucket, $uri, $path);
197 } catch (S3Exception $e) {
198 throw new moodle_exception('errorwhilecommunicatingwith', 'repository', '', $this->get_name());
199 }
b061530d 200 return array('path' => $path);
2e1cfc6e 201 }
d2c98296 202
d6453211
DC
203 /**
204 * Return the source information
205 *
206 * @param stdClass $filepath
207 * @return string
208 */
209 public function get_file_source_info($filepath) {
83d2700e 210 return 'Amazon S3: ' . $filepath;
d6453211
DC
211 }
212
d2c98296
DC
213 /**
214 * S3 doesn't require login
215 *
216 * @return bool
217 */
2e1cfc6e 218 public function check_login() {
219 return true;
220 }
2f67a9b3 221
d2c98296
DC
222 /**
223 * S3 doesn't provide search
224 *
225 * @return bool
2f67a9b3 226 */
2e1cfc6e 227 public function global_search() {
228 return false;
229 }
d2c98296 230
2e1cfc6e 231 public static function get_type_option_names() {
a5adfa26 232 return array('access_key', 'secret_key', 'pluginname');
2e1cfc6e 233 }
d2c98296 234
68a7c9a6 235 public static function type_config_form($mform, $classname = 'repository') {
a5adfa26 236 parent::type_config_form($mform);
2e1cfc6e 237 $strrequired = get_string('required');
238 $mform->addElement('text', 'access_key', get_string('access_key', 'repository_s3'));
8077527c 239 $mform->setType('access_key', PARAM_RAW_TRIMMED);
2e1cfc6e 240 $mform->addElement('text', 'secret_key', get_string('secret_key', 'repository_s3'));
8077527c 241 $mform->setType('secret_key', PARAM_RAW_TRIMMED);
2e1cfc6e 242 $mform->addRule('access_key', $strrequired, 'required', null, 'client');
243 $mform->addRule('secret_key', $strrequired, 'required', null, 'client');
2e1cfc6e 244 }
d2c98296
DC
245
246 /**
247 * S3 plugins doesn't support return links of files
248 *
249 * @return int
2f67a9b3 250 */
41076c58
DC
251 public function supported_returntypes() {
252 return FILE_INTERNAL;
253 }
31581ae6
FM
254
255 /**
256 * Is this repository accessing private data?
257 *
258 * @return bool
259 */
260 public function contains_private_data() {
261 return false;
262 }
2e1cfc6e 263}