PageRenderTime 57ms CodeModel.GetById 6ms RepoModel.GetById 9ms app.codeStats 0ms

/repository/s3/lib.php

https://bitbucket.org/synergylearning/campusconnect
PHP | 263 lines | 147 code | 25 blank | 91 comment | 17 complexity | 49fe5d17eee0acbee77f1b74d65876ed MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-3.0, GPL-3.0, LGPL-2.1, Apache-2.0, BSD-3-Clause, AGPL-3.0
  1. <?php
  2. // This file is part of Moodle - http://moodle.org/
  3. //
  4. // Moodle is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // Moodle is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  16. /**
  17. * This plugin is used to access s3 files
  18. *
  19. * @since 2.0
  20. * @package repository_s3
  21. * @copyright 2010 Dongsheng Cai {@link http://dongsheng.org}
  22. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23. */
  24. require_once($CFG->dirroot . '/repository/lib.php');
  25. require_once($CFG->dirroot . '/repository/s3/S3.php');
  26. /**
  27. * This is a repository class used to browse Amazon S3 content.
  28. *
  29. * @since 2.0
  30. * @package repository_s3
  31. * @copyright 2009 Dongsheng Cai {@link http://dongsheng.org}
  32. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  33. */
  34. class repository_s3 extends repository {
  35. /**
  36. * Constructor
  37. * @param int $repositoryid
  38. * @param object $context
  39. * @param array $options
  40. */
  41. public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
  42. parent::__construct($repositoryid, $context, $options);
  43. $this->access_key = get_config('s3', 'access_key');
  44. $this->secret_key = get_config('s3', 'secret_key');
  45. $this->s = new S3($this->access_key, $this->secret_key);
  46. $this->s->setExceptions(true);
  47. }
  48. /**
  49. * Extracts the Bucket and URI from the path
  50. *
  51. * @param string $path path in this format 'bucket/path/to/folder/and/file'
  52. * @return array including bucket and uri
  53. */
  54. protected function explode_path($path) {
  55. $parts = explode('/', $path, 2);
  56. if (isset($parts[1]) && $parts[1] !== '') {
  57. list($bucket, $uri) = $parts;
  58. } else {
  59. $bucket = $parts[0];
  60. $uri = '';
  61. }
  62. return array($bucket, $uri);
  63. }
  64. /**
  65. * Get S3 file list
  66. *
  67. * @param string $path
  68. * @return array The file list and options
  69. */
  70. public function get_listing($path = '', $page = '') {
  71. global $CFG, $OUTPUT;
  72. if (empty($this->access_key)) {
  73. throw new moodle_exception('needaccesskey', 'repository_s3');
  74. }
  75. $list = array();
  76. $list['list'] = array();
  77. $list['path'] = array(
  78. array('name' => get_string('pluginname', 'repository_s3'), 'path' => '')
  79. );
  80. // the management interface url
  81. $list['manage'] = false;
  82. // dynamically loading
  83. $list['dynload'] = true;
  84. // the current path of this list.
  85. // set to true, the login link will be removed
  86. $list['nologin'] = true;
  87. // set to true, the search button will be removed
  88. $list['nosearch'] = true;
  89. $tree = array();
  90. if (empty($path)) {
  91. try {
  92. $buckets = $this->s->listBuckets();
  93. } catch (S3Exception $e) {
  94. throw new moodle_exception('errorwhilecommunicatingwith', 'repository', '', $this->get_name());
  95. }
  96. foreach ($buckets as $bucket) {
  97. $folder = array(
  98. 'title' => $bucket,
  99. 'children' => array(),
  100. 'thumbnail' => $OUTPUT->pix_url(file_folder_icon(90))->out(false),
  101. 'path' => $bucket
  102. );
  103. $tree[] = $folder;
  104. }
  105. } else {
  106. $files = array();
  107. $folders = array();
  108. list($bucket, $uri) = $this->explode_path($path);
  109. try {
  110. $contents = $this->s->getBucket($bucket, $uri, null, null, '/', true);
  111. } catch (S3Exception $e) {
  112. throw new moodle_exception('errorwhilecommunicatingwith', 'repository', '', $this->get_name());
  113. }
  114. foreach ($contents as $object) {
  115. // If object has a prefix, it is a 'CommonPrefix', which we consider a folder
  116. if (isset($object['prefix'])) {
  117. $title = rtrim($object['prefix'], '/');
  118. } else {
  119. $title = $object['name'];
  120. }
  121. // Removes the prefix (folder path) from the title
  122. if (strlen($uri) > 0) {
  123. $title = substr($title, strlen($uri));
  124. // Check if title is empty and not zero
  125. if (empty($title) && !is_numeric($title)) {
  126. // Amazon returns the prefix itself, we skip it
  127. continue;
  128. }
  129. }
  130. // This is a so-called CommonPrefix, we consider it as a folder
  131. if (isset($object['prefix'])) {
  132. $folders[] = array(
  133. 'title' => $title,
  134. 'children' => array(),
  135. 'thumbnail'=> $OUTPUT->pix_url(file_folder_icon(90))->out(false),
  136. 'path' => $bucket . '/' . $object['prefix']
  137. );
  138. } else {
  139. $files[] = array(
  140. 'title' => $title,
  141. 'size' => $object['size'],
  142. 'datemodified' => $object['time'],
  143. 'source' => $bucket . '/' . $object['name'],
  144. 'thumbnail' => $OUTPUT->pix_url(file_extension_icon($title, 90))->out(false)
  145. );
  146. }
  147. }
  148. $tree = array_merge($folders, $files);
  149. }
  150. $trail = '';
  151. if (!empty($path)) {
  152. $parts = explode('/', $path);
  153. if (count($parts) > 1) {
  154. foreach ($parts as $part) {
  155. if (!empty($part)) {
  156. $trail .= $part . '/';
  157. $list['path'][] = array('name' => $part, 'path' => $trail);
  158. }
  159. }
  160. } else {
  161. $list['path'][] = array('name' => $path, 'path' => $path);
  162. }
  163. }
  164. $list['list'] = $tree;
  165. return $list;
  166. }
  167. /**
  168. * Download S3 files to moodle
  169. *
  170. * @param string $filepath
  171. * @param string $file The file path in moodle
  172. * @return array The local stored path
  173. */
  174. public function get_file($filepath, $file = '') {
  175. list($bucket, $uri) = $this->explode_path($filepath);
  176. $path = $this->prepare_file($file);
  177. try {
  178. $this->s->getObject($bucket, $uri, $path);
  179. } catch (S3Exception $e) {
  180. throw new moodle_exception('errorwhilecommunicatingwith', 'repository', '', $this->get_name());
  181. }
  182. return array('path' => $path);
  183. }
  184. /**
  185. * Return the source information
  186. *
  187. * @param stdClass $filepath
  188. * @return string
  189. */
  190. public function get_file_source_info($filepath) {
  191. return 'Amazon S3: ' . $filepath;
  192. }
  193. /**
  194. * S3 doesn't require login
  195. *
  196. * @return bool
  197. */
  198. public function check_login() {
  199. return true;
  200. }
  201. /**
  202. * S3 doesn't provide search
  203. *
  204. * @return bool
  205. */
  206. public function global_search() {
  207. return false;
  208. }
  209. public static function get_type_option_names() {
  210. return array('access_key', 'secret_key', 'pluginname');
  211. }
  212. public static function type_config_form($mform, $classname = 'repository') {
  213. parent::type_config_form($mform);
  214. $strrequired = get_string('required');
  215. $mform->addElement('text', 'access_key', get_string('access_key', 'repository_s3'));
  216. $mform->setType('access_key', PARAM_RAW_TRIMMED);
  217. $mform->addElement('text', 'secret_key', get_string('secret_key', 'repository_s3'));
  218. $mform->setType('secret_key', PARAM_RAW_TRIMMED);
  219. $mform->addRule('access_key', $strrequired, 'required', null, 'client');
  220. $mform->addRule('secret_key', $strrequired, 'required', null, 'client');
  221. }
  222. /**
  223. * S3 plugins doesn't support return links of files
  224. *
  225. * @return int
  226. */
  227. public function supported_returntypes() {
  228. return FILE_INTERNAL;
  229. }
  230. /**
  231. * Is this repository accessing private data?
  232. *
  233. * @return bool
  234. */
  235. public function contains_private_data() {
  236. return false;
  237. }
  238. }