Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
 * This plugin is used to access s3 files
20
 *
21
 * @since Moodle 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');
28
 
29
/**
30
 * This is a repository class used to browse Amazon S3 content.
31
 *
32
 * @since Moodle 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 {
38
 
39
    /** @var string access key. */
40
    protected $access_key;
41
    /** @var string secret key. */
42
    protected $secret_key;
43
    /** @var string endpoint URL. */
44
    protected $endpoint;
45
    /** @var S3 S3 class. */
46
    protected $s;
47
 
48
    /**
49
     * Constructor
50
     * @param int $repositoryid
51
     * @param object $context
52
     * @param array $options
53
     */
54
    public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
55
        global $CFG;
56
        parent::__construct($repositoryid, $context, $options);
57
        $this->access_key = get_config('s3', 'access_key');
58
        $this->secret_key = get_config('s3', 'secret_key');
59
        $this->endpoint = get_config('s3', 'endpoint');
60
        if ($this->endpoint === false) { // If no endpoint has been set, use the default.
61
            $this->endpoint = 's3.amazonaws.com';
62
        }
63
        $this->s = new S3($this->access_key, $this->secret_key, false, $this->endpoint);
64
        $this->s->setExceptions(true);
65
 
66
        // Port of curl::__construct().
67
        if (!empty($CFG->proxyhost)) {
68
            if (empty($CFG->proxyport)) {
69
                $proxyhost = $CFG->proxyhost;
70
            } else {
71
                $proxyhost = $CFG->proxyhost . ':' . $CFG->proxyport;
72
            }
73
            $proxytype = CURLPROXY_HTTP;
74
            $proxyuser = null;
75
            $proxypass = null;
76
            if (!empty($CFG->proxyuser) and !empty($CFG->proxypassword)) {
77
                $proxyuser = $CFG->proxyuser;
78
                $proxypass = $CFG->proxypassword;
79
            }
80
            if (!empty($CFG->proxytype) && $CFG->proxytype == 'SOCKS5') {
81
                $proxytype = CURLPROXY_SOCKS5;
82
            }
83
            $this->s->setProxy($proxyhost, $proxyuser, $proxypass, $proxytype);
84
        }
85
    }
86
 
87
    /**
88
     * Extracts the Bucket and URI from the path
89
     *
90
     * @param string $path path in this format 'bucket/path/to/folder/and/file'
91
     * @return array including bucket and uri
92
     */
93
    protected function explode_path($path) {
94
        $parts = explode('/', $path, 2);
95
        if (isset($parts[1]) && $parts[1] !== '') {
96
            list($bucket, $uri) = $parts;
97
        } else {
98
            $bucket = $parts[0];
99
            $uri = '';
100
        }
101
        return array($bucket, $uri);
102
    }
103
 
104
    /**
105
     * Get S3 file list
106
     *
107
     * @param string $path
108
     * @return array The file list and options
109
     */
110
    public function get_listing($path = '', $page = '') {
111
        global $CFG, $OUTPUT;
112
        if (empty($this->access_key)) {
113
            throw new moodle_exception('needaccesskey', 'repository_s3');
114
        }
115
 
116
        $list = array();
117
        $list['list'] = array();
118
        $list['path'] = array(
119
            array('name' => get_string('pluginname', 'repository_s3'), 'path' => '')
120
        );
121
 
122
        // the management interface url
123
        $list['manage'] = false;
124
        // dynamically loading
125
        $list['dynload'] = true;
126
        // the current path of this list.
127
        // set to true, the login link will be removed
128
        $list['nologin'] = true;
129
        // set to true, the search button will be removed
130
        $list['nosearch'] = true;
131
 
132
        $tree = array();
133
 
134
        if (empty($path)) {
135
            try {
136
                $buckets = $this->s->listBuckets();
137
            } catch (S3Exception $e) {
138
                throw new moodle_exception(
139
                    'errorwhilecommunicatingwith',
140
                    'repository',
141
                    '',
142
                    $this->get_name(),
143
                    $e->getMessage()
144
                );
145
            }
146
            foreach ($buckets as $bucket) {
147
                $folder = array(
148
                    'title' => $bucket,
149
                    'children' => array(),
150
                    'thumbnail' => $OUTPUT->image_url(file_folder_icon())->out(false),
151
                    'path' => $bucket
152
                    );
153
                $tree[] = $folder;
154
            }
155
        } else {
156
            $files = array();
157
            $folders = array();
158
            list($bucket, $uri) = $this->explode_path($path);
159
 
160
            try {
161
                $contents = $this->s->getBucket($bucket, $uri, null, null, '/', true);
162
            } catch (S3Exception $e) {
163
                throw new moodle_exception(
164
                    'errorwhilecommunicatingwith',
165
                    'repository',
166
                    '',
167
                    $this->get_name(),
168
                    $e->getMessage()
169
                );
170
            }
171
            foreach ($contents as $object) {
172
 
173
                // If object has a prefix, it is a 'CommonPrefix', which we consider a folder
174
                if (isset($object['prefix'])) {
175
                    $title = rtrim($object['prefix'], '/');
176
                } else {
177
                    $title = $object['name'];
178
                }
179
 
180
                // Removes the prefix (folder path) from the title
181
                if (strlen($uri) > 0) {
182
                    $title = substr($title, strlen($uri));
183
                    // Check if title is empty and not zero
184
                    if (empty($title) && !is_numeric($title)) {
185
                        // Amazon returns the prefix itself, we skip it
186
                        continue;
187
                    }
188
                }
189
 
190
                // This is a so-called CommonPrefix, we consider it as a folder
191
                if (isset($object['prefix'])) {
192
                    $folders[] = array(
193
                        'title' => $title,
194
                        'children' => array(),
195
                        'thumbnail' => $OUTPUT->image_url(file_folder_icon())->out(false),
196
                        'path' => $bucket . '/' . $object['prefix'],
197
                    );
198
                } else {
199
                    $files[] = array(
200
                        'title' => $title,
201
                        'size' => $object['size'],
202
                        'datemodified' => $object['time'],
203
                        'source' => $bucket . '/' . $object['name'],
204
                        'thumbnail' => $OUTPUT->image_url(file_extension_icon($title))->out(false)
205
                    );
206
                }
207
            }
208
            $tree = array_merge($folders, $files);
209
        }
210
 
211
        $trail = '';
212
        if (!empty($path)) {
213
            $parts = explode('/', $path);
214
            if (count($parts) > 1) {
215
                foreach ($parts as $part) {
216
                    if (!empty($part)) {
217
                        $trail .= $part . '/';
218
                        $list['path'][] = array('name' => $part, 'path' => $trail);
219
                    }
220
                }
221
            } else {
222
                $list['path'][] = array('name' => $path, 'path' => $path);
223
            }
224
        }
225
 
226
        $list['list'] = $tree;
227
 
228
        return $list;
229
    }
230
 
231
    /**
232
     * Download S3 files to moodle
233
     *
234
     * @param string $filepath
235
     * @param string $file The file path in moodle
236
     * @return array The local stored path
237
     */
238
    public function get_file($filepath, $file = '') {
239
        list($bucket, $uri) = $this->explode_path($filepath);
240
        $path = $this->prepare_file($file);
241
        try {
242
            $this->s->getObject($bucket, $uri, $path);
243
        } catch (S3Exception $e) {
244
            throw new moodle_exception(
245
                'errorwhilecommunicatingwith',
246
                'repository',
247
                '',
248
                $this->get_name(),
249
                $e->getMessage()
250
            );
251
        }
252
        return array('path' => $path);
253
    }
254
 
255
    /**
256
     * Return the source information
257
     *
258
     * @param stdClass $filepath
259
     * @return string
260
     */
261
    public function get_file_source_info($filepath) {
262
        return 'Amazon S3: ' . $filepath;
263
    }
264
 
265
    /**
266
     * S3 doesn't require login
267
     *
268
     * @return bool
269
     */
270
    public function check_login() {
271
        return true;
272
    }
273
 
274
    /**
275
     * S3 doesn't provide search
276
     *
277
     * @return bool
278
     */
279
    public function global_search() {
280
        return false;
281
    }
282
 
283
    public static function get_type_option_names() {
284
        return array('access_key', 'secret_key', 'endpoint', 'pluginname');
285
    }
286
 
287
    public static function type_config_form($mform, $classname = 'repository') {
288
        parent::type_config_form($mform);
289
        $strrequired = get_string('required');
290
        $endpointselect = array( // List of possible Amazon S3 Endpoints.
291
            "s3.amazonaws.com" => "s3.amazonaws.com",
292
            "s3-external-1.amazonaws.com" => "s3-external-1.amazonaws.com",
293
            "s3-us-west-2.amazonaws.com" => "s3-us-west-2.amazonaws.com",
294
            "s3-us-west-1.amazonaws.com" => "s3-us-west-1.amazonaws.com",
295
            "s3-eu-west-1.amazonaws.com" => "s3-eu-west-1.amazonaws.com",
296
            "s3.eu-central-1.amazonaws.com" => "s3.eu-central-1.amazonaws.com",
297
            "s3-eu-central-1.amazonaws.com" => "s3-eu-central-1.amazonaws.com",
298
            "s3-ap-southeast-1.amazonaws.com" => "s3-ap-southeast-1.amazonaws.com",
299
            "s3-ap-southeast-2.amazonaws.com" => "s3-ap-southeast-2.amazonaws.com",
300
            "s3-ap-northeast-1.amazonaws.com" => "s3-ap-northeast-1.amazonaws.com",
301
            "s3-sa-east-1.amazonaws.com" => "s3-sa-east-1.amazonaws.com"
302
        );
303
        $mform->addElement('text', 'access_key', get_string('access_key', 'repository_s3'));
304
        $mform->setType('access_key', PARAM_RAW_TRIMMED);
305
        $mform->addElement('text', 'secret_key', get_string('secret_key', 'repository_s3'));
306
        $mform->setType('secret_key', PARAM_RAW_TRIMMED);
307
        $mform->addElement('select', 'endpoint', get_string('endpoint', 'repository_s3'), $endpointselect);
308
        $mform->setDefault('endpoint', 's3.amazonaws.com'); // Default to US Endpoint.
309
        $mform->addRule('access_key', $strrequired, 'required', null, 'client');
310
        $mform->addRule('secret_key', $strrequired, 'required', null, 'client');
311
    }
312
 
313
    /**
314
     * S3 plugins doesn't support return links of files
315
     *
316
     * @return int
317
     */
318
    public function supported_returntypes() {
319
        return FILE_INTERNAL;
320
    }
321
 
322
    /**
323
     * Is this repository accessing private data?
324
     *
325
     * @return bool
326
     */
327
    public function contains_private_data() {
328
        return false;
329
    }
330
}