REPOSITORY MDL-24205, added more check of path and files
[moodle.git] / repository / dropbox / lib.php
CommitLineData
3e123368
DC
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/**
e35194be
DC
19 * repository_dropbox class
20 * This plugin is used to access user's dropbox files
21 *
22 * TODO:
23 * Dropbox has problems to process filepath with spaces, tried to use
24 * urlencode filepath, still doesn't work
25 * http://code.google.com/p/dropbox-php/ has the same problem
3e123368
DC
26 *
27 * @since 2.0
d078f6d3
PS
28 * @package repository
29 * @subpackage dropbox
30 * @copyright 2010 Dongsheng Cai
31 * @author Dongsheng Cai <dongsheng@moodle.com>
32 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
3e123368
DC
33 */
34
e35194be
DC
35require_once(dirname(__FILE__).'/locallib.php');
36
37class repository_dropbox extends repository {
38 private $dropbox;
39 public $files;
40 public $logged=false;
41
42 /**
43 * Constructor of dropbox plugin
44 * @param int $repositoryid
45 * @param object $context
46 * @param array $options
47 */
48 public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
49 global $SESSION, $CFG;
50 $options['page'] = optional_param('p', 1, PARAM_INT);
51 parent::__construct($repositoryid, $context, $options);
52
53 $this->setting = 'dropbox_';
54
55 $this->dropbox_key = $this->get_option('dropbox_key');
56 $this->dropbox_secret = $this->get_option('dropbox_secret');
57
58 $this->access_key = get_user_preferences($this->setting.'_access_key', '');
59 $this->access_secret = get_user_preferences($this->setting.'_access_secret', '');
60
61 if (!empty($this->access_key) && !empty($this->access_secret)) {
62 $this->logged = true;
63 }
64
0b75ea78 65 $this->callback = new moodle_url($CFG->wwwroot.'/repository/repository_callback.php', array(
e35194be
DC
66 'callback'=>'yes',
67 'repo_id'=>$repositoryid
68 ));
69
70 $args = array(
71 'oauth_consumer_key'=>$this->dropbox_key,
72 'oauth_consumer_secret'=>$this->dropbox_secret,
73 'oauth_callback' => $this->callback->out(false),
74 'api_root' => 'http://api.dropbox.com/0/oauth',
75 );
76
77 $this->dropbox = new dropbox($args);
78 }
79
80 /**
81 * Check if moodle has got access token and secret
82 * @return bool
83 */
84 public function check_login() {
85 return !empty($this->logged);
86 }
87
88 /**
89 * Generate dropbox login url
90 * @return array
91 */
92 public function print_login() {
93 $result = $this->dropbox->request_token();
94 set_user_preference($this->setting.'_request_secret', $result['oauth_token_secret']);
95 $url = $result['authorize_url'];
96 if ($this->options['ajax']) {
97 $ret = array();
98 $popup_btn = new stdclass;
99 $popup_btn->type = 'popup';
100 $popup_btn->url = $url;
101 $ret['login'] = array($popup_btn);
102 return $ret;
103 } else {
104 echo '<a target="_blank" href="'.$this->flickr->auth().'">'.get_string('login', 'repository').'</a>';
105 }
106 }
107
108 /**
109 * Request access token
110 * @return array
111 */
112 public function callback() {
113 $token = optional_param('oauth_token', '', PARAM_TEXT);
114 $secret = get_user_preferences($this->setting.'_request_secret', '');
115 $access_token = $this->dropbox->get_access_token($token, $secret);
116 set_user_preference($this->setting.'_access_key', $access_token['oauth_token']);
117 set_user_preference($this->setting.'_access_secret', $access_token['oauth_token_secret']);
118 }
119
120 /**
121 * Get dropbox files
122 * @param string $path
123 * @param int $page
124 * @return array
125 */
126 public function get_listing($path = '', $page = '1') {
127 global $OUTPUT;
128 if (empty($path) || $path=='/') {
129 $path = '/';
130 } else {
131 $path = file_correct_filepath($path);
132 }
e35194be
DC
133
134 $list = array();
135 $list['list'] = array();
32368e99
DC
136 $list['manage'] = false;
137 $list['dynload'] = true;
138 $list['nosearch'] = true;
e35194be
DC
139 // process breacrumb trail
140 $list['path'] = array(
32368e99 141 array('name'=>get_string('sandbox', 'repository_dropbox'), 'path'=>'/')
e35194be 142 );
32368e99
DC
143
144 $result = $this->dropbox->get_listing($path, $this->access_key, $this->access_secret);
145 if (!is_object($result) || empty($result)) {
146 return $list;
147 }
148 if (empty($result->path)) {
149 $current_path = '/';
150 } else {
151 $current_path = file_correct_filepath($result->path);
152 }
153
e35194be
DC
154 $trail = '';
155 if (!empty($path)) {
156 $parts = explode('/', $path);
157 if (count($parts) > 1) {
158 foreach ($parts as $part) {
159 if (!empty($part)) {
160 $trail .= ('/'.$part);
161 $list['path'][] = array('name'=>$part, 'path'=>$trail);
162 }
163 }
164 } else {
165 $list['path'][] = array('name'=>$path, 'path'=>$path);
166 }
167 }
e35194be
DC
168
169 $files = $result->contents;
32368e99
DC
170 if (!is_array($files) || empty($files)) {
171 return $list;
172 }
e35194be
DC
173 foreach ($files as $file) {
174 if ($file->is_dir) {
175 $list['list'][] = array(
176 'title' => substr($file->path, strpos($file->path, $current_path)+strlen($current_path)),
177 'path' => file_correct_filepath($file->path),
178 'size' => $file->size,
179 'date' => $file->modified,
ede72522 180 'thumbnail' => $OUTPUT->pix_url('f/folder-32')->out(false),
e35194be
DC
181 'children' => array(),
182 );
183 } else {
184 $list['list'][] = array(
185 'title' => substr($file->path, strpos($file->path, $current_path)+strlen($current_path)),
186 'source' => $file->path,
187 'size' => $file->size,
188 'date' => $file->modified,
ede72522 189 'thumbnail' => $OUTPUT->pix_url(file_extension_icon($file->path, 32))->out(false)
e35194be
DC
190 );
191 }
192 }
193 return $list;
194 }
195 /**
196 * Logout from dropbox
197 * @return array
198 */
199 public function logout() {
200 set_user_preference($this->setting.'_access_key', '');
201 set_user_preference($this->setting.'_access_secret', '');
202 $this->access_key = '';
203 $this->access_secret = '';
204 return $this->print_login();
205 }
206
207 /**
208 * Set dropbox option
209 * @param array $options
210 * @return mixed
211 */
212 public function set_option($options = array()) {
213 if (!empty($options['dropbox_key'])) {
214 set_config('dropbox_key', trim($options['dropbox_key']), 'dropbox');
215 }
216 if (!empty($options['dropbox_secret'])) {
217 set_config('dropbox_secret', trim($options['dropbox_secret']), 'dropbox');
218 }
219 unset($options['dropbox_key']);
220 unset($options['dropbox_secret']);
221 $ret = parent::set_option($options);
222 return $ret;
223 }
224
225 /**
226 * Get dropbox options
227 * @param string $config
228 * @return mixed
229 */
230 public function get_option($config = '') {
231 if ($config==='dropbox_key') {
232 return trim(get_config('dropbox', 'dropbox_key'));
233 } elseif ($config==='dropbox_secret') {
234 return trim(get_config('dropbox', 'dropbox_secret'));
235 } else {
236 $options['dropbox_key'] = trim(get_config('dropbox', 'dropbox_key'));
237 $options['dropbox_secret'] = trim(get_config('dropbox', 'dropbox_secret'));
238 }
239 $options = parent::get_option($config);
240 return $options;
241 }
242
243 /**
244 *
245 * @param string $photo_id
246 * @param string $file
247 * @return string
248 */
249 public function get_file($filepath, $saveas = '') {
250 $this->dropbox->set_access_token($this->access_key, $this->access_secret);
251 return $this->dropbox->get_file($filepath, $saveas);
252 }
253 /**
254 * Add Plugin settings input to Moodle form
255 * @param object $mform
256 */
257 public function type_config_form($mform) {
258 global $CFG;
a5adfa26 259 parent::type_config_form($mform);
e35194be
DC
260 $key = get_config('dropbox', 'dropbox_key');
261 $secret = get_config('dropbox', 'dropbox_secret');
262
263 if (empty($key)) {
264 $key = '';
265 }
266 if (empty($secret)) {
267 $secret = '';
268 }
269
270 $strrequired = get_string('required');
271
272 $mform->addElement('text', 'dropbox_key', get_string('apikey', 'repository_dropbox'), array('value'=>$key,'size' => '40'));
273 $mform->addElement('text', 'dropbox_secret', get_string('secret', 'repository_dropbox'), array('value'=>$secret,'size' => '40'));
274
275 $mform->addRule('dropbox_key', $strrequired, 'required', null, 'client');
276 $mform->addRule('dropbox_secret', $strrequired, 'required', null, 'client');
277 $str_getkey = get_string('instruction', 'repository_dropbox');
278 $mform->addElement('static', null, '', $str_getkey);
279 }
280
281 /**
282 * Option names of dropbox plugin
283 * @return array
284 */
285 public static function get_type_option_names() {
a5adfa26 286 return array('dropbox_key', 'dropbox_secret', 'pluginname');
e35194be
DC
287 }
288
289 /**
290 * Dropbox plugin supports all kinds of files
291 * @return array
292 */
293 public function supported_filetypes() {
294 return '*';
295 }
3e123368 296
e35194be
DC
297 /**
298 * User cannot use the external link to dropbox
299 * @return int
300 */
301 public function supported_returntypes() {
302 return FILE_INTERNAL;
3e123368
DC
303 }
304}