Commit | Line | Data |
---|---|---|
12c79bfd | 1 | <?php |
1cf56396 | 2 | |
6f2cd52a DC |
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 | ||
1cf56396 | 18 | |
aca64b79 | 19 | /** |
6f2cd52a DC |
20 | * This file contains classes used to manage the repository plugins in Moodle |
21 | * and was introduced as part of the changes occuring in Moodle 2.0 | |
22 | * | |
23 | * @since 2.0 | |
5d354ded | 24 | * @package core |
6f2cd52a | 25 | * @subpackage repository |
5d354ded PS |
26 | * @copyright 2009 Dongsheng Cai <dongsheng@moodle.com> |
27 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
aca64b79 | 28 | */ |
29 | ||
19add4c0 | 30 | require_once(dirname(dirname(__FILE__)) . '/config.php'); |
c19f8e7d | 31 | require_once($CFG->libdir . '/filelib.php'); |
32 | require_once($CFG->libdir . '/formslib.php'); | |
41076c58 DC |
33 | |
34 | define('FILE_EXTERNAL', 1); | |
35 | define('FILE_INTERNAL', 2); | |
f392caba | 36 | define('RENAME_SUFFIX', '_2'); |
41076c58 | 37 | |
a6600395 | 38 | /** |
6f2cd52a DC |
39 | * This class is used to manage repository plugins |
40 | * | |
a6600395 | 41 | * A repository_type is a repository plug-in. It can be Box.net, Flick-r, ... |
42 | * A repository type can be edited, sorted and hidden. It is mandatory for an | |
43 | * administrator to create a repository type in order to be able to create | |
44 | * some instances of this type. | |
a6600395 | 45 | * Coding note: |
46 | * - a repository_type object is mapped to the "repository" database table | |
47 | * - "typename" attibut maps the "type" database field. It is unique. | |
48 | * - general "options" for a repository type are saved in the config_plugin table | |
eb239694 | 49 | * - when you delete a repository, all instances are deleted, and general |
50 | * options are also deleted from database | |
a6600395 | 51 | * - When you create a type for a plugin that can't have multiple instances, a |
52 | * instance is automatically created. | |
6f2cd52a DC |
53 | * |
54 | * @package moodlecore | |
55 | * @subpackage repository | |
56 | * @copyright 2009 Jerome Mouneyrac | |
57 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
a6600395 | 58 | */ |
59 | class repository_type { | |
60 | ||
61 | ||
62 | /** | |
63 | * Type name (no whitespace) - A type name is unique | |
64 | * Note: for a user-friendly type name see get_readablename() | |
65 | * @var String | |
66 | */ | |
67 | private $_typename; | |
68 | ||
69 | ||
70 | /** | |
71 | * Options of this type | |
72 | * They are general options that any instance of this type would share | |
73 | * e.g. API key | |
74 | * These options are saved in config_plugin table | |
75 | * @var array | |
76 | */ | |
7a3b93c1 | 77 | private $_options; |
a6600395 | 78 | |
79 | ||
80 | /** | |
81 | * Is the repository type visible or hidden | |
82 | * If false (hidden): no instances can be created, edited, deleted, showned , used... | |
83 | * @var boolean | |
84 | */ | |
7a3b93c1 | 85 | private $_visible; |
a6600395 | 86 | |
87 | ||
88 | /** | |
89 | * 0 => not ordered, 1 => first position, 2 => second position... | |
90 | * A not order type would appear in first position (should never happened) | |
91 | * @var integer | |
92 | */ | |
93 | private $_sortorder; | |
94 | ||
f48fb4d6 | 95 | /** |
96 | * Return if the instance is visible in a context | |
97 | * TODO: check if the context visibility has been overwritten by the plugin creator | |
98 | * (need to create special functions to be overvwritten in repository class) | |
5363905a | 99 | * @param objet $context - context |
f48fb4d6 | 100 | * @return boolean |
101 | */ | |
5363905a DC |
102 | public function get_contextvisibility($context) { |
103 | global $USER; | |
dbc01944 | 104 | |
5363905a | 105 | if ($context->contextlevel == CONTEXT_COURSE) { |
f48fb4d6 | 106 | return $this->_options['enablecourseinstances']; |
107 | } | |
108 | ||
5363905a | 109 | if ($context->contextlevel == CONTEXT_USER) { |
f48fb4d6 | 110 | return $this->_options['enableuserinstances']; |
111 | } | |
112 | ||
113 | //the context is SITE | |
114 | return true; | |
115 | } | |
dbc01944 | 116 | |
f48fb4d6 | 117 | |
118 | ||
a6600395 | 119 | /** |
120 | * repository_type constructor | |
2b8beee3 | 121 | * @global object $CFG |
a6600395 | 122 | * @param integer $typename |
123 | * @param array $typeoptions | |
124 | * @param boolean $visible | |
125 | * @param integer $sortorder (don't really need set, it will be during create() call) | |
126 | */ | |
a642bf6f | 127 | public function __construct($typename = '', $typeoptions = array(), $visible = true, $sortorder = 0) { |
a6600395 | 128 | global $CFG; |
129 | ||
130 | //set type attributs | |
131 | $this->_typename = $typename; | |
132 | $this->_visible = $visible; | |
133 | $this->_sortorder = $sortorder; | |
46dd6bb0 | 134 | |
a6600395 | 135 | //set options attribut |
136 | $this->_options = array(); | |
a5adfa26 | 137 | $options = repository::static_function($typename, 'get_type_option_names'); |
a6600395 | 138 | //check that the type can be setup |
06e65e1e | 139 | if (!empty($options)) { |
a6600395 | 140 | //set the type options |
141 | foreach ($options as $config) { | |
a5adfa26 | 142 | if (array_key_exists($config, $typeoptions)) { |
7a3b93c1 | 143 | $this->_options[$config] = $typeoptions[$config]; |
a6600395 | 144 | } |
145 | } | |
146 | } | |
f48fb4d6 | 147 | |
148 | //retrieve visibility from option | |
149 | if (array_key_exists('enablecourseinstances',$typeoptions)) { | |
150 | $this->_options['enablecourseinstances'] = $typeoptions['enablecourseinstances']; | |
9f7c761a | 151 | } else { |
152 | $this->_options['enablecourseinstances'] = 0; | |
f48fb4d6 | 153 | } |
dbc01944 | 154 | |
f48fb4d6 | 155 | if (array_key_exists('enableuserinstances',$typeoptions)) { |
156 | $this->_options['enableuserinstances'] = $typeoptions['enableuserinstances']; | |
9f7c761a | 157 | } else { |
158 | $this->_options['enableuserinstances'] = 0; | |
f48fb4d6 | 159 | } |
dbc01944 | 160 | |
a6600395 | 161 | } |
162 | ||
163 | /** | |
164 | * Get the type name (no whitespace) | |
165 | * For a human readable name, use get_readablename() | |
166 | * @return String the type name | |
167 | */ | |
7a3b93c1 | 168 | public function get_typename() { |
a6600395 | 169 | return $this->_typename; |
170 | } | |
171 | ||
172 | /** | |
173 | * Return a human readable and user-friendly type name | |
174 | * @return string user-friendly type name | |
175 | */ | |
7a3b93c1 | 176 | public function get_readablename() { |
614d18d2 | 177 | return get_string('pluginname','repository_'.$this->_typename); |
a6600395 | 178 | } |
179 | ||
180 | /** | |
181 | * Return general options | |
182 | * @return array the general options | |
183 | */ | |
7a3b93c1 | 184 | public function get_options() { |
a6600395 | 185 | return $this->_options; |
186 | } | |
187 | ||
188 | /** | |
189 | * Return visibility | |
190 | * @return boolean | |
191 | */ | |
7a3b93c1 | 192 | public function get_visible() { |
a6600395 | 193 | return $this->_visible; |
194 | } | |
195 | ||
196 | /** | |
197 | * Return order / position of display in the file picker | |
198 | * @return integer | |
199 | */ | |
7a3b93c1 | 200 | public function get_sortorder() { |
a6600395 | 201 | return $this->_sortorder; |
202 | } | |
203 | ||
204 | /** | |
205 | * Create a repository type (the type name must not already exist) | |
a75c78d3 | 206 | * @param boolean throw exception? |
207 | * @return mixed return int if create successfully, return false if | |
208 | * any errors | |
a6600395 | 209 | * @global object $DB |
210 | */ | |
a75c78d3 | 211 | public function create($silent = false) { |
a6600395 | 212 | global $DB; |
213 | ||
214 | //check that $type has been set | |
215 | $timmedtype = trim($this->_typename); | |
216 | if (empty($timmedtype)) { | |
7a3b93c1 | 217 | throw new repository_exception('emptytype', 'repository'); |
a6600395 | 218 | } |
219 | ||
220 | //set sortorder as the last position in the list | |
7a3b93c1 | 221 | if (!isset($this->_sortorder) || $this->_sortorder == 0 ) { |
a6600395 | 222 | $sql = "SELECT MAX(sortorder) FROM {repository}"; |
223 | $this->_sortorder = 1 + $DB->get_field_sql($sql); | |
224 | } | |
225 | ||
226 | //only create a new type if it doesn't already exist | |
227 | $existingtype = $DB->get_record('repository', array('type'=>$this->_typename)); | |
7a3b93c1 | 228 | if (!$existingtype) { |
229 | //create the type | |
6bdfef5d | 230 | $newtype = new stdClass(); |
7a3b93c1 | 231 | $newtype->type = $this->_typename; |
232 | $newtype->visible = $this->_visible; | |
233 | $newtype->sortorder = $this->_sortorder; | |
a75c78d3 | 234 | $plugin_id = $DB->insert_record('repository', $newtype); |
7a3b93c1 | 235 | //save the options in DB |
236 | $this->update_options(); | |
237 | ||
a5adfa26 DC |
238 | $instanceoptionnames = repository::static_function($this->_typename, 'get_instance_option_names'); |
239 | ||
edb50637 | 240 | //if the plugin type has no multiple instance (e.g. has no instance option name) so it wont |
7a3b93c1 | 241 | //be possible for the administrator to create a instance |
242 | //in this case we need to create an instance | |
edb50637 | 243 | if (empty($instanceoptionnames)) { |
7a3b93c1 | 244 | $instanceoptions = array(); |
a5adfa26 DC |
245 | if (empty($this->_options['pluginname'])) { |
246 | // when moodle trying to install some repo plugin automatically | |
247 | // this option will be empty, get it from language string when display | |
248 | $instanceoptions['name'] = ''; | |
249 | } else { | |
250 | // when admin trying to add a plugin manually, he will type a name | |
251 | // for it | |
252 | $instanceoptions['name'] = $this->_options['pluginname']; | |
253 | } | |
dbc01944 | 254 | repository::static_function($this->_typename, 'create', $this->_typename, 0, get_system_context(), $instanceoptions); |
7a3b93c1 | 255 | } |
60c366e8 | 256 | //run plugin_init function |
257 | if (!repository::static_function($this->_typename, 'plugin_init')) { | |
258 | if (!$silent) { | |
259 | throw new repository_exception('cannotinitplugin', 'repository'); | |
260 | } | |
261 | } | |
262 | ||
a75c78d3 | 263 | if(!empty($plugin_id)) { |
264 | // return plugin_id if create successfully | |
265 | return $plugin_id; | |
266 | } else { | |
267 | return false; | |
268 | } | |
948c2860 | 269 | |
7a3b93c1 | 270 | } else { |
a75c78d3 | 271 | if (!$silent) { |
272 | throw new repository_exception('existingrepository', 'repository'); | |
273 | } | |
274 | // If plugin existed, return false, tell caller no new plugins were created. | |
275 | return false; | |
a6600395 | 276 | } |
277 | } | |
278 | ||
279 | ||
280 | /** | |
281 | * Update plugin options into the config_plugin table | |
282 | * @param array $options | |
283 | * @return boolean | |
284 | */ | |
7a3b93c1 | 285 | public function update_options($options = null) { |
a5adfa26 DC |
286 | global $DB; |
287 | $classname = 'repository_' . $this->_typename; | |
288 | $instanceoptions = repository::static_function($this->_typename, 'get_instance_option_names'); | |
289 | if (empty($instanceoptions)) { | |
290 | // update repository instance name if this plugin type doesn't have muliti instances | |
291 | $params = array(); | |
292 | $params['type'] = $this->_typename; | |
293 | $instances = repository::get_instances($params); | |
294 | $instance = array_pop($instances); | |
295 | if ($instance) { | |
296 | $DB->set_field('repository_instances', 'name', $options['pluginname'], array('id'=>$instance->id)); | |
297 | } | |
298 | unset($options['pluginname']); | |
299 | } | |
300 | ||
7a3b93c1 | 301 | if (!empty($options)) { |
a6600395 | 302 | $this->_options = $options; |
303 | } | |
304 | ||
305 | foreach ($this->_options as $name => $value) { | |
a5adfa26 | 306 | set_config($name, $value, $this->_typename); |
a6600395 | 307 | } |
308 | ||
309 | return true; | |
310 | } | |
311 | ||
312 | /** | |
313 | * Update visible database field with the value given as parameter | |
314 | * or with the visible value of this object | |
315 | * This function is private. | |
316 | * For public access, have a look to switch_and_update_visibility() | |
317 | * @global object $DB | |
318 | * @param boolean $visible | |
319 | * @return boolean | |
320 | */ | |
7a3b93c1 | 321 | private function update_visible($visible = null) { |
a6600395 | 322 | global $DB; |
323 | ||
7a3b93c1 | 324 | if (!empty($visible)) { |
a6600395 | 325 | $this->_visible = $visible; |
326 | } | |
7a3b93c1 | 327 | else if (!isset($this->_visible)) { |
a6600395 | 328 | throw new repository_exception('updateemptyvisible', 'repository'); |
329 | } | |
330 | ||
331 | return $DB->set_field('repository', 'visible', $this->_visible, array('type'=>$this->_typename)); | |
332 | } | |
333 | ||
334 | /** | |
335 | * Update database sortorder field with the value given as parameter | |
336 | * or with the sortorder value of this object | |
337 | * This function is private. | |
338 | * For public access, have a look to move_order() | |
339 | * @global object $DB | |
340 | * @param integer $sortorder | |
341 | * @return boolean | |
342 | */ | |
7a3b93c1 | 343 | private function update_sortorder($sortorder = null) { |
a6600395 | 344 | global $DB; |
345 | ||
7a3b93c1 | 346 | if (!empty($sortorder) && $sortorder!=0) { |
a6600395 | 347 | $this->_sortorder = $sortorder; |
348 | } | |
349 | //if sortorder is not set, we set it as the ;ast position in the list | |
7a3b93c1 | 350 | else if (!isset($this->_sortorder) || $this->_sortorder == 0 ) { |
a6600395 | 351 | $sql = "SELECT MAX(sortorder) FROM {repository}"; |
352 | $this->_sortorder = 1 + $DB->get_field_sql($sql); | |
353 | } | |
354 | ||
355 | return $DB->set_field('repository', 'sortorder', $this->_sortorder, array('type'=>$this->_typename)); | |
356 | } | |
357 | ||
358 | /** | |
359 | * Change order of the type with its adjacent upper or downer type | |
360 | * (database fields are updated) | |
361 | * Algorithm details: | |
362 | * 1. retrieve all types in an array. This array is sorted by sortorder, | |
363 | * and the array keys start from 0 to X (incremented by 1) | |
364 | * 2. switch sortorder values of this type and its adjacent type | |
365 | * @global object $DB | |
366 | * @param string $move "up" or "down" | |
367 | */ | |
368 | public function move_order($move) { | |
369 | global $DB; | |
a6600395 | 370 | |
dbc01944 | 371 | $types = repository::get_types(); // retrieve all types |
7a3b93c1 | 372 | |
373 | /// retrieve this type into the returned array | |
374 | $i = 0; | |
375 | while (!isset($indice) && $i<count($types)) { | |
376 | if ($types[$i]->get_typename() == $this->_typename) { | |
a6600395 | 377 | $indice = $i; |
378 | } | |
379 | $i++; | |
380 | } | |
381 | ||
7a3b93c1 | 382 | /// retrieve adjacent indice |
a6600395 | 383 | switch ($move) { |
384 | case "up": | |
385 | $adjacentindice = $indice - 1; | |
7a3b93c1 | 386 | break; |
a6600395 | 387 | case "down": |
388 | $adjacentindice = $indice + 1; | |
7a3b93c1 | 389 | break; |
a6600395 | 390 | default: |
7a3b93c1 | 391 | throw new repository_exception('movenotdefined', 'repository'); |
a6600395 | 392 | } |
393 | ||
394 | //switch sortorder of this type and the adjacent type | |
395 | //TODO: we could reset sortorder for all types. This is not as good in performance term, but | |
396 | //that prevent from wrong behaviour on a screwed database. As performance are not important in this particular case | |
397 | //it worth to change the algo. | |
7a3b93c1 | 398 | if ($adjacentindice>=0 && !empty($types[$adjacentindice])) { |
a6600395 | 399 | $DB->set_field('repository', 'sortorder', $this->_sortorder, array('type'=>$types[$adjacentindice]->get_typename())); |
400 | $this->update_sortorder($types[$adjacentindice]->get_sortorder()); | |
401 | } | |
402 | } | |
403 | ||
404 | /** | |
79698344 MD |
405 | * 1. Change visibility to the value chosen |
406 | * | |
a6600395 | 407 | * 2. Update the type |
2b8beee3 | 408 | * @return boolean |
a6600395 | 409 | */ |
79698344 MD |
410 | public function update_visibility($visible = null) { |
411 | if (is_bool($visible)) { | |
412 | $this->_visible = $visible; | |
413 | } else { | |
414 | $this->_visible = !$this->_visible; | |
415 | } | |
a6600395 | 416 | return $this->update_visible(); |
417 | } | |
418 | ||
419 | ||
420 | /** | |
eb239694 | 421 | * Delete a repository_type (general options are removed from config_plugin |
422 | * table, and all instances are deleted) | |
a6600395 | 423 | * @global object $DB |
424 | * @return boolean | |
425 | */ | |
7a3b93c1 | 426 | public function delete() { |
a6600395 | 427 | global $DB; |
46dd6bb0 | 428 | |
429 | //delete all instances of this type | |
6f2cd52a DC |
430 | $params = array(); |
431 | $params['context'] = array(); | |
432 | $params['onlyvisible'] = false; | |
433 | $params['type'] = $this->_typename; | |
434 | $instances = repository::get_instances($params); | |
7a3b93c1 | 435 | foreach ($instances as $instance) { |
46dd6bb0 | 436 | $instance->delete(); |
437 | } | |
438 | ||
eb239694 | 439 | //delete all general options |
7a3b93c1 | 440 | foreach ($this->_options as $name => $value) { |
eb239694 | 441 | set_config($name, null, $this->_typename); |
442 | } | |
443 | ||
a6600395 | 444 | return $DB->delete_records('repository', array('type' => $this->_typename)); |
445 | } | |
446 | } | |
447 | ||
a6600395 | 448 | /** |
8d419e59 | 449 | * This is the base class of the repository class |
450 | * | |
451 | * To use repository plugin, see: | |
728ebac7 | 452 | * http://docs.moodle.org/dev/Repository_How_to_Create_Plugin |
8d419e59 | 453 | * class repository is an abstract class, some functions must be implemented in subclass. |
e35194be | 454 | * See an example: repository/boxnet/lib.php |
8d419e59 | 455 | * |
456 | * A few notes: | |
457 | * // for ajax file picker, this will print a json string to tell file picker | |
458 | * // how to build a login form | |
459 | * $repo->print_login(); | |
460 | * // for ajax file picker, this will return a files list. | |
461 | * $repo->get_listing(); | |
462 | * // this function will be used for non-javascript version. | |
463 | * $repo->print_listing(); | |
464 | * // print a search box | |
465 | * $repo->print_search(); | |
466 | * | |
6f2cd52a DC |
467 | * @package moodlecore |
468 | * @subpackage repository | |
469 | * @copyright 2009 Dongsheng Cai <dongsheng@moodle.com> | |
470 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
a6600395 | 471 | */ |
fca079c5 | 472 | abstract class repository { |
efe018b4 | 473 | // $disabled can be set to true to disable a plugin by force |
474 | // example: self::$disabled = true | |
475 | public $disabled = false; | |
4a65c39a | 476 | public $id; |
be85f7ab | 477 | /** @var object current context */ |
4a65c39a | 478 | public $context; |
479 | public $options; | |
948c2860 | 480 | public $readonly; |
41076c58 | 481 | public $returntypes; |
a5adfa26 DC |
482 | /** @var object repository instance database record */ |
483 | public $instance; | |
a0ff4137 DC |
484 | /** |
485 | * 1. Initialize context and options | |
486 | * 2. Accept necessary parameters | |
487 | * | |
e35194be DC |
488 | * @param integer $repositoryid repository instance id |
489 | * @param integer|object a context id or context object | |
490 | * @param array $options repository options | |
a0ff4137 | 491 | */ |
e35194be | 492 | public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array(), $readonly = 0) { |
a5adfa26 | 493 | global $DB; |
a0ff4137 | 494 | $this->id = $repositoryid; |
be85f7ab | 495 | if (is_object($context)) { |
e35194be DC |
496 | $this->context = $context; |
497 | } else { | |
498 | $this->context = get_context_instance_by_id($context); | |
499 | } | |
a5adfa26 | 500 | $this->instance = $DB->get_record('repository_instances', array('id'=>$this->id)); |
a0ff4137 DC |
501 | $this->readonly = $readonly; |
502 | $this->options = array(); | |
e35194be | 503 | |
a0ff4137 DC |
504 | if (is_array($options)) { |
505 | $options = array_merge($this->get_option(), $options); | |
506 | } else { | |
507 | $options = $this->get_option(); | |
508 | } | |
509 | foreach ($options as $n => $v) { | |
510 | $this->options[$n] = $v; | |
511 | } | |
512 | $this->name = $this->get_name(); | |
513 | $this->returntypes = $this->supported_returntypes(); | |
514 | $this->super_called = true; | |
515 | } | |
1cf56396 | 516 | |
dbc01944 | 517 | /** |
e35194be | 518 | * Get a repository type object by a given type name. |
dbc01944 | 519 | * @global object $DB |
e35194be DC |
520 | * @param string $typename the repository type name |
521 | * @return repository_type|bool | |
dbc01944 | 522 | */ |
523 | public static function get_type_by_typename($typename) { | |
524 | global $DB; | |
525 | ||
526 | if (!$record = $DB->get_record('repository',array('type' => $typename))) { | |
527 | return false; | |
528 | } | |
529 | ||
530 | return new repository_type($typename, (array)get_config($typename), $record->visible, $record->sortorder); | |
531 | } | |
532 | ||
533 | /** | |
e35194be | 534 | * Get the repository type by a given repository type id. |
dbc01944 | 535 | * @global object $DB |
8e0946bf DC |
536 | * @param int $id the type id |
537 | * @return object | |
dbc01944 | 538 | */ |
539 | public static function get_type_by_id($id) { | |
540 | global $DB; | |
541 | ||
542 | if (!$record = $DB->get_record('repository',array('id' => $id))) { | |
543 | return false; | |
544 | } | |
545 | ||
546 | return new repository_type($record->type, (array)get_config($record->type), $record->visible, $record->sortorder); | |
547 | } | |
548 | ||
549 | /** | |
e35194be DC |
550 | * Return all repository types ordered by sortorder field |
551 | * first repository type in returnedarray[0], second repository type in returnedarray[1], ... | |
dbc01944 | 552 | * @global object $DB |
e35194be | 553 | * @global object $CFG |
dbc01944 | 554 | * @param boolean $visible can return types by visiblity, return all types if null |
555 | * @return array Repository types | |
556 | */ | |
557 | public static function get_types($visible=null) { | |
489d8a75 | 558 | global $DB, $CFG; |
dbc01944 | 559 | |
560 | $types = array(); | |
561 | $params = null; | |
562 | if (!empty($visible)) { | |
563 | $params = array('visible' => $visible); | |
564 | } | |
565 | if ($records = $DB->get_records('repository',$params,'sortorder')) { | |
566 | foreach($records as $type) { | |
e35194be | 567 | if (file_exists($CFG->dirroot . '/repository/'. $type->type .'/lib.php')) { |
489d8a75 DC |
568 | $types[] = new repository_type($type->type, (array)get_config($type->type), $type->visible, $type->sortorder); |
569 | } | |
dbc01944 | 570 | } |
571 | } | |
572 | ||
573 | return $types; | |
574 | } | |
575 | ||
576 | /** | |
e35194be DC |
577 | * To check if the context id is valid |
578 | * @global object $USER | |
579 | * @param int $contextid | |
dbc01944 | 580 | * @return boolean |
581 | */ | |
be85f7ab | 582 | public static function check_capability($contextid, $instance) { |
e35194be | 583 | $context = get_context_instance_by_id($contextid); |
be85f7ab DC |
584 | $capability = has_capability('repository/'.$instance->type.':view', $context); |
585 | if (!$capability) { | |
586 | throw new repository_exception('nopermissiontoaccess', 'repository'); | |
dbc01944 | 587 | } |
dbc01944 | 588 | } |
589 | ||
f392caba DC |
590 | /** |
591 | * Check if file already exists in draft area | |
592 | * | |
593 | * @param int $itemid | |
594 | * @param string $filepath | |
595 | * @param string $filename | |
596 | * @return boolean | |
597 | */ | |
598 | public static function draftfile_exists($itemid, $filepath, $filename) { | |
599 | global $USER; | |
600 | $fs = get_file_storage(); | |
601 | $usercontext = get_context_instance(CONTEXT_USER, $USER->id); | |
602 | if ($fs->get_file($usercontext->id, 'user', 'draft', $itemid, $filepath, $filename)) { | |
603 | return true; | |
604 | } else { | |
605 | return false; | |
606 | } | |
607 | } | |
608 | ||
609 | /** | |
610 | * Does this repository used to browse moodle files? | |
611 | * | |
612 | * @return boolean | |
613 | */ | |
614 | public function has_moodle_files() { | |
615 | return false; | |
616 | } | |
617 | /** | |
618 | * This function is used to copy a moodle file to draft area | |
619 | * | |
620 | * @global object $USER | |
621 | * @global object $DB | |
622 | * @param string $encoded The metainfo of file, it is base64 encoded php serialized data | |
623 | * @param string $draftitemid itemid | |
624 | * @param string $new_filename The intended name of file | |
625 | * @param string $new_filepath the new path in draft area | |
626 | * @return array The information of file | |
627 | */ | |
628 | public function copy_to_area($encoded, $draftitemid, $new_filepath, $new_filename) { | |
629 | global $USER, $DB; | |
630 | ||
631 | if ($this->has_moodle_files() == false) { | |
632 | throw new coding_exception('Only repository used to browse moodle files can use copy_to_area'); | |
633 | } | |
634 | ||
635 | $browser = get_file_browser(); | |
636 | $params = unserialize(base64_decode($encoded)); | |
637 | $user_context = get_context_instance(CONTEXT_USER, $USER->id); | |
638 | ||
639 | $contextid = clean_param($params['contextid'], PARAM_INT); | |
640 | $fileitemid = clean_param($params['itemid'], PARAM_INT); | |
641 | $filename = clean_param($params['filename'], PARAM_FILE); | |
642 | $filepath = clean_param($params['filepath'], PARAM_PATH);; | |
643 | $filearea = clean_param($params['filearea'], PARAM_ALPHAEXT); | |
644 | $component = clean_param($params['component'], PARAM_ALPHAEXT); | |
645 | ||
646 | $context = get_context_instance_by_id($contextid); | |
647 | // the file needs to copied to draft area | |
648 | $file_info = $browser->get_file_info($context, $component, $filearea, $fileitemid, $filepath, $filename); | |
649 | ||
650 | if (repository::draftfile_exists($draftitemid, $new_filepath, $new_filename)) { | |
651 | // create new file | |
652 | $unused_filename = repository::get_unused_filename($draftitemid, $new_filepath, $new_filename); | |
653 | $file_info->copy_to_storage($user_context->id, 'user', 'draft', $draftitemid, $new_filepath, $unused_filename); | |
654 | $event = array(); | |
655 | $event['event'] = 'fileexists'; | |
656 | $event['newfile'] = new stdClass; | |
657 | $event['newfile']->filepath = $new_filepath; | |
658 | $event['newfile']->filename = $unused_filename; | |
659 | $event['newfile']->url = moodle_url::make_draftfile_url($draftitemid, $new_filepath, $unused_filename)->out(); | |
660 | $event['existingfile'] = new stdClass; | |
661 | $event['existingfile']->filepath = $new_filepath; | |
662 | $event['existingfile']->filename = $new_filename; | |
663 | $event['existingfile']->url = moodle_url::make_draftfile_url($draftitemid, $filepath, $filename)->out();; | |
664 | return $event; | |
665 | } else { | |
666 | $file_info->copy_to_storage($user_context->id, 'user', 'draft', $draftitemid, $new_filepath, $new_filename); | |
667 | $info = array(); | |
668 | $info['itemid'] = $draftitemid; | |
669 | $info['title'] = $new_filename; | |
670 | $info['contextid'] = $user_context->id; | |
671 | $info['url'] = moodle_url::make_draftfile_url($draftitemid, $new_filepath, $new_filename)->out();; | |
672 | $info['filesize'] = $file_info->get_filesize(); | |
673 | return $info; | |
674 | } | |
675 | } | |
676 | ||
677 | /** | |
678 | * Get unused filename by appending suffix | |
679 | * | |
680 | * @param int $itemid | |
681 | * @param string $filepath | |
682 | * @param string $filename | |
683 | * @return string | |
684 | */ | |
685 | public static function get_unused_filename($itemid, $filepath, $filename) { | |
686 | global $USER; | |
687 | $fs = get_file_storage(); | |
688 | while (repository::draftfile_exists($itemid, $filepath, $filename)) { | |
689 | $filename = repository::append_suffix($filename); | |
690 | } | |
691 | return $filename; | |
692 | } | |
693 | ||
694 | /** | |
695 | * Append a suffix to filename | |
696 | * | |
697 | * @param string $filename | |
698 | * @return string | |
699 | */ | |
700 | function append_suffix($filename) { | |
701 | $pathinfo = pathinfo($filename); | |
702 | if (empty($pathinfo['extension'])) { | |
703 | return $filename . RENAME_SUFFIX; | |
704 | } else { | |
705 | return $pathinfo['filename'] . RENAME_SUFFIX . '.' . $pathinfo['extension']; | |
706 | } | |
707 | } | |
708 | ||
dbc01944 | 709 | /** |
710 | * Return all types that you a user can create/edit and which are also visible | |
711 | * Note: Mostly used in order to know if at least one editable type can be set | |
712 | * @param object $context the context for which we want the editable types | |
713 | * @return array types | |
714 | */ | |
715 | public static function get_editable_types($context = null) { | |
716 | ||
717 | if (empty($context)) { | |
718 | $context = get_system_context(); | |
719 | } | |
720 | ||
721 | $types= repository::get_types(true); | |
722 | $editabletypes = array(); | |
723 | foreach ($types as $type) { | |
724 | $instanceoptionnames = repository::static_function($type->get_typename(), 'get_instance_option_names'); | |
725 | if (!empty($instanceoptionnames)) { | |
5363905a | 726 | if ($type->get_contextvisibility($context)) { |
dbc01944 | 727 | $editabletypes[]=$type; |
728 | } | |
729 | } | |
730 | } | |
731 | return $editabletypes; | |
732 | } | |
733 | ||
734 | /** | |
735 | * Return repository instances | |
736 | * @global object $DB | |
737 | * @global object $CFG | |
738 | * @global object $USER | |
92a89068 PL |
739 | * |
740 | * @param array $args Array containing the following keys: | |
741 | * currentcontext | |
742 | * context | |
743 | * onlyvisible | |
744 | * type | |
745 | * accepted_types | |
8e0946bf | 746 | * return_types |
92a89068 PL |
747 | * userid |
748 | * | |
dbc01944 | 749 | * @return array repository instances |
750 | */ | |
6f2cd52a | 751 | public static function get_instances($args = array()) { |
dbc01944 | 752 | global $DB, $CFG, $USER; |
753 | ||
6f2cd52a DC |
754 | if (isset($args['currentcontext'])) { |
755 | $current_context = $args['currentcontext']; | |
756 | } else { | |
757 | $current_context = null; | |
758 | } | |
759 | ||
760 | if (!empty($args['context'])) { | |
761 | $contexts = $args['context']; | |
762 | } else { | |
763 | $contexts = array(); | |
764 | } | |
765 | ||
766 | $onlyvisible = isset($args['onlyvisible']) ? $args['onlyvisible'] : true; | |
e35194be | 767 | $returntypes = isset($args['return_types']) ? $args['return_types'] : 3; |
6f2cd52a | 768 | $type = isset($args['type']) ? $args['type'] : null; |
6f2cd52a | 769 | |
dbc01944 | 770 | $params = array(); |
a090554a PS |
771 | $sql = "SELECT i.*, r.type AS repositorytype, r.sortorder, r.visible |
772 | FROM {repository} r, {repository_instances} i | |
773 | WHERE i.typeid = r.id "; | |
dbc01944 | 774 | |
227dfa43 | 775 | if (!empty($args['disable_types']) && is_array($args['disable_types'])) { |
cf717dc2 | 776 | list($types, $p) = $DB->get_in_or_equal($args['disable_types'], SQL_PARAMS_QM, 'param', false); |
a090554a | 777 | $sql .= " AND r.type $types"; |
227dfa43 DC |
778 | $params = array_merge($params, $p); |
779 | } | |
780 | ||
6f2cd52a | 781 | if (!empty($args['userid']) && is_numeric($args['userid'])) { |
a090554a | 782 | $sql .= " AND (i.userid = 0 or i.userid = ?)"; |
6f2cd52a | 783 | $params[] = $args['userid']; |
dbc01944 | 784 | } |
227dfa43 | 785 | |
dbc01944 | 786 | foreach ($contexts as $context) { |
787 | if (empty($firstcontext)) { | |
788 | $firstcontext = true; | |
a090554a | 789 | $sql .= " AND ((i.contextid = ?)"; |
dbc01944 | 790 | } else { |
a090554a | 791 | $sql .= " OR (i.contextid = ?)"; |
dbc01944 | 792 | } |
793 | $params[] = $context->id; | |
794 | } | |
795 | ||
796 | if (!empty($firstcontext)) { | |
797 | $sql .=')'; | |
798 | } | |
799 | ||
800 | if ($onlyvisible == true) { | |
a090554a | 801 | $sql .= " AND (r.visible = 1)"; |
dbc01944 | 802 | } |
803 | ||
804 | if (isset($type)) { | |
a090554a | 805 | $sql .= " AND (r.type = ?)"; |
dbc01944 | 806 | $params[] = $type; |
807 | } | |
a090554a | 808 | $sql .= " ORDER BY r.sortorder, i.name"; |
50a5cf09 | 809 | |
6f2cd52a DC |
810 | if (!$records = $DB->get_records_sql($sql, $params)) { |
811 | $records = array(); | |
dbc01944 | 812 | } |
813 | ||
6f2cd52a | 814 | $repositories = array(); |
99eaca9d | 815 | $ft = new filetype_parser(); |
1e0b0415 DC |
816 | if (isset($args['accepted_types'])) { |
817 | $accepted_types = $args['accepted_types']; | |
818 | } else { | |
819 | $accepted_types = '*'; | |
820 | } | |
6f2cd52a | 821 | foreach ($records as $record) { |
e35194be | 822 | if (!file_exists($CFG->dirroot . '/repository/'. $record->repositorytype.'/lib.php')) { |
062d21cd DC |
823 | continue; |
824 | } | |
e35194be | 825 | require_once($CFG->dirroot . '/repository/'. $record->repositorytype.'/lib.php'); |
6f2cd52a | 826 | $options['visible'] = $record->visible; |
6f2cd52a DC |
827 | $options['type'] = $record->repositorytype; |
828 | $options['typeid'] = $record->typeid; | |
c167aa26 | 829 | // tell instance what file types will be accepted by file picker |
6f2cd52a DC |
830 | $classname = 'repository_' . $record->repositorytype; |
831 | ||
832 | $repository = new $classname($record->id, $record->contextid, $options, $record->readonly); | |
833 | ||
014c1ca0 | 834 | $is_supported = true; |
dbc01944 | 835 | |
271bd2e0 | 836 | if (empty($repository->super_called)) { |
6f2cd52a DC |
837 | // to make sure the super construct is called |
838 | debugging('parent::__construct must be called by '.$record->repositorytype.' plugin.'); | |
271bd2e0 | 839 | } else { |
6f2cd52a | 840 | // check mimetypes |
99eaca9d DC |
841 | if ($accepted_types !== '*' and $repository->supported_filetypes() !== '*') { |
842 | $accepted_types = $ft->get_extensions($accepted_types); | |
843 | $supported_filetypes = $ft->get_extensions($repository->supported_filetypes()); | |
6f2cd52a | 844 | |
271bd2e0 | 845 | $is_supported = false; |
846 | foreach ($supported_filetypes as $type) { | |
99eaca9d | 847 | if (in_array($type, $accepted_types)) { |
271bd2e0 | 848 | $is_supported = true; |
849 | } | |
014c1ca0 | 850 | } |
6f2cd52a | 851 | |
014c1ca0 | 852 | } |
6f2cd52a | 853 | // check return values |
41076c58 DC |
854 | if ($returntypes !== 3 and $repository->supported_returntypes() !== 3) { |
855 | $type = $repository->supported_returntypes(); | |
856 | if ($type & $returntypes) { | |
857 | // | |
858 | } else { | |
859 | $is_supported = false; | |
271bd2e0 | 860 | } |
014c1ca0 | 861 | } |
d3959c26 | 862 | |
271bd2e0 | 863 | if (!$onlyvisible || ($repository->is_visible() && !$repository->disabled)) { |
6f2cd52a DC |
864 | // check capability in current context |
865 | if (!empty($current_context)) { | |
866 | $capability = has_capability('repository/'.$record->repositorytype.':view', $current_context); | |
867 | } else { | |
6f2cd52a DC |
868 | $capability = has_capability('repository/'.$record->repositorytype.':view', get_system_context()); |
869 | } | |
d3959c26 DC |
870 | if ($record->repositorytype == 'coursefiles') { |
871 | // coursefiles plugin needs managefiles permission | |
872 | $capability = $capability && has_capability('moodle/course:managefiles', $current_context); | |
873 | } | |
c86dde2e | 874 | if ($is_supported && $capability) { |
99eaca9d | 875 | $repositories[$repository->id] = $repository; |
271bd2e0 | 876 | } |
014c1ca0 | 877 | } |
dbc01944 | 878 | } |
879 | } | |
6f2cd52a | 880 | return $repositories; |
dbc01944 | 881 | } |
882 | ||
883 | /** | |
884 | * Get single repository instance | |
885 | * @global object $DB | |
886 | * @global object $CFG | |
887 | * @param integer $id repository id | |
888 | * @return object repository instance | |
889 | */ | |
890 | public static function get_instance($id) { | |
891 | global $DB, $CFG; | |
a090554a PS |
892 | $sql = "SELECT i.*, r.type AS repositorytype, r.visible |
893 | FROM {repository} r | |
894 | JOIN {repository_instances} i ON i.typeid = r.id | |
895 | WHERE i.id = ?"; | |
dbc01944 | 896 | |
a090554a | 897 | if (!$instance = $DB->get_record_sql($sql, array($id))) { |
dbc01944 | 898 | return false; |
899 | } | |
e35194be | 900 | require_once($CFG->dirroot . '/repository/'. $instance->repositorytype.'/lib.php'); |
dbc01944 | 901 | $classname = 'repository_' . $instance->repositorytype; |
902 | $options['typeid'] = $instance->typeid; | |
903 | $options['type'] = $instance->repositorytype; | |
904 | $options['name'] = $instance->name; | |
271bd2e0 | 905 | $obj = new $classname($instance->id, $instance->contextid, $options, $instance->readonly); |
906 | if (empty($obj->super_called)) { | |
907 | debugging('parent::__construct must be called by '.$classname.' plugin.'); | |
908 | } | |
909 | return $obj; | |
dbc01944 | 910 | } |
911 | ||
912 | /** | |
e35194be | 913 | * Call a static function. Any additional arguments than plugin and function will be passed through. |
2b8beee3 | 914 | * @global object $CFG |
915 | * @param string $plugin | |
916 | * @param string $function | |
2b8beee3 | 917 | * @return mixed |
dbc01944 | 918 | */ |
919 | public static function static_function($plugin, $function) { | |
920 | global $CFG; | |
921 | ||
922 | //check that the plugin exists | |
e35194be | 923 | $typedirectory = $CFG->dirroot . '/repository/'. $plugin . '/lib.php'; |
dbc01944 | 924 | if (!file_exists($typedirectory)) { |
f1cfe56e | 925 | //throw new repository_exception('invalidplugin', 'repository'); |
926 | return false; | |
dbc01944 | 927 | } |
928 | ||
929 | $pname = null; | |
930 | if (is_object($plugin) || is_array($plugin)) { | |
931 | $plugin = (object)$plugin; | |
932 | $pname = $plugin->name; | |
933 | } else { | |
934 | $pname = $plugin; | |
935 | } | |
936 | ||
937 | $args = func_get_args(); | |
938 | if (count($args) <= 2) { | |
939 | $args = array(); | |
e35194be | 940 | } else { |
dbc01944 | 941 | array_shift($args); |
942 | array_shift($args); | |
943 | } | |
944 | ||
945 | require_once($typedirectory); | |
81bdfdb9 | 946 | return call_user_func_array(array('repository_' . $plugin, $function), $args); |
dbc01944 | 947 | } |
948 | ||
23bfe0a4 PS |
949 | /** |
950 | * Scan file, throws exception in case of infected file. | |
951 | * | |
952 | * Please note that the scanning engine must be able to access the file, | |
953 | * permissions of the file are not modified here! | |
954 | * | |
955 | * @static | |
956 | * @param string $thefile | |
957 | * @param string $filename name of the file | |
958 | * @param bool $deleteinfected | |
959 | * @return void | |
960 | */ | |
961 | public static function antivir_scan_file($thefile, $filename, $deleteinfected) { | |
962 | global $CFG; | |
963 | ||
964 | if (!is_readable($thefile)) { | |
965 | // this should not happen | |
966 | return; | |
967 | } | |
968 | ||
969 | if (empty($CFG->runclamonupload) or empty($CFG->pathtoclam)) { | |
970 | // clam not enabled | |
971 | return; | |
972 | } | |
973 | ||
974 | $CFG->pathtoclam = trim($CFG->pathtoclam); | |
975 | ||
976 | if (!file_exists($CFG->pathtoclam) or !is_executable($CFG->pathtoclam)) { | |
977 | // misconfigured clam - use the old notification for now | |
978 | require("$CFG->libdir/uploadlib.php"); | |
979 | $notice = get_string('clamlost', 'moodle', $CFG->pathtoclam); | |
980 | clam_message_admins($notice); | |
981 | return; | |
982 | } | |
983 | ||
984 | // do NOT mess with permissions here, the calling party is responsible for making | |
985 | // sure the scanner engine can access the files! | |
986 | ||
987 | // execute test | |
988 | $cmd = escapeshellcmd($CFG->pathtoclam).' --stdout '.escapeshellarg($thefile); | |
989 | exec($cmd, $output, $return); | |
990 | ||
991 | if ($return == 0) { | |
992 | // perfect, no problem found | |
993 | return; | |
994 | ||
995 | } else if ($return == 1) { | |
996 | // infection found | |
997 | if ($deleteinfected) { | |
998 | unlink($thefile); | |
999 | } | |
1000 | throw new moodle_exception('virusfounduser', 'moodle', '', array('filename'=>$filename)); | |
1001 | ||
1002 | } else { | |
1003 | //unknown problem | |
1004 | require("$CFG->libdir/uploadlib.php"); | |
1005 | $notice = get_string('clamfailed', 'moodle', get_clam_error_code($return)); | |
1006 | $notice .= "\n\n". implode("\n", $output); | |
1007 | clam_message_admins($notice); | |
1008 | if ($CFG->clamfailureonupload === 'actlikevirus') { | |
1009 | if ($deleteinfected) { | |
1010 | unlink($thefile); | |
1011 | } | |
1012 | throw new moodle_exception('virusfounduser', 'moodle', '', array('filename'=>$filename)); | |
1013 | } else { | |
1014 | return; | |
1015 | } | |
1016 | } | |
1017 | } | |
1018 | ||
dbc01944 | 1019 | /** |
1020 | * Move file from download folder to file pool using FILE API | |
1021 | * @global object $DB | |
1022 | * @global object $CFG | |
1023 | * @global object $USER | |
1a6195b4 | 1024 | * @global object $OUTPUT |
8e0946bf | 1025 | * @param string $thefile file path in download folder |
50dea1b7 | 1026 | * @param object $record |
1a6195b4 DC |
1027 | * @return array containing the following keys: |
1028 | * icon | |
1029 | * file | |
1030 | * id | |
1031 | * url | |
dbc01944 | 1032 | */ |
14469892 | 1033 | public static function move_to_filepool($thefile, $record) { |
390baf46 | 1034 | global $DB, $CFG, $USER, $OUTPUT; |
23bfe0a4 PS |
1035 | |
1036 | // scan for viruses if possible, throws exception if problem found | |
1037 | self::antivir_scan_file($thefile, $record->filename, empty($CFG->repository_no_delete)); //TODO: MDL-28637 this repository_no_delete is a bloody hack! | |
1038 | ||
14469892 DC |
1039 | if ($record->filepath !== '/') { |
1040 | $record->filepath = trim($record->filepath, '/'); | |
1041 | $record->filepath = '/'.$record->filepath.'/'; | |
e5fa0e8d | 1042 | } |
dbc01944 | 1043 | $context = get_context_instance(CONTEXT_USER, $USER->id); |
1044 | $now = time(); | |
14469892 DC |
1045 | |
1046 | $record->contextid = $context->id; | |
64f93798 PS |
1047 | $record->component = 'user'; |
1048 | $record->filearea = 'draft'; | |
14469892 DC |
1049 | $record->timecreated = $now; |
1050 | $record->timemodified = $now; | |
1051 | $record->userid = $USER->id; | |
1052 | $record->mimetype = mimeinfo('type', $thefile); | |
1053 | if(!is_numeric($record->itemid)) { | |
1054 | $record->itemid = 0; | |
dbc01944 | 1055 | } |
dbc01944 | 1056 | $fs = get_file_storage(); |
64f93798 | 1057 | if ($existingfile = $fs->get_file($context->id, $record->component, $record->filearea, $record->itemid, $record->filepath, $record->filename)) { |
f392caba DC |
1058 | $draftitemid = $record->itemid; |
1059 | $new_filename = repository::get_unused_filename($draftitemid, $record->filepath, $record->filename); | |
1060 | $old_filename = $record->filename; | |
1061 | // create a tmp file | |
1062 | $record->filename = $new_filename; | |
1063 | $newfile = $fs->create_file_from_pathname($record, $thefile); | |
1064 | $event = array(); | |
1065 | $event['event'] = 'fileexists'; | |
1066 | $event['newfile'] = new stdClass; | |
1067 | $event['newfile']->filepath = $record->filepath; | |
1068 | $event['newfile']->filename = $new_filename; | |
1069 | $event['newfile']->url = moodle_url::make_draftfile_url($draftitemid, $record->filepath, $new_filename)->out(); | |
1070 | ||
1071 | $event['existingfile'] = new stdClass; | |
1072 | $event['existingfile']->filepath = $record->filepath; | |
1073 | $event['existingfile']->filename = $old_filename; | |
1074 | $event['existingfile']->url = moodle_url::make_draftfile_url($draftitemid, $record->filepath, $old_filename)->out();; | |
1075 | return $event; | |
b423b4af | 1076 | } |
14469892 | 1077 | if ($file = $fs->create_file_from_pathname($record, $thefile)) { |
88b126a5 | 1078 | if (empty($CFG->repository_no_delete)) { |
99eaca9d | 1079 | $delete = unlink($thefile); |
88b126a5 | 1080 | unset($CFG->repository_no_delete); |
1081 | } | |
64f93798 | 1082 | return array( |
50a8bd6c | 1083 | 'url'=>moodle_url::make_draftfile_url($file->get_itemid(), $file->get_filepath(), $file->get_filename())->out(), |
64f93798 PS |
1084 | 'id'=>$file->get_itemid(), |
1085 | 'file'=>$file->get_filename(), | |
1086 | 'icon' => $OUTPUT->pix_url(file_extension_icon($thefile, 32))->out(), | |
1087 | ); | |
dbc01944 | 1088 | } else { |
1089 | return null; | |
1090 | } | |
1091 | } | |
1092 | ||
dbc01944 | 1093 | /** |
1094 | * Builds a tree of files This function is | |
1095 | * then called recursively. | |
1096 | * | |
1097 | * @param $fileinfo an object returned by file_browser::get_file_info() | |
1098 | * @param $search searched string | |
1099 | * @param $dynamicmode bool no recursive call is done when in dynamic mode | |
1100 | * @param $list - the array containing the files under the passed $fileinfo | |
1101 | * @returns int the number of files found | |
1102 | * | |
1103 | * todo: take $search into account, and respect a threshold for dynamic loading | |
1104 | */ | |
1105 | public static function build_tree($fileinfo, $search, $dynamicmode, &$list) { | |
390baf46 | 1106 | global $CFG, $OUTPUT; |
dbc01944 | 1107 | |
1108 | $filecount = 0; | |
1109 | $children = $fileinfo->get_children(); | |
1110 | ||
1111 | foreach ($children as $child) { | |
1112 | $filename = $child->get_visible_name(); | |
1113 | $filesize = $child->get_filesize(); | |
1114 | $filesize = $filesize ? display_size($filesize) : ''; | |
1115 | $filedate = $child->get_timemodified(); | |
1116 | $filedate = $filedate ? userdate($filedate) : ''; | |
1117 | $filetype = $child->get_mimetype(); | |
1118 | ||
1119 | if ($child->is_directory()) { | |
1120 | $path = array(); | |
1121 | $level = $child->get_parent(); | |
1122 | while ($level) { | |
1123 | $params = $level->get_params(); | |
64f93798 | 1124 | $path[] = array($params['filepath'], $level->get_visible_name()); |
dbc01944 | 1125 | $level = $level->get_parent(); |
1126 | } | |
1127 | ||
1128 | $tmp = array( | |
1129 | 'title' => $child->get_visible_name(), | |
1130 | 'size' => 0, | |
1131 | 'date' => $filedate, | |
1132 | 'path' => array_reverse($path), | |
b5d0cafc | 1133 | 'thumbnail' => $OUTPUT->pix_url('f/folder-32') |
dbc01944 | 1134 | ); |
1135 | ||
1136 | //if ($dynamicmode && $child->is_writable()) { | |
1137 | // $tmp['children'] = array(); | |
1138 | //} else { | |
1139 | // if folder name matches search, we send back all files contained. | |
1140 | $_search = $search; | |
1141 | if ($search && stristr($tmp['title'], $search) !== false) { | |
1142 | $_search = false; | |
1143 | } | |
1144 | $tmp['children'] = array(); | |
1145 | $_filecount = repository::build_tree($child, $_search, $dynamicmode, $tmp['children']); | |
1146 | if ($search && $_filecount) { | |
1147 | $tmp['expanded'] = 1; | |
1148 | } | |
1149 | ||
1150 | //} | |
1151 | ||
fc3ec2ca | 1152 | if (!$search || $_filecount || (stristr($tmp['title'], $search) !== false)) { |
dbc01944 | 1153 | $filecount += $_filecount; |
1154 | $list[] = $tmp; | |
1155 | } | |
1156 | ||
1157 | } else { // not a directory | |
1158 | // skip the file, if we're in search mode and it's not a match | |
1159 | if ($search && (stristr($filename, $search) === false)) { | |
1160 | continue; | |
1161 | } | |
1162 | $params = $child->get_params(); | |
64f93798 | 1163 | $source = serialize(array($params['contextid'], $params['component'], $params['filearea'], $params['itemid'], $params['filepath'], $params['filename'])); |
dbc01944 | 1164 | $list[] = array( |
1165 | 'title' => $filename, | |
1166 | 'size' => $filesize, | |
1167 | 'date' => $filedate, | |
1168 | //'source' => $child->get_url(), | |
1169 | 'source' => base64_encode($source), | |
b5d0cafc | 1170 | 'thumbnail'=>$OUTPUT->pix_url(file_extension_icon($filename, 32)), |
dbc01944 | 1171 | ); |
1172 | $filecount++; | |
1173 | } | |
1174 | } | |
1175 | ||
1176 | return $filecount; | |
1177 | } | |
1178 | ||
1179 | ||
1180 | /** | |
1181 | * Display a repository instance list (with edit/delete/create links) | |
1182 | * @global object $CFG | |
1183 | * @global object $USER | |
8e0946bf | 1184 | * @global object $OUTPUT |
dbc01944 | 1185 | * @param object $context the context for which we display the instance |
1186 | * @param string $typename if set, we display only one type of instance | |
1187 | */ | |
1188 | public static function display_instances_list($context, $typename = null) { | |
50a5cf09 | 1189 | global $CFG, $USER, $OUTPUT; |
dbc01944 | 1190 | |
50a5cf09 | 1191 | $output = $OUTPUT->box_start('generalbox'); |
dbc01944 | 1192 | //if the context is SYSTEM, so we call it from administration page |
1193 | $admin = ($context->id == SYSCONTEXTID) ? true : false; | |
1194 | if ($admin) { | |
e35194be DC |
1195 | $baseurl = new moodle_url('/'.$CFG->admin.'/repositoryinstance.php', array('sesskey'=>sesskey())); |
1196 | $output .= $OUTPUT->heading(get_string('siteinstances', 'repository')); | |
dbc01944 | 1197 | } else { |
e35194be | 1198 | $baseurl = new moodle_url('/repository/manage_instances.php', array('contextid'=>$context->id, 'sesskey'=>sesskey())); |
dbc01944 | 1199 | } |
e35194be | 1200 | $url = $baseurl; |
dbc01944 | 1201 | |
1202 | $namestr = get_string('name'); | |
1203 | $pluginstr = get_string('plugin', 'repository'); | |
1204 | $settingsstr = get_string('settings'); | |
1205 | $deletestr = get_string('delete'); | |
dbc01944 | 1206 | //retrieve list of instances. In administration context we want to display all |
1207 | //instances of a type, even if this type is not visible. In course/user context we | |
92eaeca5 | 1208 | //want to display only visible instances, but for every type types. The repository::get_instances() |
dbc01944 | 1209 | //third parameter displays only visible type. |
6f2cd52a DC |
1210 | $params = array(); |
1211 | $params['context'] = array($context, get_system_context()); | |
1212 | $params['currentcontext'] = $context; | |
1213 | $params['onlyvisible'] = !$admin; | |
1214 | $params['type'] = $typename; | |
1215 | $instances = repository::get_instances($params); | |
dbc01944 | 1216 | $instancesnumber = count($instances); |
1217 | $alreadyplugins = array(); | |
1218 | ||
55400db0 | 1219 | $table = new html_table(); |
79698344 | 1220 | $table->head = array($namestr, $pluginstr, $settingsstr, $deletestr); |
dbc01944 | 1221 | $table->align = array('left', 'left', 'center','center'); |
1222 | $table->data = array(); | |
1223 | ||
1224 | $updowncount = 1; | |
1225 | ||
1226 | foreach ($instances as $i) { | |
1227 | $settings = ''; | |
1228 | $delete = ''; | |
5363905a DC |
1229 | |
1230 | $type = repository::get_type_by_id($i->options['typeid']); | |
1231 | ||
1232 | if ($type->get_contextvisibility($context)) { | |
1233 | if (!$i->readonly) { | |
1234 | ||
1235 | $url->param('type', $i->options['type']); | |
1236 | $url->param('edit', $i->id); | |
0f4c64b7 | 1237 | $settings .= html_writer::link($url, $settingsstr); |
5363905a DC |
1238 | |
1239 | $url->remove_params('edit'); | |
1240 | $url->param('delete', $i->id); | |
0f4c64b7 | 1241 | $delete .= html_writer::link($url, $deletestr); |
5363905a DC |
1242 | |
1243 | $url->remove_params('type'); | |
1244 | } | |
dbc01944 | 1245 | } |
1246 | ||
a3d8df25 | 1247 | $type = repository::get_type_by_id($i->options['typeid']); |
79698344 | 1248 | $table->data[] = array($i->name, $type->get_readablename(), $settings, $delete); |
dbc01944 | 1249 | |
1250 | //display a grey row if the type is defined as not visible | |
1251 | if (isset($type) && !$type->get_visible()) { | |
704ac344 | 1252 | $table->rowclasses[] = 'dimmed_text'; |
dbc01944 | 1253 | } else { |
704ac344 | 1254 | $table->rowclasses[] = ''; |
dbc01944 | 1255 | } |
1256 | ||
1257 | if (!in_array($i->name, $alreadyplugins)) { | |
1258 | $alreadyplugins[] = $i->name; | |
1259 | } | |
1260 | } | |
16be8974 | 1261 | $output .= html_writer::table($table); |
dbc01944 | 1262 | $instancehtml = '<div>'; |
1263 | $addable = 0; | |
1264 | ||
1265 | //if no type is set, we can create all type of instance | |
1266 | if (!$typename) { | |
1267 | $instancehtml .= '<h3>'; | |
1268 | $instancehtml .= get_string('createrepository', 'repository'); | |
1269 | $instancehtml .= '</h3><ul>'; | |
1270 | $types = repository::get_editable_types($context); | |
1271 | foreach ($types as $type) { | |
1272 | if (!empty($type) && $type->get_visible()) { | |
1273 | $instanceoptionnames = repository::static_function($type->get_typename(), 'get_instance_option_names'); | |
1274 | if (!empty($instanceoptionnames)) { | |
e35194be DC |
1275 | $baseurl->param('new', $type->get_typename()); |
1276 | $instancehtml .= '<li><a href="'.$baseurl->out().'">'.get_string('createxxinstance', 'repository', get_string('pluginname', 'repository_'.$type->get_typename())). '</a></li>'; | |
1277 | $baseurl->remove_params('new'); | |
dbc01944 | 1278 | $addable++; |
1279 | } | |
1280 | } | |
1281 | } | |
1282 | $instancehtml .= '</ul>'; | |
1283 | ||
1284 | } else { | |
1285 | $instanceoptionnames = repository::static_function($typename, 'get_instance_option_names'); | |
1286 | if (!empty($instanceoptionnames)) { //create a unique type of instance | |
1287 | $addable = 1; | |
e35194be DC |
1288 | $baseurl->param('new', $typename); |
1289 | $instancehtml .= "<form action='".$baseurl->out()."' method='post'> | |
1290 | <p><input type='submit' value='".get_string('createinstance', 'repository')."'/></p> | |
dbc01944 | 1291 | </form>"; |
e35194be | 1292 | $baseurl->remove_params('new'); |
dbc01944 | 1293 | } |
1294 | } | |
1295 | ||
1296 | if ($addable) { | |
1297 | $instancehtml .= '</div>'; | |
1298 | $output .= $instancehtml; | |
1299 | } | |
1300 | ||
50a5cf09 | 1301 | $output .= $OUTPUT->box_end(); |
dbc01944 | 1302 | |
1303 | //print the list + creation links | |
1304 | print($output); | |
1305 | } | |
1cf56396 | 1306 | |
c425472d | 1307 | /** |
e35194be | 1308 | * Decide where to save the file, can be overwriten by subclass |
a53d4f45 | 1309 | * @param string filename |
c425472d | 1310 | */ |
a560785f | 1311 | public function prepare_file($filename) { |
c425472d | 1312 | global $CFG; |
7aa06e6d TL |
1313 | if (!file_exists($CFG->tempdir.'/download')) { |
1314 | mkdir($CFG->tempdir.'/download/', $CFG->directorypermissions, true); | |
1e28c767 | 1315 | } |
7aa06e6d TL |
1316 | if (is_dir($CFG->tempdir.'/download')) { |
1317 | $dir = $CFG->tempdir.'/download/'; | |
1e28c767 | 1318 | } |
a560785f | 1319 | if (empty($filename)) { |
cedc3d33 | 1320 | $filename = uniqid('repo', true).'_'.time().'.tmp'; |
84df43de | 1321 | } |
a560785f | 1322 | if (file_exists($dir.$filename)) { |
1323 | $filename = uniqid('m').$filename; | |
c425472d | 1324 | } |
a560785f | 1325 | return $dir.$filename; |
a53d4f45 | 1326 | } |
1327 | ||
99d52655 DC |
1328 | /** |
1329 | * Return file URL, for most plugins, the parameter is the original | |
1330 | * url, but some plugins use a file id, so we need this function to | |
1331 | * convert file id to original url. | |
1332 | * | |
1333 | * @param string $url the url of file | |
8e0946bf | 1334 | * @return string |
99d52655 DC |
1335 | */ |
1336 | public function get_link($url) { | |
1337 | return $url; | |
1338 | } | |
1339 | ||
a53d4f45 | 1340 | /** |
1341 | * Download a file, this function can be overridden by | |
1342 | * subclass. | |
1343 | * | |
1344 | * @global object $CFG | |
1345 | * @param string $url the url of file | |
a560785f | 1346 | * @param string $filename save location |
a53d4f45 | 1347 | * @return string the location of the file |
1348 | * @see curl package | |
1349 | */ | |
a560785f | 1350 | public function get_file($url, $filename = '') { |
a53d4f45 | 1351 | global $CFG; |
41076c58 DC |
1352 | $path = $this->prepare_file($filename); |
1353 | $fp = fopen($path, 'w'); | |
1354 | $c = new curl; | |
1355 | $c->download(array(array('url'=>$url, 'file'=>$fp))); | |
1dce6261 | 1356 | return array('path'=>$path, 'url'=>$url); |
82669dc4 | 1357 | } |
1cf56396 | 1358 | |
c0d60b3a AKA |
1359 | /** |
1360 | * Return size of a file in bytes. | |
1361 | * | |
1362 | * @param string $source encoded and serialized data of file | |
1363 | * @return integer file size in bytes | |
1364 | */ | |
1365 | public function get_file_size($source) { | |
1366 | $browser = get_file_browser(); | |
1367 | $params = unserialize(base64_decode($source)); | |
1368 | $contextid = clean_param($params['contextid'], PARAM_INT); | |
1369 | $fileitemid = clean_param($params['itemid'], PARAM_INT); | |
1370 | $filename = clean_param($params['filename'], PARAM_FILE); | |
1371 | $filepath = clean_param($params['filepath'], PARAM_PATH); | |
1372 | $filearea = clean_param($params['filearea'], PARAM_SAFEDIR); | |
1373 | $component = clean_param($params['component'], PARAM_ALPHAEXT); | |
1374 | $context = get_context_instance_by_id($contextid); | |
1375 | $file_info = $browser->get_file_info($context, $component, $filearea, $fileitemid, $filepath, $filename); | |
1376 | if (!empty($file_info)) { | |
1377 | $filesize = $file_info->get_filesize(); | |
1378 | } else { | |
1379 | $filesize = null; | |
1380 | } | |
1381 | return $filesize; | |
1382 | } | |
1383 | ||
f48fb4d6 | 1384 | /** |
1385 | * Return is the instance is visible | |
1386 | * (is the type visible ? is the context enable ?) | |
1387 | * @return boolean | |
1388 | */ | |
dbc01944 | 1389 | public function is_visible() { |
7d554b64 | 1390 | $type = repository::get_type_by_id($this->options['typeid']); |
dbc01944 | 1391 | $instanceoptions = repository::static_function($type->get_typename(), 'get_instance_option_names'); |
f48fb4d6 | 1392 | |
1393 | if ($type->get_visible()) { | |
1394 | //if the instance is unique so it's visible, otherwise check if the instance has a enabled context | |
5363905a | 1395 | if (empty($instanceoptions) || $type->get_contextvisibility($this->context)) { |
f48fb4d6 | 1396 | return true; |
1397 | } | |
1398 | } | |
1399 | ||
1400 | return false; | |
1401 | } | |
1402 | ||
eb239694 | 1403 | /** |
66dc47bc | 1404 | * Return the name of this instance, can be overridden. |
2b8beee3 | 1405 | * @global object $DB |
1406 | * @return string | |
eb239694 | 1407 | */ |
7a3b93c1 | 1408 | public function get_name() { |
d31af46a | 1409 | global $DB; |
a5adfa26 DC |
1410 | if ( $name = $this->instance->name ) { |
1411 | return $name; | |
d31af46a | 1412 | } else { |
a5adfa26 | 1413 | return get_string('pluginname', 'repository_' . $this->options['type']); |
d31af46a | 1414 | } |
1415 | } | |
aa754fe3 | 1416 | |
b318bb6d | 1417 | /** |
1418 | * what kind of files will be in this repository? | |
1419 | * @return array return '*' means this repository support any files, otherwise | |
1420 | * return mimetypes of files, it can be an array | |
1421 | */ | |
014c1ca0 | 1422 | public function supported_filetypes() { |
b318bb6d | 1423 | // return array('text/plain', 'image/gif'); |
1424 | return '*'; | |
1425 | } | |
1426 | ||
1427 | /** | |
1428 | * does it return a file url or a item_id | |
1429 | * @return string | |
1430 | */ | |
41076c58 DC |
1431 | public function supported_returntypes() { |
1432 | return (FILE_INTERNAL | FILE_EXTERNAL); | |
92eaeca5 | 1433 | } |
b318bb6d | 1434 | |
82669dc4 | 1435 | /** |
3f24ea1e | 1436 | * Provide repository instance information for Ajax |
8dcd5deb | 1437 | * @global object $CFG |
4a65c39a | 1438 | * @return object |
82669dc4 | 1439 | */ |
7d554b64 | 1440 | final public function get_meta() { |
c82d7320 | 1441 | global $CFG, $OUTPUT; |
99eaca9d | 1442 | $ft = new filetype_parser; |
6bdfef5d | 1443 | $meta = new stdClass(); |
7d554b64 | 1444 | $meta->id = $this->id; |
1445 | $meta->name = $this->get_name(); | |
1446 | $meta->type = $this->options['type']; | |
c82d7320 | 1447 | $meta->icon = $OUTPUT->pix_url('icon', 'repository_'.$meta->type)->out(false); |
99eaca9d | 1448 | $meta->supported_types = $ft->get_extensions($this->supported_filetypes()); |
6f2cd52a | 1449 | $meta->return_types = $this->supported_returntypes(); |
7d554b64 | 1450 | return $meta; |
4a65c39a | 1451 | } |
1cf56396 | 1452 | |
b1339e98 | 1453 | /** |
1454 | * Create an instance for this plug-in | |
8dcd5deb | 1455 | * @global object $CFG |
1456 | * @global object $DB | |
1457 | * @param string $type the type of the repository | |
1458 | * @param integer $userid the user id | |
1459 | * @param object $context the context | |
1460 | * @param array $params the options for this instance | |
635f1a8b | 1461 | * @param integer $readonly whether to create it readonly or not (defaults to not) |
2b8beee3 | 1462 | * @return mixed |
b1339e98 | 1463 | */ |
49d20def | 1464 | public static function create($type, $userid, $context, $params, $readonly=0) { |
b1339e98 | 1465 | global $CFG, $DB; |
1466 | $params = (array)$params; | |
e35194be | 1467 | require_once($CFG->dirroot . '/repository/'. $type . '/lib.php'); |
b1339e98 | 1468 | $classname = 'repository_' . $type; |
3023078f | 1469 | if ($repo = $DB->get_record('repository', array('type'=>$type))) { |
6bdfef5d | 1470 | $record = new stdClass(); |
3023078f | 1471 | $record->name = $params['name']; |
1472 | $record->typeid = $repo->id; | |
1473 | $record->timecreated = time(); | |
1474 | $record->timemodified = time(); | |
1475 | $record->contextid = $context->id; | |
948c2860 | 1476 | $record->readonly = $readonly; |
3023078f | 1477 | $record->userid = $userid; |
1478 | $id = $DB->insert_record('repository_instances', $record); | |
0a6221f9 | 1479 | $options = array(); |
edb50637 | 1480 | $configs = call_user_func($classname . '::get_instance_option_names'); |
1e08b5cf | 1481 | if (!empty($configs)) { |
1482 | foreach ($configs as $config) { | |
14b2d8d8 DC |
1483 | if (isset($params[$config])) { |
1484 | $options[$config] = $params[$config]; | |
1485 | } else { | |
1486 | $options[$config] = null; | |
1487 | } | |
1e08b5cf | 1488 | } |
3023078f | 1489 | } |
3a01a46a | 1490 | |
3023078f | 1491 | if (!empty($id)) { |
1492 | unset($options['name']); | |
dbc01944 | 1493 | $instance = repository::get_instance($id); |
3023078f | 1494 | $instance->set_option($options); |
1495 | return $id; | |
1496 | } else { | |
1497 | return null; | |
b1339e98 | 1498 | } |
b1339e98 | 1499 | } else { |
1500 | return null; | |
1501 | } | |
1502 | } | |
8dcd5deb | 1503 | |
82669dc4 | 1504 | /** |
4a65c39a | 1505 | * delete a repository instance |
8dcd5deb | 1506 | * @global object $DB |
2b8beee3 | 1507 | * @return mixed |
82669dc4 | 1508 | */ |
7a3b93c1 | 1509 | final public function delete() { |
4a65c39a | 1510 | global $DB; |
122defc5 | 1511 | $DB->delete_records('repository_instances', array('id'=>$this->id)); |
2b0b3626 | 1512 | $DB->delete_records('repository_instance_config', array('instanceid'=>$this->id)); |
4a65c39a | 1513 | return true; |
1514 | } | |
8dcd5deb | 1515 | |
4a65c39a | 1516 | /** |
1517 | * Hide/Show a repository | |
8dcd5deb | 1518 | * @global object $DB |
1519 | * @param string $hide | |
2b8beee3 | 1520 | * @return boolean |
4a65c39a | 1521 | */ |
7a3b93c1 | 1522 | final public function hide($hide = 'toggle') { |
4a65c39a | 1523 | global $DB; |
1524 | if ($entry = $DB->get_record('repository', array('id'=>$this->id))) { | |
1525 | if ($hide === 'toggle' ) { | |
1526 | if (!empty($entry->visible)) { | |
1527 | $entry->visible = 0; | |
1528 | } else { | |
1529 | $entry->visible = 1; | |
1530 | } | |
1531 | } else { | |
1532 | if (!empty($hide)) { | |
1533 | $entry->visible = 0; | |
1534 | } else { | |
1535 | $entry->visible = 1; | |
1536 | } | |
1537 | } | |
1538 | return $DB->update_record('repository', $entry); | |
1539 | } | |
1540 | return false; | |
1541 | } | |
1cf56396 | 1542 | |
1cf56396 | 1543 | /** |
4a65c39a | 1544 | * Save settings for repository instance |
8dcd5deb | 1545 | * $repo->set_option(array('api_key'=>'f2188bde132', 'name'=>'dongsheng')); |
1546 | * @global object $DB | |
1547 | * @param array $options settings | |
4a65c39a | 1548 | * @return int Id of the record |
1cf56396 | 1549 | */ |
7a3b93c1 | 1550 | public function set_option($options = array()) { |
4a65c39a | 1551 | global $DB; |
7a3b93c1 | 1552 | |
122defc5 | 1553 | if (!empty($options['name'])) { |
a27ab6fd | 1554 | $r = new stdClass(); |
122defc5 | 1555 | $r->id = $this->id; |
1556 | $r->name = $options['name']; | |
1557 | $DB->update_record('repository_instances', $r); | |
1558 | unset($options['name']); | |
1559 | } | |
27051e43 | 1560 | foreach ($options as $name=>$value) { |
1561 | if ($id = $DB->get_field('repository_instance_config', 'id', array('name'=>$name, 'instanceid'=>$this->id))) { | |
f685e830 | 1562 | $DB->set_field('repository_instance_config', 'value', $value, array('id'=>$id)); |
27051e43 | 1563 | } else { |
a27ab6fd | 1564 | $config = new stdClass(); |
27051e43 | 1565 | $config->instanceid = $this->id; |
1566 | $config->name = $name; | |
1567 | $config->value = $value; | |
f685e830 | 1568 | $DB->insert_record('repository_instance_config', $config); |
27051e43 | 1569 | } |
4a65c39a | 1570 | } |
f685e830 | 1571 | return true; |
1cf56396 | 1572 | } |
1cf56396 | 1573 | |
4a65c39a | 1574 | /** |
1575 | * Get settings for repository instance | |
8dcd5deb | 1576 | * @global object $DB |
2b8beee3 | 1577 | * @param string $config |
4a65c39a | 1578 | * @return array Settings |
1579 | */ | |
7a3b93c1 | 1580 | public function get_option($config = '') { |
4a65c39a | 1581 | global $DB; |
27051e43 | 1582 | $entries = $DB->get_records('repository_instance_config', array('instanceid'=>$this->id)); |
1583 | $ret = array(); | |
1584 | if (empty($entries)) { | |
1585 | return $ret; | |
4a65c39a | 1586 | } |
7a3b93c1 | 1587 | foreach($entries as $entry) { |
27051e43 | 1588 | $ret[$entry->name] = $entry->value; |
4a65c39a | 1589 | } |
1590 | if (!empty($config)) { | |
9e6aa5ec | 1591 | if (isset($ret[$config])) { |
75003899 | 1592 | return $ret[$config]; |
9e6aa5ec DC |
1593 | } else { |
1594 | return null; | |
1595 | } | |
4a65c39a | 1596 | } else { |
1597 | return $ret; | |
1598 | } | |
1599 | } | |
bf1fccf0 | 1600 | |
c167aa26 | 1601 | public function filter(&$value) { |
1602 | $pass = false; | |
18bd7573 | 1603 | $accepted_types = optional_param_array('accepted_types', '', PARAM_RAW); |
99eaca9d | 1604 | $ft = new filetype_parser; |
af79a6f5 | 1605 | //$ext = $ft->get_extensions($this->supported_filetypes()); |
b81ebefd | 1606 | if (isset($value['children'])) { |
c167aa26 | 1607 | $pass = true; |
b81ebefd | 1608 | if (!empty($value['children'])) { |
b81ebefd | 1609 | $value['children'] = array_filter($value['children'], array($this, 'filter')); |
537d44e8 | 1610 | } |
c167aa26 | 1611 | } else { |
46ee50dc | 1612 | if ($accepted_types == '*' or empty($accepted_types) |
1613 | or (is_array($accepted_types) and in_array('*', $accepted_types))) { | |
c167aa26 | 1614 | $pass = true; |
1615 | } elseif (is_array($accepted_types)) { | |
1616 | foreach ($accepted_types as $type) { | |
af79a6f5 DC |
1617 | $extensions = $ft->get_extensions($type); |
1618 | if (!is_array($extensions)) { | |
c167aa26 | 1619 | $pass = true; |
af79a6f5 DC |
1620 | } else { |
1621 | foreach ($extensions as $ext) { | |
1622 | if (preg_match('#'.$ext.'$#', $value['title'])) { | |
1623 | $pass = true; | |
1624 | } | |
1625 | } | |
c167aa26 | 1626 | } |
1627 | } | |
1628 | } | |
1629 | } | |
1630 | return $pass; | |
1631 | } | |
1632 | ||
4a65c39a | 1633 | /** |
1634 | * Given a path, and perhaps a search, get a list of files. | |
1635 | * | |
728ebac7 | 1636 | * See details on http://docs.moodle.org/dev/Repository_plugins |
f7639c37 | 1637 | * |
8e0946bf | 1638 | * @param string $path, this parameter can |
4a65c39a | 1639 | * a folder name, or a identification of folder |
8e0946bf | 1640 | * @param string $page, the page number of file list |
1a6195b4 DC |
1641 | * @return array the list of files, including meta infomation, containing the following keys |
1642 | * manage, url to manage url | |
1643 | * client_id | |
1644 | * login, login form | |
1645 | * repo_id, active repository id | |
1646 | * login_btn_action, the login button action | |
1647 | * login_btn_label, the login button label | |
1648 | * total, number of results | |
1649 | * perpage, items per page | |
1650 | * page | |
1651 | * pages, total pages | |
29199e56 | 1652 | * issearchresult, is it a search result? |
1a6195b4 DC |
1653 | * list, file list |
1654 | * path, current path and parent path | |
4a65c39a | 1655 | */ |
9d6aa286 | 1656 | public function get_listing($path = '', $page = '') { |
1657 | } | |
1cf56396 | 1658 | |
fbd508b4 | 1659 | /** |
353d5cf3 | 1660 | * Search files in repository |
1661 | * When doing global search, $search_text will be used as | |
dbc01944 | 1662 | * keyword. |
353d5cf3 | 1663 | * |
fbd508b4 | 1664 | * @return mixed, see get_listing() |
1665 | */ | |
353d5cf3 | 1666 | public function search($search_text) { |
1667 | $list = array(); | |
1668 | $list['list'] = array(); | |
1669 | return false; | |
fbd508b4 | 1670 | } |
1671 | ||
d68c527f | 1672 | /** |
1673 | * Logout from repository instance | |
1674 | * By default, this function will return a login form | |
1675 | * | |
1676 | * @return string | |
1677 | */ | |
1678 | public function logout(){ | |
1679 | return $this->print_login(); | |
1680 | } | |
1681 | ||
1682 | /** | |
1683 | * To check whether the user is logged in. | |
1684 | * | |
1685 | * @return boolean | |
1686 | */ | |
1687 | public function check_login(){ | |
1688 | return true; | |
1689 | } | |
1690 | ||
1cf56396 | 1691 | |
4a65c39a | 1692 | /** |
1693 | * Show the login screen, if required | |
4a65c39a | 1694 | */ |
1d66f2b2 | 1695 | public function print_login(){ |
1696 | return $this->get_listing(); | |
1697 | } | |
1cf56396 | 1698 | |
4a65c39a | 1699 | /** |
1700 | * Show the search screen, if required | |
4a65c39a | 1701 | * @return null |
1702 | */ | |
a560785f | 1703 | public function print_search() { |
b763c2d9 | 1704 | $str = ''; |
1705 | $str .= '<input type="hidden" name="repo_id" value="'.$this->id.'" />'; | |
1706 | $str .= '<input type="hidden" name="ctx_id" value="'.$this->context->id.'" />'; | |
1707 | $str .= '<input type="hidden" name="seekey" value="'.sesskey().'" />'; | |
1708 | $str .= '<label>'.get_string('keyword', 'repository').': </label><br/><input name="s" value="" /><br/>'; | |
1709 | return $str; | |
2b9feb5f | 1710 | } |
4a65c39a | 1711 | |
3e123368 DC |
1712 | /** |
1713 | * For oauth like external authentication, when external repository direct user back to moodle, | |
1714 | * this funciton will be called to set up token and token_secret | |
1715 | */ | |
1716 | public function callback() { | |
1717 | } | |
1718 | ||
455860ce | 1719 | /** |
1720 | * is it possible to do glboal search? | |
1721 | * @return boolean | |
1722 | */ | |
7a3b93c1 | 1723 | public function global_search() { |
455860ce | 1724 | return false; |
1725 | } | |
1726 | ||
8dcd5deb | 1727 | /** |
a6600395 | 1728 | * Defines operations that happen occasionally on cron |
2b8beee3 | 1729 | * @return boolean |
8dcd5deb | 1730 | */ |
a6600395 | 1731 | public function cron() { |
1732 | return true; | |
1733 | } | |
1734 | ||
7892948d | 1735 | /** |
83a018ed | 1736 | * function which is run when the type is created (moodle administrator add the plugin) |
3e0794ed | 1737 | * @return boolean success or fail? |
7892948d | 1738 | */ |
f1cfe56e | 1739 | public static function plugin_init() { |
3e0794ed | 1740 | return true; |
7892948d | 1741 | } |
1742 | ||
a6600395 | 1743 | /** |
06e65e1e | 1744 | * Edit/Create Admin Settings Moodle form |
8e5af6cf DC |
1745 | * @param object $mform Moodle form (passed by reference) |
1746 | * @param string $classname repository class name | |
a6600395 | 1747 | */ |
8e5af6cf DC |
1748 | public function type_config_form($mform, $classname = 'repository') { |
1749 | $instnaceoptions = call_user_func(array($classname, 'get_instance_option_names'), $mform, $classname); | |
a5adfa26 DC |
1750 | if (empty($instnaceoptions)) { |
1751 | // this plugin has only one instance | |
1752 | // so we need to give it a name | |
1753 | // it can be empty, then moodle will look for instance name from language string | |
1754 | $mform->addElement('text', 'pluginname', get_string('pluginname', 'repository'), array('size' => '40')); | |
1755 | $mform->addElement('static', 'pluginnamehelp', '', get_string('pluginnamehelp', 'repository')); | |
1756 | } | |
4a65c39a | 1757 | } |
dbc01944 | 1758 | |
84ee73ee RK |
1759 | /** |
1760 | * Validate Admin Settings Moodle form | |
1761 | * @param object $mform Moodle form (passed by reference) | |
1762 | * @param array array of ("fieldname"=>value) of submitted data | |
1763 | * @param array array of ("fieldname"=>errormessage) of errors | |
1764 | * @return array array of errors | |
1765 | */ | |
1766 | public static function type_form_validation($mform, $data, $errors) { | |
1767 | return $errors; | |
1768 | } | |
1769 | ||
1770 | ||
6f2cd52a | 1771 | /** |
06e65e1e | 1772 | * Edit/Create Instance Settings Moodle form |
a5adfa26 | 1773 | * @param object $mform Moodle form (passed by reference) |
a6600395 | 1774 | */ |
8c4a4687 | 1775 | public function instance_config_form($mform) { |
a6600395 | 1776 | } |
4a65c39a | 1777 | |
a6600395 | 1778 | /** |
1779 | * Return names of the general options | |
1780 | * By default: no general option name | |
1781 | * @return array | |
1782 | */ | |
1b79955a | 1783 | public static function get_type_option_names() { |
a5adfa26 | 1784 | return array('pluginname'); |
a6600395 | 1785 | } |
1786 | ||
1787 | /** | |
1788 | * Return names of the instance options | |
1789 | * By default: no instance option name | |
1790 | * @return array | |
1791 | */ | |
7a3b93c1 | 1792 | public static function get_instance_option_names() { |
a6600395 | 1793 | return array(); |
8b65d45c | 1794 | } |
e35194be | 1795 | |
6b172cdc DC |
1796 | public static function instance_form_validation($mform, $data, $errors) { |
1797 | return $errors; | |
1798 | } | |
1799 | ||
f00340e2 | 1800 | public function get_short_filename($str, $maxlength) { |
138c7678 PS |
1801 | if (textlib::strlen($str) >= $maxlength) { |
1802 | return trim(textlib::substr($str, 0, $maxlength)).'...'; | |
f00340e2 DC |
1803 | } else { |
1804 | return $str; | |
1805 | } | |
1806 | } | |
f392caba DC |
1807 | |
1808 | /** | |
1809 | * Overwrite an existing file | |
1810 | * | |
1811 | * @param int $itemid | |
1812 | * @param string $filepath | |
1813 | * @param string $filename | |
1814 | * @param string $newfilepath | |
1815 | * @param string $newfilename | |
1816 | * @return boolean | |
1817 | */ | |
1818 | function overwrite_existing_draftfile($itemid, $filepath, $filename, $newfilepath, $newfilename) { | |
1819 | global $USER; | |
1820 | $fs = get_file_storage(); | |
1821 | $user_context = get_context_instance(CONTEXT_USER, $USER->id); | |
1822 | if ($file = $fs->get_file($user_context->id, 'user', 'draft', $itemid, $filepath, $filename)) { | |
1823 | if ($tempfile = $fs->get_file($user_context->id, 'user', 'draft', $itemid, $newfilepath, $newfilename)) { | |
1824 | // delete existing file to release filename | |
1825 | $file->delete(); | |
1826 | // create new file | |
1827 | $newfile = $fs->create_file_from_storedfile(array('filepath'=>$filepath, 'filename'=>$filename), $tempfile); | |
1828 | // remove temp file | |
1829 | $tempfile->delete(); | |
1830 | return true; | |
1831 | } | |
1832 | } | |
1833 | return false; | |
1834 | } | |
1835 | ||
1836 | /** | |
1837 | * Delete a temp file from draft area | |
1838 | * | |
1839 | * @param int $draftitemid | |
1840 | * @param string $filepath | |
1841 | * @param string $filename | |
1842 | * @return boolean | |
1843 | */ | |
1844 | function delete_tempfile_from_draft($draftitemid, $filepath, $filename) { | |
1845 | global $USER; | |
1846 | $fs = get_file_storage(); | |
1847 | $user_context = get_context_instance(CONTEXT_USER, $USER->id); | |
1848 | if ($file = $fs->get_file($user_context->id, 'user', 'draft', $draftitemid, $filepath, $filename)) { | |
1849 | $file->delete(); | |
1850 | return true; | |
1851 | } else { | |
1852 | return false; | |
1853 | } | |
1854 | } | |
8b65d45c | 1855 | } |
837ebb78 | 1856 | |
1857 | /** | |
6f2cd52a DC |
1858 | * Exception class for repository api |
1859 | * | |
1860 | * @since 2.0 | |
1861 | * @package moodlecore | |
1862 | * @subpackage repository | |
1863 | * @copyright 2009 Dongsheng Cai <dongsheng@moodle.com> | |
1864 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
837ebb78 | 1865 | */ |
4a65c39a | 1866 | class repository_exception extends moodle_exception { |
8b65d45c | 1867 | } |
4ed43890 | 1868 | |
8dcd5deb | 1869 | /** |
6f2cd52a DC |
1870 | * This is a class used to define a repository instance form |
1871 | * | |
1872 | * @since 2.0 | |
1873 | * @package moodlecore | |
1874 | * @subpackage repository | |
1875 | * @copyright 2009 Dongsheng Cai <dongsheng@moodle.com> | |
1876 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
8dcd5deb | 1877 | */ |
a6600395 | 1878 | final class repository_instance_form extends moodleform { |
4a65c39a | 1879 | protected $instance; |
1880 | protected $plugin; | |
49d20def | 1881 | protected function add_defaults() { |
4a65c39a | 1882 | $mform =& $this->_form; |
1883 | $strrequired = get_string('required'); | |
1884 | ||
1885 | $mform->addElement('hidden', 'edit', ($this->instance) ? $this->instance->id : 0); | |
d18e0fe6 | 1886 | $mform->setType('edit', PARAM_INT); |
4a65c39a | 1887 | $mform->addElement('hidden', 'new', $this->plugin); |
d18e0fe6 | 1888 | $mform->setType('new', PARAM_FORMAT); |
4a65c39a | 1889 | $mform->addElement('hidden', 'plugin', $this->plugin); |
d18e0fe6 | 1890 | $mform->setType('plugin', PARAM_SAFEDIR); |
27051e43 | 1891 | $mform->addElement('hidden', 'typeid', $this->typeid); |
d18e0fe6 | 1892 | $mform->setType('typeid', PARAM_INT); |
faaa613d | 1893 | $mform->addElement('hidden', 'contextid', $this->contextid); |
d18e0fe6 | 1894 | $mform->setType('contextid', PARAM_INT); |
4a65c39a | 1895 | |
1896 | $mform->addElement('text', 'name', get_string('name'), 'maxlength="100" size="30"'); | |
1897 | $mform->addRule('name', $strrequired, 'required', null, 'client'); | |
49d20def | 1898 | } |
4a65c39a | 1899 | |
49d20def DC |
1900 | public function definition() { |
1901 | global $CFG; | |
1902 | // type of plugin, string | |
1903 | $this->plugin = $this->_customdata['plugin']; | |
1904 | $this->typeid = $this->_customdata['typeid']; | |
1905 | $this->contextid = $this->_customdata['contextid']; | |
1906 | $this->instance = (isset($this->_customdata['instance']) | |
1907 | && is_subclass_of($this->_customdata['instance'], 'repository')) | |
1908 | ? $this->_customdata['instance'] : null; | |
1909 | ||
1910 | $mform =& $this->_form; | |
1e97f196 | 1911 | |
49d20def | 1912 | $this->add_defaults(); |
f48fb4d6 | 1913 | //add fields |
1914 | if (!$this->instance) { | |
dbc01944 | 1915 | $result = repository::static_function($this->plugin, 'instance_config_form', $mform); |
49d20def DC |
1916 | if ($result === false) { |
1917 | $mform->removeElement('name'); | |
1918 | } | |
1919 | } else { | |
f48fb4d6 | 1920 | $data = array(); |
1921 | $data['name'] = $this->instance->name; | |
1922 | if (!$this->instance->readonly) { | |
1923 | $result = $this->instance->instance_config_form($mform); | |
49d20def DC |
1924 | if ($result === false) { |
1925 | $mform->removeElement('name'); | |
1926 | } | |
f48fb4d6 | 1927 | // and set the data if we have some. |
1e97f196 | 1928 | foreach ($this->instance->get_instance_option_names() as $config) { |
a3d8df25 | 1929 | if (!empty($this->instance->options[$config])) { |
1930 | $data[$config] = $this->instance->options[$config]; | |
1e97f196 | 1931 | } else { |
1932 | $data[$config] = ''; | |
1933 | } | |
27051e43 | 1934 | } |
4a65c39a | 1935 | } |
f48fb4d6 | 1936 | $this->set_data($data); |
1e97f196 | 1937 | } |
1938 | ||
49d20def DC |
1939 | if ($result === false) { |
1940 | $mform->addElement('cancel'); | |
1941 | } else { | |
1942 | $this->add_action_buttons(true, get_string('save','repository')); | |
1943 | } | |
4a65c39a | 1944 | } |
1945 | ||
1946 | public function validation($data) { | |
1947 | global $DB; | |
4a65c39a | 1948 | $errors = array(); |
6b172cdc DC |
1949 | $plugin = $this->_customdata['plugin']; |
1950 | $instance = (isset($this->_customdata['instance']) | |
1951 | && is_subclass_of($this->_customdata['instance'], 'repository')) | |
1952 | ? $this->_customdata['instance'] : null; | |
1953 | if (!$instance) { | |
1954 | $errors = repository::static_function($plugin, 'instance_form_validation', $this, $data, $errors); | |
1955 | } else { | |
1956 | $errors = $instance->instance_form_validation($this, $data, $errors); | |
1957 | } | |
1958 | ||
a090554a PS |
1959 | $sql = "SELECT count('x') |
1960 | FROM {repository_instances} i, {repository} r | |
1961 | WHERE r.type=:plugin AND r.id=i.typeid AND i.name=:name"; | |
09bff8e8 | 1962 | if ($DB->count_records_sql($sql, array('name' => $data['name'], 'plugin' => $data['plugin'])) > 1) { |
6b172cdc | 1963 | $errors['name'] = get_string('erroruniquename', 'repository'); |
4a65c39a | 1964 | } |
1965 | ||
4a65c39a | 1966 | return $errors; |
1967 | } | |
1968 | } | |
a6600395 | 1969 | |
a6600395 | 1970 | /** |
6f2cd52a DC |
1971 | * This is a class used to define a repository type setting form |
1972 | * | |
1973 | * @since 2.0 | |
1974 | * @package moodlecore | |
1975 | * @subpackage repository | |
1976 | * @copyright 2009 Dongsheng Cai <dongsheng@moodle.com> | |
1977 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
a6600395 | 1978 | */ |
c295f9ff | 1979 | final class repository_type_form extends moodleform { |
a6600395 | 1980 | protected $instance; |
1981 | protected $plugin; | |
79698344 | 1982 | protected $action; |
a6600395 | 1983 | |
1984 | /** | |
1985 | * Definition of the moodleform | |
1986 | * @global object $CFG | |
1987 | */ | |
1988 | public function definition() { | |
1989 | global $CFG; | |
1990 | // type of plugin, string | |
1991 | $this->plugin = $this->_customdata['plugin']; | |
1992 | $this->instance = (isset($this->_customdata['instance']) | |
1993 | && is_a($this->_customdata['instance'], 'repository_type')) | |
1994 | ? $this->_customdata['instance'] : null; | |
1995 | ||
79698344 | 1996 | $this->action = $this->_customdata['action']; |
a5adfa26 | 1997 | $this->pluginname = $this->_customdata['pluginname']; |
a6600395 | 1998 | $mform =& $this->_form; |
1999 | $strrequired = get_string('required'); | |
4d5948f1 | 2000 | |
79698344 MD |
2001 | $mform->addElement('hidden', 'action', $this->action); |
2002 | $mform->setType('action', PARAM_TEXT); | |
2003 | $mform->addElement('hidden', 'repos', $this->plugin); | |
2004 | $mform->setType('repos', PARAM_SAFEDIR); | |
8f943eba | 2005 | |
06e65e1e | 2006 | // let the plugin add its specific fields |
a5adfa26 DC |
2007 | $classname = 'repository_' . $this->plugin; |
2008 | require_once($CFG->dirroot . '/repository/' . $this->plugin . '/lib.php'); | |
f48fb4d6 | 2009 | //add "enable course/user instances" checkboxes if multiple instances are allowed |
dbc01944 | 2010 | $instanceoptionnames = repository::static_function($this->plugin, 'get_instance_option_names'); |
8e5af6cf DC |
2011 | |
2012 | $result = call_user_func(array($classname, 'type_config_form'), $mform, $classname); | |
2013 | ||
a5adfa26 | 2014 | if (!empty($instanceoptionnames)) { |
8e5af6cf DC |
2015 | $sm = get_string_manager(); |
2016 | $component = 'repository'; | |
2017 | if ($sm->string_exists('enablecourseinstances', 'repository_' . $this->plugin)) { | |
2018 | $component .= ('_' . $this->plugin); | |
2019 | } | |
2020 | $mform->addElement('checkbox', 'enablecourseinstances', get_string('enablecourseinstances', $component)); | |
2021 | ||
2022 | $component = 'repository'; | |
2023 | if ($sm->string_exists('enableuserinstances', 'repository_' . $this->plugin)) { | |
2024 | $component .= ('_' . $this->plugin); | |
2025 | } | |
2026 | $mform->addElement('checkbox', 'enableuserinstances', get_string('enableuserinstances', $component)); | |
f48fb4d6 | 2027 | } |
2028 | ||
2029 | // set the data if we have some. | |
a6600395 | 2030 | if ($this->instance) { |
2031 | $data = array(); | |
1b79955a | 2032 | $option_names = call_user_func(array($classname,'get_type_option_names')); |
f48fb4d6 | 2033 | if (!empty($instanceoptionnames)){ |
2034 | $option_names[] = 'enablecourseinstances'; | |
2035 | $option_names[] = 'enableuserinstances'; | |
2036 | } | |
2037 | ||
a6600395 | 2038 | $instanceoptions = $this->instance->get_options(); |
2039 | foreach ($option_names as $config) { | |
2040 | if (!empty($instanceoptions[$config])) { | |
2041 | $data[$config] = $instanceoptions[$config]; | |
2042 | } else { | |
2043 | $data[$config] = ''; | |
2044 | } | |
2045 | } | |
a5adfa26 DC |
2046 | // XXX: set plugin name for plugins which doesn't have muliti instances |
2047 | if (empty($instanceoptionnames)){ | |
2048 | $data['pluginname'] = $this->pluginname; | |
2049 | } | |
a6600395 | 2050 | $this->set_data($data); |
2051 | } | |
dbc01944 | 2052 | |
46dd6bb0 | 2053 | $this->add_action_buttons(true, get_string('save','repository')); |
a6600395 | 2054 | } |
84ee73ee RK |
2055 | |
2056 | public function validation($data) { | |
2057 | $errors = array(); | |
2058 | $plugin = $this->_customdata['plugin']; | |
2059 | $instance = (isset($this->_customdata['instance']) | |
2060 | && is_subclass_of($this->_customdata['instance'], 'repository')) | |
2061 | ? $this->_customdata['instance'] : null; | |
2062 | if (!$instance) { | |
2063 | $errors = repository::static_function($plugin, 'type_form_validation', $this, $data, $errors); | |
2064 | } else { | |
2065 | $errors = $instance->type_form_validation($this, $data, $errors); | |
2066 | } | |
2067 | ||
2068 | return $errors; | |
2069 | } | |
a6600395 | 2070 | } |
2071 | ||
8e0946bf DC |
2072 | /** |
2073 | * Generate all options needed by filepicker | |
2074 | * | |
2075 | * @param array $args, including following keys | |
2076 | * context | |
2077 | * accepted_types | |
2078 | * return_types | |
2079 | * | |
2080 | * @return array the list of repository instances, including meta infomation, containing the following keys | |
2081 | * externallink | |
2082 | * repositories | |
2083 | * accepted_types | |
2084 | */ | |
99eaca9d | 2085 | function initialise_filepicker($args) { |
a28c9253 | 2086 | global $CFG, $USER, $PAGE, $OUTPUT; |
1dce6261 | 2087 | require_once($CFG->libdir . '/licenselib.php'); |
4f0c2d00 | 2088 | |
6bdfef5d | 2089 | $return = new stdClass(); |
d1d4813f | 2090 | $licenses = array(); |
4f0c2d00 PS |
2091 | if (!empty($CFG->licenses)) { |
2092 | $array = explode(',', $CFG->licenses); | |
2093 | foreach ($array as $license) { | |
6bdfef5d | 2094 | $l = new stdClass(); |
4f0c2d00 PS |
2095 | $l->shortname = $license; |
2096 | $l->fullname = get_string($license, 'license'); | |
2097 | $licenses[] = $l; | |
2098 | } | |
d1d4813f | 2099 | } |
308d948b DC |
2100 | if (!empty($CFG->sitedefaultlicense)) { |
2101 | $return->defaultlicense = $CFG->sitedefaultlicense; | |
2102 | } | |
1dce6261 | 2103 | |
1dce6261 DC |
2104 | $return->licenses = $licenses; |
2105 | ||
2106 | $return->author = fullname($USER); | |
2107 | ||
99eaca9d DC |
2108 | $ft = new filetype_parser(); |
2109 | if (empty($args->context)) { | |
2110 | $context = $PAGE->context; | |
e189ec00 | 2111 | } else { |
99eaca9d DC |
2112 | $context = $args->context; |
2113 | } | |
6bf197b3 DC |
2114 | $disable_types = array(); |
2115 | if (!empty($args->disable_types)) { | |
2116 | $disable_types = $args->disable_types; | |
2117 | } | |
99eaca9d | 2118 | |
e189ec00 | 2119 | $user_context = get_context_instance(CONTEXT_USER, $USER->id); |
99eaca9d | 2120 | |
bf413f6f DC |
2121 | list($context, $course, $cm) = get_context_info_array($context->id); |
2122 | $contexts = array($user_context, get_system_context()); | |
2123 | if (!empty($course)) { | |
2124 | // adding course context | |
2125 | $contexts[] = get_context_instance(CONTEXT_COURSE, $course->id); | |
2126 | } | |
99eaca9d DC |
2127 | $externallink = (int)get_config(null, 'repositoryallowexternallinks'); |
2128 | $repositories = repository::get_instances(array( | |
bf413f6f | 2129 | 'context'=>$contexts, |
99eaca9d | 2130 | 'currentcontext'=> $context, |
ea1780ad | 2131 | 'accepted_types'=>$args->accepted_types, |
6bf197b3 DC |
2132 | 'return_types'=>$args->return_types, |
2133 | 'disable_types'=>$disable_types | |
99eaca9d DC |
2134 | )); |
2135 | ||
2136 | $return->repositories = array(); | |
2137 | ||
2138 | if (empty($externallink)) { | |
2139 | $return->externallink = false; | |
2140 | } else { | |
2141 | $return->externallink = true; | |
2142 | } | |
2143 | ||
99eaca9d DC |
2144 | // provided by form element |
2145 | $return->accepted_types = $ft->get_extensions($args->accepted_types); | |
766514a0 | 2146 | $return->return_types = $args->return_types; |
99eaca9d DC |
2147 | foreach ($repositories as $repository) { |
2148 | $meta = $repository->get_meta(); | |
2149 | $return->repositories[$repository->id] = $meta; | |
2150 | } | |
2151 | return $return; | |
e189ec00 | 2152 | } |
f392caba DC |
2153 | /** |
2154 | * Small function to walk an array to attach repository ID | |
2155 | * @param array $value | |
2156 | * @param string $key | |
2157 | * @param int $id | |
2158 | */ | |
2159 | function repository_attach_id(&$value, $key, $id){ | |
2160 | $value['repo_id'] = $id; | |
2161 | } |