Commit | Line | Data |
---|---|---|
6667f9e4 | 1 | <?php |
10d53fd3 DC |
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 | ||
6667f9e4 | 17 | /** |
3425813f | 18 | * This plugin is used to access Google Drive. |
6667f9e4 | 19 | * |
5bcfd504 | 20 | * @since Moodle 2.0 |
67233725 | 21 | * @package repository_googledocs |
61506a0a | 22 | * @copyright 2009 Dan Poltawski <talktodan@gmail.com> |
d078f6d3 | 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
6667f9e4 | 24 | */ |
3425813f FM |
25 | |
26 | defined('MOODLE_INTERNAL') || die(); | |
27 | ||
67233725 | 28 | require_once($CFG->dirroot . '/repository/lib.php'); |
28cdc043 | 29 | require_once($CFG->libdir . '/google/lib.php'); |
6667f9e4 | 30 | |
67233725 DC |
31 | /** |
32 | * Google Docs Plugin | |
33 | * | |
5bcfd504 | 34 | * @since Moodle 2.0 |
67233725 DC |
35 | * @package repository_googledocs |
36 | * @copyright 2009 Dan Poltawski <talktodan@gmail.com> | |
37 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
38 | */ | |
6667f9e4 | 39 | class repository_googledocs extends repository { |
6667f9e4 | 40 | |
3425813f FM |
41 | /** |
42 | * Google Client. | |
43 | * @var Google_Client | |
44 | */ | |
45 | private $client = null; | |
6667f9e4 | 46 | |
3425813f FM |
47 | /** |
48 | * Google Drive Service. | |
28cdc043 | 49 | * @var Google_Drive_Service |
3425813f FM |
50 | */ |
51 | private $service = null; | |
52 | ||
53 | /** | |
54 | * Session key to store the accesstoken. | |
55 | * @var string | |
56 | */ | |
57 | const SESSIONKEY = 'googledrive_accesstoken'; | |
4560fd1b | 58 | |
3425813f FM |
59 | /** |
60 | * URI to the callback file for OAuth. | |
61 | * @var string | |
62 | */ | |
63 | const CALLBACKURL = '/admin/oauth2callback.php'; | |
64 | ||
65 | /** | |
66 | * Constructor. | |
67 | * | |
68 | * @param int $repositoryid repository instance id. | |
69 | * @param int|stdClass $context a context id or context object. | |
70 | * @param array $options repository options. | |
71 | * @param int $readonly indicate this repo is readonly or not. | |
72 | * @return void | |
73 | */ | |
74 | public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array(), $readonly = 0) { | |
75 | parent::__construct($repositoryid, $context, $options, $readonly = 0); | |
76 | ||
77 | $callbackurl = new moodle_url(self::CALLBACKURL); | |
78 | ||
28cdc043 | 79 | $this->client = get_google_client(); |
3425813f FM |
80 | $this->client->setClientId(get_config('googledocs', 'clientid')); |
81 | $this->client->setClientSecret(get_config('googledocs', 'secret')); | |
28cdc043 | 82 | $this->client->setScopes(array(Google_Service_Drive::DRIVE_READONLY)); |
3425813f | 83 | $this->client->setRedirectUri($callbackurl->out(false)); |
28cdc043 | 84 | $this->service = new Google_Service_Drive($this->client); |
4560fd1b | 85 | |
94742bca | 86 | $this->check_login(); |
6667f9e4 | 87 | } |
88 | ||
3425813f FM |
89 | /** |
90 | * Returns the access token if any. | |
91 | * | |
92 | * @return string|null access token. | |
93 | */ | |
94 | protected function get_access_token() { | |
95 | global $SESSION; | |
96 | if (isset($SESSION->{self::SESSIONKEY})) { | |
97 | return $SESSION->{self::SESSIONKEY}; | |
98 | } | |
99 | return null; | |
100 | } | |
101 | ||
102 | /** | |
103 | * Store the access token in the session. | |
104 | * | |
105 | * @param string $token token to store. | |
106 | * @return void | |
107 | */ | |
108 | protected function store_access_token($token) { | |
109 | global $SESSION; | |
110 | $SESSION->{self::SESSIONKEY} = $token; | |
111 | } | |
112 | ||
113 | /** | |
114 | * Callback method during authentication. | |
115 | * | |
116 | * @return void | |
117 | */ | |
118 | public function callback() { | |
119 | if ($code = optional_param('oauth2code', null, PARAM_RAW)) { | |
120 | $this->client->authenticate($code); | |
121 | $this->store_access_token($this->client->getAccessToken()); | |
122 | } | |
123 | } | |
124 | ||
125 | /** | |
126 | * Checks whether the user is authenticate or not. | |
127 | * | |
128 | * @return bool true when logged in. | |
129 | */ | |
6667f9e4 | 130 | public function check_login() { |
3425813f FM |
131 | if ($token = $this->get_access_token()) { |
132 | $this->client->setAccessToken($token); | |
133 | return true; | |
134 | } | |
135 | return false; | |
6667f9e4 | 136 | } |
137 | ||
3425813f FM |
138 | /** |
139 | * Print or return the login form. | |
140 | * | |
141 | * @return void|array for ajax. | |
142 | */ | |
4560fd1b | 143 | public function print_login() { |
3425813f FM |
144 | $returnurl = new moodle_url('/repository/repository_callback.php'); |
145 | $returnurl->param('callback', 'yes'); | |
146 | $returnurl->param('repo_id', $this->id); | |
147 | $returnurl->param('sesskey', sesskey()); | |
4560fd1b | 148 | |
3425813f FM |
149 | $url = new moodle_url($this->client->createAuthUrl()); |
150 | $url->param('state', $returnurl->out_as_local_url(false)); | |
4560fd1b DP |
151 | if ($this->options['ajax']) { |
152 | $popup = new stdClass(); | |
153 | $popup->type = 'popup'; | |
154 | $popup->url = $url->out(false); | |
155 | return array('login' => array($popup)); | |
156 | } else { | |
157 | echo '<a target="_blank" href="'.$url->out(false).'">'.get_string('login', 'repository').'</a>'; | |
6667f9e4 | 158 | } |
159 | } | |
160 | ||
3425813f FM |
161 | /** |
162 | * Build the breadcrumb from a path. | |
163 | * | |
164 | * @param string $path to create a breadcrumb from. | |
165 | * @return array containing name and path of each crumb. | |
166 | */ | |
167 | protected function build_breadcrumb($path) { | |
168 | $bread = explode('/', $path); | |
169 | $crumbtrail = ''; | |
170 | foreach ($bread as $crumb) { | |
171 | list($id, $name) = $this->explode_node_path($crumb); | |
172 | $name = empty($name) ? $id : $name; | |
173 | $breadcrumb[] = array( | |
174 | 'name' => $name, | |
175 | 'path' => $this->build_node_path($id, $name, $crumbtrail) | |
176 | ); | |
177 | $tmp = end($breadcrumb); | |
178 | $crumbtrail = $tmp['path']; | |
179 | } | |
180 | return $breadcrumb; | |
181 | } | |
182 | ||
183 | /** | |
184 | * Generates a safe path to a node. | |
185 | * | |
186 | * Typically, a node will be id|Name of the node. | |
187 | * | |
188 | * @param string $id of the node. | |
189 | * @param string $name of the node, will be URL encoded. | |
190 | * @param string $root to append the node on, must be a result of this function. | |
191 | * @return string path to the node. | |
192 | */ | |
193 | protected function build_node_path($id, $name = '', $root = '') { | |
194 | $path = $id; | |
195 | if (!empty($name)) { | |
196 | $path .= '|' . urlencode($name); | |
197 | } | |
198 | if (!empty($root)) { | |
199 | $path = trim($root, '/') . '/' . $path; | |
200 | } | |
201 | return $path; | |
202 | } | |
203 | ||
204 | /** | |
205 | * Returns information about a node in a path. | |
206 | * | |
207 | * @see self::build_node_path() | |
208 | * @param string $node to extrat information from. | |
209 | * @return array about the node. | |
210 | */ | |
211 | protected function explode_node_path($node) { | |
212 | if (strpos($node, '|') !== false) { | |
213 | list($id, $name) = explode('|', $node, 2); | |
214 | $name = urldecode($name); | |
215 | } else { | |
216 | $id = $node; | |
217 | $name = ''; | |
218 | } | |
219 | $id = urldecode($id); | |
220 | return array( | |
221 | 0 => $id, | |
222 | 1 => $name, | |
223 | 'id' => $id, | |
224 | 'name' => $name | |
225 | ); | |
226 | } | |
227 | ||
228 | ||
229 | /** | |
230 | * List the files and folders. | |
231 | * | |
232 | * @param string $path path to browse. | |
233 | * @param string $page page to browse. | |
234 | * @return array of result. | |
235 | */ | |
6667f9e4 | 236 | public function get_listing($path='', $page = '') { |
3425813f FM |
237 | if (empty($path)) { |
238 | $path = $this->build_node_path('root', get_string('pluginname', 'repository_googledocs')); | |
239 | } | |
240 | ||
241 | // We analyse the path to extract what to browse. | |
242 | $trail = explode('/', $path); | |
243 | $uri = array_pop($trail); | |
244 | list($id, $name) = $this->explode_node_path($uri); | |
245 | ||
246 | // Handle the special keyword 'search', which we defined in self::search() so that | |
247 | // we could set up a breadcrumb in the search results. In any other case ID would be | |
248 | // 'root' which is a special keyword set up by Google, or a parent (folder) ID. | |
249 | if ($id === 'search') { | |
250 | return $this->search($name); | |
251 | } | |
252 | ||
253 | // Query the Drive. | |
254 | $q = "'" . str_replace("'", "\'", $id) . "' in parents"; | |
255 | $q .= ' AND trashed = false'; | |
256 | $results = $this->query($q, $path); | |
6667f9e4 | 257 | |
258 | $ret = array(); | |
259 | $ret['dynload'] = true; | |
3425813f FM |
260 | $ret['path'] = $this->build_breadcrumb($path); |
261 | $ret['list'] = $results; | |
6667f9e4 | 262 | return $ret; |
263 | } | |
264 | ||
3425813f FM |
265 | /** |
266 | * Search throughout the Google Drive. | |
267 | * | |
268 | * @param string $search_text text to search for. | |
269 | * @param int $page search page. | |
270 | * @return array of results. | |
271 | */ | |
68a7c9a6 | 272 | public function search($search_text, $page = 0) { |
3425813f FM |
273 | $path = $this->build_node_path('root', get_string('pluginname', 'repository_googledocs')); |
274 | $path = $this->build_node_path('search', $search_text, $path); | |
275 | ||
276 | // Query the Drive. | |
277 | $q = "fullText contains '" . str_replace("'", "\'", $search_text) . "'"; | |
278 | $q .= ' AND trashed = false'; | |
279 | $results = $this->query($q, $path); | |
6667f9e4 | 280 | |
281 | $ret = array(); | |
282 | $ret['dynload'] = true; | |
3425813f FM |
283 | $ret['path'] = $this->build_breadcrumb($path); |
284 | $ret['list'] = $results; | |
6667f9e4 | 285 | return $ret; |
286 | } | |
287 | ||
3425813f FM |
288 | /** |
289 | * Query Google Drive for files and folders using a search query. | |
290 | * | |
291 | * Documentation about the query format can be found here: | |
292 | * https://developers.google.com/drive/search-parameters | |
293 | * | |
294 | * This returns a list of files and folders with their details as they should be | |
295 | * formatted and returned by functions such as get_listing() or search(). | |
296 | * | |
297 | * @param string $q search query as expected by the Google API. | |
298 | * @param string $path parent path of the current files, will not be used for the query. | |
299 | * @param int $page page. | |
300 | * @return array of files and folders. | |
301 | */ | |
302 | protected function query($q, $path = null, $page = 0) { | |
303 | global $OUTPUT; | |
304 | ||
305 | $files = array(); | |
306 | $folders = array(); | |
307 | $fields = "items(id,title,mimeType,downloadUrl,fileExtension,exportLinks,modifiedDate,fileSize,thumbnailLink)"; | |
308 | $params = array('q' => $q, 'fields' => $fields); | |
15a5c4b2 | 309 | $config = get_config('googledocs'); |
3425813f FM |
310 | |
311 | try { | |
312 | // Retrieving files and folders. | |
313 | $response = $this->service->files->listFiles($params); | |
28cdc043 | 314 | } catch (Google_Service_Exception $e) { |
3425813f FM |
315 | if ($e->getCode() == 403 && strpos($e->getMessage(), 'Access Not Configured') !== false) { |
316 | // This is raised when the service Drive API has not been enabled on Google APIs control panel. | |
317 | throw new repository_exception('servicenotenabled', 'repository_googledocs'); | |
318 | } else { | |
319 | throw $e; | |
320 | } | |
321 | } | |
322 | ||
323 | $items = isset($response['items']) ? $response['items'] : array(); | |
324 | foreach ($items as $item) { | |
325 | if ($item['mimeType'] == 'application/vnd.google-apps.folder') { | |
326 | // This is a folder. | |
327 | $folders[$item['title'] . $item['id']] = array( | |
328 | 'title' => $item['title'], | |
329 | 'path' => $this->build_node_path($item['id'], $item['title'], $path), | |
330 | 'date' => strtotime($item['modifiedDate']), | |
663640f5 | 331 | 'thumbnail' => $OUTPUT->image_url(file_folder_icon(64))->out(false), |
3425813f FM |
332 | 'thumbnail_height' => 64, |
333 | 'thumbnail_width' => 64, | |
334 | 'children' => array() | |
335 | ); | |
336 | } else { | |
337 | // This is a file. | |
338 | if (isset($item['fileExtension'])) { | |
339 | // The file has an extension, therefore there is a download link. | |
340 | $title = $item['title']; | |
341 | $source = $item['downloadUrl']; | |
342 | } else { | |
343 | // The file is probably a Google Doc file, we get the corresponding export link. | |
344 | // This should be improved by allowing the user to select the type of export they'd like. | |
345 | $type = str_replace('application/vnd.google-apps.', '', $item['mimeType']); | |
346 | $title = ''; | |
347 | $exportType = ''; | |
15a5c4b2 SB |
348 | $types = get_mimetypes_array(); |
349 | ||
3425813f FM |
350 | switch ($type){ |
351 | case 'document': | |
15a5c4b2 SB |
352 | $ext = $config->documentformat; |
353 | $title = $item['title'] . '.'. $ext; | |
354 | if ($ext === 'rtf') { | |
355 | // Moodle user 'text/rtf' as the MIME type for RTF files. | |
356 | // Google uses 'application/rtf' for the same type of file. | |
357 | // See https://developers.google.com/drive/v3/web/manage-downloads. | |
358 | $exportType = 'application/rtf'; | |
359 | } else { | |
360 | $exportType = $types[$ext]['type']; | |
361 | } | |
3425813f FM |
362 | break; |
363 | case 'presentation': | |
15a5c4b2 SB |
364 | $ext = $config->presentationformat; |
365 | $title = $item['title'] . '.'. $ext; | |
366 | $exportType = $types[$ext]['type']; | |
3425813f FM |
367 | break; |
368 | case 'spreadsheet': | |
15a5c4b2 SB |
369 | $ext = $config->spreadsheetformat; |
370 | $title = $item['title'] . '.'. $ext; | |
371 | $exportType = $types[$ext]['type']; | |
372 | break; | |
373 | case 'drawing': | |
374 | $ext = $config->drawingformat; | |
375 | $title = $item['title'] . '.'. $ext; | |
376 | $exportType = $types[$ext]['type']; | |
3425813f FM |
377 | break; |
378 | } | |
379 | // Skips invalid/unknown types. | |
380 | if (empty($title) || !isset($item['exportLinks'][$exportType])) { | |
381 | continue; | |
382 | } | |
383 | $source = $item['exportLinks'][$exportType]; | |
384 | } | |
385 | // Adds the file to the file list. Using the itemId along with the title as key | |
386 | // of the array because Google Drive allows files with identical names. | |
387 | $files[$title . $item['id']] = array( | |
388 | 'title' => $title, | |
389 | 'source' => $source, | |
390 | 'date' => strtotime($item['modifiedDate']), | |
391 | 'size' => isset($item['fileSize']) ? $item['fileSize'] : null, | |
663640f5 | 392 | 'thumbnail' => $OUTPUT->image_url(file_extension_icon($title, 64))->out(false), |
3425813f FM |
393 | 'thumbnail_height' => 64, |
394 | 'thumbnail_width' => 64, | |
395 | // Do not use real thumbnails as they wouldn't work if the user disabled 3rd party | |
396 | // plugins in his browser, or if they're not logged in their Google account. | |
397 | ); | |
398 | ||
399 | // Sometimes the real thumbnails can't be displayed, for example if 3rd party cookies are disabled | |
400 | // or if the user is not logged in Google anymore. But this restriction does not seem to be applied | |
401 | // to a small subset of files. | |
402 | $extension = strtolower(pathinfo($title, PATHINFO_EXTENSION)); | |
403 | if (isset($item['thumbnailLink']) && in_array($extension, array('jpg', 'png', 'txt', 'pdf'))) { | |
404 | $files[$title . $item['id']]['realthumbnail'] = $item['thumbnailLink']; | |
405 | } | |
406 | } | |
407 | } | |
408 | ||
409 | // Filter and order the results. | |
410 | $files = array_filter($files, array($this, 'filter')); | |
2f1e464a PS |
411 | core_collator::ksort($files, core_collator::SORT_NATURAL); |
412 | core_collator::ksort($folders, core_collator::SORT_NATURAL); | |
3425813f FM |
413 | return array_merge(array_values($folders), array_values($files)); |
414 | } | |
415 | ||
416 | /** | |
417 | * Logout. | |
418 | * | |
419 | * @return string | |
420 | */ | |
4560fd1b | 421 | public function logout() { |
3425813f | 422 | $this->store_access_token(null); |
6667f9e4 | 423 | return parent::logout(); |
424 | } | |
425 | ||
3425813f FM |
426 | /** |
427 | * Get a file. | |
428 | * | |
429 | * @param string $reference reference of the file. | |
430 | * @param string $file name to save the file to. | |
431 | * @return string JSON encoded array of information about the file. | |
432 | */ | |
433 | public function get_file($reference, $filename = '') { | |
eb459f71 PS |
434 | global $CFG; |
435 | ||
28cdc043 FM |
436 | $auth = $this->client->getAuth(); |
437 | $request = $auth->authenticatedRequest(new Google_Http_Request($reference)); | |
438 | if ($request->getResponseHttpCode() == 200) { | |
3425813f | 439 | $path = $this->prepare_file($filename); |
28cdc043 | 440 | $content = $request->getResponseBody(); |
3425813f | 441 | if (file_put_contents($path, $content) !== false) { |
eb459f71 | 442 | @chmod($path, $CFG->filepermissions); |
3425813f FM |
443 | return array( |
444 | 'path' => $path, | |
445 | 'url' => $reference | |
446 | ); | |
447 | } | |
ec7e998f | 448 | } |
3425813f FM |
449 | throw new repository_exception('cannotdownload', 'repository'); |
450 | } | |
451 | ||
452 | /** | |
453 | * Prepare file reference information. | |
454 | * | |
455 | * We are using this method to clean up the source to make sure that it | |
456 | * is a valid source. | |
457 | * | |
458 | * @param string $source of the file. | |
459 | * @return string file reference. | |
460 | */ | |
461 | public function get_file_reference($source) { | |
462 | return clean_param($source, PARAM_URL); | |
41076c58 | 463 | } |
6667f9e4 | 464 | |
3425813f FM |
465 | /** |
466 | * What kind of files will be in this repository? | |
467 | * | |
468 | * @return array return '*' means this repository support any files, otherwise | |
469 | * return mimetypes of files, it can be an array | |
470 | */ | |
41076c58 | 471 | public function supported_filetypes() { |
4560fd1b | 472 | return '*'; |
41076c58 | 473 | } |
3425813f FM |
474 | |
475 | /** | |
476 | * Tells how the file can be picked from this repository. | |
477 | * | |
478 | * Maximum value is FILE_INTERNAL | FILE_EXTERNAL | FILE_REFERENCE. | |
479 | * | |
480 | * @return int | |
481 | */ | |
41076c58 DC |
482 | public function supported_returntypes() { |
483 | return FILE_INTERNAL; | |
484 | } | |
4560fd1b | 485 | |
3425813f FM |
486 | /** |
487 | * Return names of the general options. | |
488 | * By default: no general option name. | |
489 | * | |
490 | * @return array | |
491 | */ | |
4560fd1b | 492 | public static function get_type_option_names() { |
15a5c4b2 SB |
493 | return array('clientid', 'secret', 'pluginname', |
494 | 'documentformat', 'drawingformat', | |
495 | 'presentationformat', 'spreadsheetformat'); | |
4560fd1b DP |
496 | } |
497 | ||
3425813f FM |
498 | /** |
499 | * Edit/Create Admin Settings Moodle form. | |
500 | * | |
501 | * @param moodleform $mform Moodle form (passed by reference). | |
502 | * @param string $classname repository class name. | |
503 | */ | |
4560fd1b | 504 | public static function type_config_form($mform, $classname = 'repository') { |
3425813f FM |
505 | $callbackurl = new moodle_url(self::CALLBACKURL); |
506 | ||
4560fd1b | 507 | $a = new stdClass; |
8b503936 | 508 | $a->docsurl = get_docs_url('Google_OAuth_2.0_setup'); |
3425813f | 509 | $a->callbackurl = $callbackurl->out(false); |
4560fd1b DP |
510 | |
511 | $mform->addElement('static', null, '', get_string('oauthinfo', 'repository_googledocs', $a)); | |
512 | ||
513 | parent::type_config_form($mform); | |
514 | $mform->addElement('text', 'clientid', get_string('clientid', 'repository_googledocs')); | |
999427e9 | 515 | $mform->setType('clientid', PARAM_RAW_TRIMMED); |
4560fd1b | 516 | $mform->addElement('text', 'secret', get_string('secret', 'repository_googledocs')); |
999427e9 | 517 | $mform->setType('secret', PARAM_RAW_TRIMMED); |
4560fd1b DP |
518 | |
519 | $strrequired = get_string('required'); | |
520 | $mform->addRule('clientid', $strrequired, 'required', null, 'client'); | |
521 | $mform->addRule('secret', $strrequired, 'required', null, 'client'); | |
15a5c4b2 SB |
522 | |
523 | $mform->addElement('static', null, '', get_string('importformat', 'repository_googledocs', $a)); | |
524 | ||
525 | // Documents. | |
526 | $docsformat = array(); | |
527 | $docsformat['html'] = 'html'; | |
528 | $docsformat['docx'] = 'docx'; | |
529 | $docsformat['odt'] = 'odt'; | |
530 | $docsformat['pdf'] = 'pdf'; | |
531 | $docsformat['rtf'] = 'rtf'; | |
532 | $docsformat['txt'] = 'txt'; | |
533 | core_collator::ksort($docsformat, core_collator::SORT_NATURAL); | |
534 | ||
535 | $mform->addElement('select', 'documentformat', get_string('docsformat', 'repository_googledocs'), $docsformat); | |
536 | $mform->setDefault('documentformat', $docsformat['rtf']); | |
537 | $mform->setType('documentformat', PARAM_ALPHANUM); | |
538 | ||
539 | // Drawing. | |
540 | $drawingformat = array(); | |
541 | $drawingformat['jpeg'] = 'jpeg'; | |
542 | $drawingformat['png'] = 'png'; | |
543 | $drawingformat['svg'] = 'svg'; | |
544 | $drawingformat['pdf'] = 'pdf'; | |
545 | core_collator::ksort($drawingformat, core_collator::SORT_NATURAL); | |
546 | ||
547 | $mform->addElement('select', 'drawingformat', get_string('drawingformat', 'repository_googledocs'), $drawingformat); | |
548 | $mform->setDefault('drawingformat', $drawingformat['pdf']); | |
549 | $mform->setType('drawingformat', PARAM_ALPHANUM); | |
550 | ||
551 | // Presentation. | |
552 | $presentationformat = array(); | |
553 | $presentationformat['pdf'] = 'pdf'; | |
554 | $presentationformat['pptx'] = 'pptx'; | |
555 | $presentationformat['txt'] = 'txt'; | |
556 | core_collator::ksort($presentationformat, core_collator::SORT_NATURAL); | |
557 | ||
558 | $mform->addElement('select', 'presentationformat', get_string('presentationformat', 'repository_googledocs'), $presentationformat); | |
559 | $mform->setDefault('presentationformat', $presentationformat['pptx']); | |
560 | $mform->setType('presentationformat', PARAM_ALPHANUM); | |
561 | ||
562 | // Spreadsheet. | |
563 | $spreadsheetformat = array(); | |
564 | $spreadsheetformat['csv'] = 'csv'; | |
565 | $spreadsheetformat['ods'] = 'ods'; | |
566 | $spreadsheetformat['pdf'] = 'pdf'; | |
567 | $spreadsheetformat['xlsx'] = 'xlsx'; | |
568 | core_collator::ksort($spreadsheetformat, core_collator::SORT_NATURAL); | |
569 | ||
570 | $mform->addElement('select', 'spreadsheetformat', get_string('spreadsheetformat', 'repository_googledocs'), $spreadsheetformat); | |
571 | $mform->setDefault('spreadsheetformat', $spreadsheetformat['xlsx']); | |
572 | $mform->setType('spreadsheetformat', PARAM_ALPHANUM); | |
4560fd1b | 573 | } |
6667f9e4 | 574 | } |
4560fd1b | 575 | // Icon from: http://www.iconspedia.com/icon/google-2706.html. |