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