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