12c79bfd |
1 | <?php |
2 | // $Id$ |
1cf56396 |
3 | |
4 | /////////////////////////////////////////////////////////////////////////// |
5 | // // |
6 | // NOTICE OF COPYRIGHT // |
7 | // // |
8 | // Moodle - Modular Object-Oriented Dynamic Learning Environment // |
9 | // http://moodle.com // |
10 | // // |
11 | // Copyright (C) 2008 onwards Moodle Pty Ltd http://moodle.com // |
12 | // // |
13 | // This program is free software; you can redistribute it and/or modify // |
14 | // it under the terms of the GNU General Public License as published by // |
15 | // the Free Software Foundation; either version 2 of the License, or // |
16 | // (at your option) any later version. // |
17 | // // |
18 | // This program is distributed in the hope that it will be useful, // |
19 | // but WITHOUT ANY WARRANTY; without even the implied warranty of // |
20 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // |
21 | // GNU General Public License for more details: // |
22 | // // |
23 | // http://www.gnu.org/copyleft/gpl.html // |
24 | // // |
25 | /////////////////////////////////////////////////////////////////////////// |
26 | |
aca64b79 |
27 | /** |
28 | * About repository/lib.php: |
29 | * two main classes: |
30 | * 1. repository_type => a repository plugin, You can activate a plugin into |
31 | * Moodle. You also can set some general settings/options for this type of repository. |
32 | * All instances would share the same options (for example: a API key for the connection |
33 | * to the repository) |
34 | * 2. repository => an instance of a plugin. You can also call it an access or |
35 | * an account. An instance has specific settings (for example: a public url) and a specific |
36 | * name. That's this name which is displayed in the file picker. |
37 | */ |
38 | |
39 | |
40 | |
19add4c0 |
41 | require_once(dirname(dirname(__FILE__)) . '/config.php'); |
9bdd9eee |
42 | require_once(dirname(dirname(__FILE__)) . '/lib/filelib.php'); |
43 | require_once(dirname(dirname(__FILE__)) . '/lib/formslib.php'); |
44 | // File picker javascript code |
45 | require_once(dirname(dirname(__FILE__)) . '/repository/javascript.php'); |
1cf56396 |
46 | |
a6600395 |
47 | /** |
48 | * A repository_type is a repository plug-in. It can be Box.net, Flick-r, ... |
49 | * A repository type can be edited, sorted and hidden. It is mandatory for an |
50 | * administrator to create a repository type in order to be able to create |
51 | * some instances of this type. |
52 | * |
53 | * Coding note: |
54 | * - a repository_type object is mapped to the "repository" database table |
55 | * - "typename" attibut maps the "type" database field. It is unique. |
56 | * - general "options" for a repository type are saved in the config_plugin table |
eb239694 |
57 | * - when you delete a repository, all instances are deleted, and general |
58 | * options are also deleted from database |
a6600395 |
59 | * - When you create a type for a plugin that can't have multiple instances, a |
60 | * instance is automatically created. |
61 | */ |
62 | class repository_type { |
63 | |
64 | |
65 | /** |
66 | * Type name (no whitespace) - A type name is unique |
67 | * Note: for a user-friendly type name see get_readablename() |
68 | * @var String |
69 | */ |
70 | private $_typename; |
71 | |
72 | |
73 | /** |
74 | * Options of this type |
75 | * They are general options that any instance of this type would share |
76 | * e.g. API key |
77 | * These options are saved in config_plugin table |
78 | * @var array |
79 | */ |
7a3b93c1 |
80 | private $_options; |
a6600395 |
81 | |
82 | |
83 | /** |
84 | * Is the repository type visible or hidden |
85 | * If false (hidden): no instances can be created, edited, deleted, showned , used... |
86 | * @var boolean |
87 | */ |
7a3b93c1 |
88 | private $_visible; |
a6600395 |
89 | |
90 | |
91 | /** |
92 | * 0 => not ordered, 1 => first position, 2 => second position... |
93 | * A not order type would appear in first position (should never happened) |
94 | * @var integer |
95 | */ |
96 | private $_sortorder; |
97 | |
f48fb4d6 |
98 | /** |
99 | * Return if the instance is visible in a context |
100 | * TODO: check if the context visibility has been overwritten by the plugin creator |
101 | * (need to create special functions to be overvwritten in repository class) |
102 | * @param objet $contextlevel - context level |
103 | * @return boolean |
104 | */ |
105 | public function get_contextvisibility($contextlevel) { |
106 | |
107 | if ($contextlevel == CONTEXT_COURSE) { |
108 | return $this->_options['enablecourseinstances']; |
109 | } |
110 | |
111 | if ($contextlevel == CONTEXT_USER) { |
112 | return $this->_options['enableuserinstances']; |
113 | } |
114 | |
115 | //the context is SITE |
116 | return true; |
117 | } |
118 | |
119 | |
120 | |
a6600395 |
121 | /** |
122 | * repository_type constructor |
123 | * @global <type> $CFG |
124 | * @param integer $typename |
125 | * @param array $typeoptions |
126 | * @param boolean $visible |
127 | * @param integer $sortorder (don't really need set, it will be during create() call) |
128 | */ |
7a3b93c1 |
129 | public function __construct($typename = '', $typeoptions = array(), $visible = false, $sortorder = 0) { |
a6600395 |
130 | global $CFG; |
131 | |
132 | //set type attributs |
133 | $this->_typename = $typename; |
134 | $this->_visible = $visible; |
135 | $this->_sortorder = $sortorder; |
46dd6bb0 |
136 | |
a6600395 |
137 | //set options attribut |
138 | $this->_options = array(); |
1b79955a |
139 | $options = repository_static_function($typename,'get_type_option_names'); |
a6600395 |
140 | //check that the type can be setup |
06e65e1e |
141 | if (!empty($options)) { |
a6600395 |
142 | //set the type options |
143 | foreach ($options as $config) { |
7a3b93c1 |
144 | if (array_key_exists($config,$typeoptions)) { |
145 | $this->_options[$config] = $typeoptions[$config]; |
a6600395 |
146 | } |
147 | } |
148 | } |
f48fb4d6 |
149 | |
150 | //retrieve visibility from option |
151 | if (array_key_exists('enablecourseinstances',$typeoptions)) { |
152 | $this->_options['enablecourseinstances'] = $typeoptions['enablecourseinstances']; |
9f7c761a |
153 | } else { |
154 | $this->_options['enablecourseinstances'] = 0; |
f48fb4d6 |
155 | } |
156 | |
157 | if (array_key_exists('enableuserinstances',$typeoptions)) { |
158 | $this->_options['enableuserinstances'] = $typeoptions['enableuserinstances']; |
9f7c761a |
159 | } else { |
160 | $this->_options['enableuserinstances'] = 0; |
f48fb4d6 |
161 | } |
162 | |
a6600395 |
163 | } |
164 | |
165 | /** |
166 | * Get the type name (no whitespace) |
167 | * For a human readable name, use get_readablename() |
168 | * @return String the type name |
169 | */ |
7a3b93c1 |
170 | public function get_typename() { |
a6600395 |
171 | return $this->_typename; |
172 | } |
173 | |
174 | /** |
175 | * Return a human readable and user-friendly type name |
176 | * @return string user-friendly type name |
177 | */ |
7a3b93c1 |
178 | public function get_readablename() { |
a6600395 |
179 | return get_string('repositoryname','repository_'.$this->_typename); |
180 | } |
181 | |
182 | /** |
183 | * Return general options |
184 | * @return array the general options |
185 | */ |
7a3b93c1 |
186 | public function get_options() { |
a6600395 |
187 | return $this->_options; |
188 | } |
189 | |
190 | /** |
191 | * Return visibility |
192 | * @return boolean |
193 | */ |
7a3b93c1 |
194 | public function get_visible() { |
a6600395 |
195 | return $this->_visible; |
196 | } |
197 | |
198 | /** |
199 | * Return order / position of display in the file picker |
200 | * @return integer |
201 | */ |
7a3b93c1 |
202 | public function get_sortorder() { |
a6600395 |
203 | return $this->_sortorder; |
204 | } |
205 | |
206 | /** |
207 | * Create a repository type (the type name must not already exist) |
208 | * @global object $DB |
209 | */ |
7a3b93c1 |
210 | public function create() { |
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 |
229 | $newtype = new stdclass; |
230 | $newtype->type = $this->_typename; |
231 | $newtype->visible = $this->_visible; |
232 | $newtype->sortorder = $this->_sortorder; |
233 | $DB->insert_record('repository', $newtype); |
234 | |
235 | //save the options in DB |
236 | $this->update_options(); |
237 | |
edb50637 |
238 | //if the plugin type has no multiple instance (e.g. has no instance option name) so it wont |
7a3b93c1 |
239 | //be possible for the administrator to create a instance |
240 | //in this case we need to create an instance |
edb50637 |
241 | $instanceoptionnames = repository_static_function($this->_typename, 'get_instance_option_names'); |
242 | if (empty($instanceoptionnames)) { |
7a3b93c1 |
243 | $instanceoptions = array(); |
244 | $instanceoptions['name'] = $this->_typename; |
245 | repository_static_function($this->_typename, 'create', $this->_typename, 0, get_system_context(), $instanceoptions); |
246 | } |
948c2860 |
247 | |
248 | //run init function |
3e0794ed |
249 | if (!repository_static_function($this->_typename, 'plugin_init')) { |
250 | throw new repository_exception('cannotcreatetype', 'repository'); |
251 | } |
948c2860 |
252 | |
7a3b93c1 |
253 | } else { |
a6600395 |
254 | throw new repository_exception('existingrepository', 'repository'); |
255 | } |
256 | } |
257 | |
258 | |
259 | /** |
260 | * Update plugin options into the config_plugin table |
261 | * @param array $options |
262 | * @return boolean |
263 | */ |
7a3b93c1 |
264 | public function update_options($options = null) { |
265 | if (!empty($options)) { |
a6600395 |
266 | $this->_options = $options; |
267 | } |
268 | |
269 | foreach ($this->_options as $name => $value) { |
270 | set_config($name,$value,$this->_typename); |
271 | } |
272 | |
273 | return true; |
274 | } |
275 | |
276 | /** |
277 | * Update visible database field with the value given as parameter |
278 | * or with the visible value of this object |
279 | * This function is private. |
280 | * For public access, have a look to switch_and_update_visibility() |
281 | * @global object $DB |
282 | * @param boolean $visible |
283 | * @return boolean |
284 | */ |
7a3b93c1 |
285 | private function update_visible($visible = null) { |
a6600395 |
286 | global $DB; |
287 | |
7a3b93c1 |
288 | if (!empty($visible)) { |
a6600395 |
289 | $this->_visible = $visible; |
290 | } |
7a3b93c1 |
291 | else if (!isset($this->_visible)) { |
a6600395 |
292 | throw new repository_exception('updateemptyvisible', 'repository'); |
293 | } |
294 | |
295 | return $DB->set_field('repository', 'visible', $this->_visible, array('type'=>$this->_typename)); |
296 | } |
297 | |
298 | /** |
299 | * Update database sortorder field with the value given as parameter |
300 | * or with the sortorder value of this object |
301 | * This function is private. |
302 | * For public access, have a look to move_order() |
303 | * @global object $DB |
304 | * @param integer $sortorder |
305 | * @return boolean |
306 | */ |
7a3b93c1 |
307 | private function update_sortorder($sortorder = null) { |
a6600395 |
308 | global $DB; |
309 | |
7a3b93c1 |
310 | if (!empty($sortorder) && $sortorder!=0) { |
a6600395 |
311 | $this->_sortorder = $sortorder; |
312 | } |
313 | //if sortorder is not set, we set it as the ;ast position in the list |
7a3b93c1 |
314 | else if (!isset($this->_sortorder) || $this->_sortorder == 0 ) { |
a6600395 |
315 | $sql = "SELECT MAX(sortorder) FROM {repository}"; |
316 | $this->_sortorder = 1 + $DB->get_field_sql($sql); |
317 | } |
318 | |
319 | return $DB->set_field('repository', 'sortorder', $this->_sortorder, array('type'=>$this->_typename)); |
320 | } |
321 | |
322 | /** |
323 | * Change order of the type with its adjacent upper or downer type |
324 | * (database fields are updated) |
325 | * Algorithm details: |
326 | * 1. retrieve all types in an array. This array is sorted by sortorder, |
327 | * and the array keys start from 0 to X (incremented by 1) |
328 | * 2. switch sortorder values of this type and its adjacent type |
329 | * @global object $DB |
330 | * @param string $move "up" or "down" |
331 | */ |
332 | public function move_order($move) { |
333 | global $DB; |
a6600395 |
334 | |
7a3b93c1 |
335 | $types = repository_get_types(); // retrieve all types |
336 | |
337 | /// retrieve this type into the returned array |
338 | $i = 0; |
339 | while (!isset($indice) && $i<count($types)) { |
340 | if ($types[$i]->get_typename() == $this->_typename) { |
a6600395 |
341 | $indice = $i; |
342 | } |
343 | $i++; |
344 | } |
345 | |
7a3b93c1 |
346 | /// retrieve adjacent indice |
a6600395 |
347 | switch ($move) { |
348 | case "up": |
349 | $adjacentindice = $indice - 1; |
7a3b93c1 |
350 | break; |
a6600395 |
351 | case "down": |
352 | $adjacentindice = $indice + 1; |
7a3b93c1 |
353 | break; |
a6600395 |
354 | default: |
7a3b93c1 |
355 | throw new repository_exception('movenotdefined', 'repository'); |
a6600395 |
356 | } |
357 | |
358 | //switch sortorder of this type and the adjacent type |
359 | //TODO: we could reset sortorder for all types. This is not as good in performance term, but |
360 | //that prevent from wrong behaviour on a screwed database. As performance are not important in this particular case |
361 | //it worth to change the algo. |
7a3b93c1 |
362 | if ($adjacentindice>=0 && !empty($types[$adjacentindice])) { |
a6600395 |
363 | $DB->set_field('repository', 'sortorder', $this->_sortorder, array('type'=>$types[$adjacentindice]->get_typename())); |
364 | $this->update_sortorder($types[$adjacentindice]->get_sortorder()); |
365 | } |
366 | } |
367 | |
368 | /** |
369 | * 1. Switch the visibility OFF if it's ON, and ON if it's OFF. |
370 | * 2. Update the type |
371 | * @return <type> |
372 | */ |
7a3b93c1 |
373 | public function switch_and_update_visibility() { |
a6600395 |
374 | $this->_visible = !$this->_visible; |
375 | return $this->update_visible(); |
376 | } |
377 | |
378 | |
379 | /** |
eb239694 |
380 | * Delete a repository_type (general options are removed from config_plugin |
381 | * table, and all instances are deleted) |
a6600395 |
382 | * @global object $DB |
383 | * @return boolean |
384 | */ |
7a3b93c1 |
385 | public function delete() { |
a6600395 |
386 | global $DB; |
46dd6bb0 |
387 | |
388 | //delete all instances of this type |
12c79bfd |
389 | $instances = repository_get_instances(array(),null,false,$this->_typename); |
7a3b93c1 |
390 | foreach ($instances as $instance) { |
46dd6bb0 |
391 | $instance->delete(); |
392 | } |
393 | |
eb239694 |
394 | //delete all general options |
7a3b93c1 |
395 | foreach ($this->_options as $name => $value) { |
eb239694 |
396 | set_config($name, null, $this->_typename); |
397 | } |
398 | |
a6600395 |
399 | return $DB->delete_records('repository', array('type' => $this->_typename)); |
400 | } |
401 | } |
402 | |
403 | /** |
404 | * Return a type for a given type name. |
405 | * @global object $DB |
406 | * @param string $typename the type name |
407 | * @return integer |
408 | */ |
7a3b93c1 |
409 | function repository_get_type_by_typename($typename) { |
a6600395 |
410 | global $DB; |
411 | |
7a3b93c1 |
412 | if (!$record = $DB->get_record('repository',array('type' => $typename))) { |
a6600395 |
413 | return false; |
414 | } |
415 | |
416 | return new repository_type($typename, (array)get_config($typename), $record->visible, $record->sortorder); |
417 | } |
418 | |
419 | /** |
420 | * Return a type for a given type id. |
421 | * @global object $DB |
422 | * @param string $typename the type name |
423 | * @return integer |
424 | */ |
7a3b93c1 |
425 | function repository_get_type_by_id($id) { |
a6600395 |
426 | global $DB; |
427 | |
7a3b93c1 |
428 | if (!$record = $DB->get_record('repository',array('id' => $id))) { |
a6600395 |
429 | return false; |
430 | } |
431 | |
432 | return new repository_type($record->type, (array)get_config($record->type), $record->visible, $record->sortorder); |
433 | } |
434 | |
435 | /** |
436 | * Return all repository types ordered by sortorder |
437 | * first type in returnedarray[0], second type in returnedarray[1], ... |
438 | * @global object $DB |
bbcd4860 |
439 | * @param boolean $visible can return types by visiblity, return all types if null |
a6600395 |
440 | * @return array Repository types |
441 | */ |
7a3b93c1 |
442 | function repository_get_types($visible=null) { |
a6600395 |
443 | global $DB; |
444 | |
445 | $types = array(); |
bbcd4860 |
446 | $params = null; |
447 | if (!empty($visible)) { |
448 | $params = array('visible' => $visible); |
449 | } |
7a3b93c1 |
450 | if ($records = $DB->get_records('repository',$params,'sortorder')) { |
a6600395 |
451 | foreach($records as $type) { |
46dd6bb0 |
452 | $types[] = new repository_type($type->type, (array)get_config($type->type), $type->visible, $type->sortorder); |
a6600395 |
453 | } |
454 | } |
455 | |
456 | return $types; |
457 | } |
458 | |
459 | /** |
8d419e59 |
460 | * This is the base class of the repository class |
461 | * |
462 | * To use repository plugin, see: |
463 | * http://docs.moodle.org/en/Development:Repository_How_to_Create_Plugin |
464 | * |
465 | * class repository is an abstract class, some functions must be implemented in subclass. |
466 | * |
467 | * See an example: repository/boxnet/repository.class.php |
468 | * |
469 | * A few notes: |
470 | * // for ajax file picker, this will print a json string to tell file picker |
471 | * // how to build a login form |
472 | * $repo->print_login(); |
473 | * // for ajax file picker, this will return a files list. |
474 | * $repo->get_listing(); |
475 | * // this function will be used for non-javascript version. |
476 | * $repo->print_listing(); |
477 | * // print a search box |
478 | * $repo->print_search(); |
479 | * |
480 | * @package repository |
481 | * @license http://www.gnu.org/copyleft/gpl.html GNU Public License |
a6600395 |
482 | */ |
fca079c5 |
483 | abstract class repository { |
efe018b4 |
484 | // $disabled can be set to true to disable a plugin by force |
485 | // example: self::$disabled = true |
486 | public $disabled = false; |
4a65c39a |
487 | public $id; |
488 | public $context; |
489 | public $options; |
948c2860 |
490 | public $readonly; |
1cf56396 |
491 | |
492 | /** |
3f24ea1e |
493 | * 1. Initialize context and options |
494 | * 2. Accept necessary parameters |
495 | * |
8dcd5deb |
496 | * @param integer $repositoryid |
497 | * @param integer $contextid |
498 | * @param array $options |
1cf56396 |
499 | */ |
948c2860 |
500 | public function __construct($repositoryid, $contextid = SITEID, $options = array(), $readonly = 0) { |
4a65c39a |
501 | $this->id = $repositoryid; |
502 | $this->context = get_context_instance_by_id($contextid); |
948c2860 |
503 | $this->readonly = $readonly; |
4a65c39a |
504 | $this->options = array(); |
fca079c5 |
505 | if (is_array($options)) { |
4a65c39a |
506 | $options = array_merge($this->get_option(), $options); |
507 | } else { |
508 | $options = $this->get_option(); |
509 | } |
b1339e98 |
510 | $this->options = array(); |
4a65c39a |
511 | foreach ($options as $n => $v) { |
512 | $this->options[$n] = $v; |
82669dc4 |
513 | } |
d31af46a |
514 | $this->name = $this->get_name(); |
1cf56396 |
515 | } |
516 | |
8dcd5deb |
517 | /** |
3f24ea1e |
518 | * set options for repository instance |
519 | * |
8dcd5deb |
520 | * @param string $name |
3f24ea1e |
521 | * @param mixed $value |
8dcd5deb |
522 | */ |
fca079c5 |
523 | public function __set($name, $value) { |
82669dc4 |
524 | $this->options[$name] = $value; |
525 | } |
1cf56396 |
526 | |
8dcd5deb |
527 | /** |
3f24ea1e |
528 | * get options for repository instance |
529 | * |
530 | * @param string $name |
531 | * @return mixed |
8dcd5deb |
532 | */ |
fca079c5 |
533 | public function __get($name) { |
7a3b93c1 |
534 | if (array_key_exists($name, $this->options)) { |
82669dc4 |
535 | return $this->options[$name]; |
536 | } |
537 | trigger_error('Undefined property: '.$name, E_USER_NOTICE); |
538 | return null; |
539 | } |
1cf56396 |
540 | |
8dcd5deb |
541 | /** |
3f24ea1e |
542 | * test option name |
543 | * |
544 | * @param string name |
8dcd5deb |
545 | */ |
fca079c5 |
546 | public function __isset($name) { |
82669dc4 |
547 | return isset($this->options[$name]); |
1cf56396 |
548 | } |
549 | |
8dcd5deb |
550 | /** |
3f24ea1e |
551 | * Return the name of the repository class |
8dcd5deb |
552 | * @return <type> |
553 | */ |
fca079c5 |
554 | public function __toString() { |
82669dc4 |
555 | return 'Repository class: '.__CLASS__; |
556 | } |
4a65c39a |
557 | |
c425472d |
558 | /** |
66dc47bc |
559 | * Download a file, this function can be overridden by |
560 | * subclass. |
3f24ea1e |
561 | * |
8dcd5deb |
562 | * @global object $CFG |
c425472d |
563 | * @param string $url the url of file |
564 | * @param string $file save location |
3f24ea1e |
565 | * @return string the location of the file |
b1339e98 |
566 | * @see curl package |
c425472d |
567 | */ |
bb2c046d |
568 | public function get_file($url, $file = '') { |
c425472d |
569 | global $CFG; |
c9260130 |
570 | if (!file_exists($CFG->dataroot.'/temp/download')) { |
571 | mkdir($CFG->dataroot.'/temp/download/', 0777, true); |
1e28c767 |
572 | } |
7a3b93c1 |
573 | if (is_dir($CFG->dataroot.'/temp/download')) { |
c9260130 |
574 | $dir = $CFG->dataroot.'/temp/download/'; |
1e28c767 |
575 | } |
7a3b93c1 |
576 | if (empty($file)) { |
84df43de |
577 | $file = uniqid('repo').'_'.time().'.tmp'; |
578 | } |
7a3b93c1 |
579 | if (file_exists($dir.$file)) { |
84df43de |
580 | $file = uniqid('m').$file; |
c425472d |
581 | } |
84df43de |
582 | $fp = fopen($dir.$file, 'w'); |
583 | $c = new curl; |
584 | $c->download(array( |
7a3b93c1 |
585 | array('url'=>$url, 'file'=>$fp) |
586 | )); |
84df43de |
587 | return $dir.$file; |
82669dc4 |
588 | } |
1cf56396 |
589 | |
1cf56396 |
590 | /** |
66dc47bc |
591 | * Print a list or return formatted string, can be overridden by subclass |
82669dc4 |
592 | * |
593 | * @param string $list |
3f24ea1e |
594 | * @param boolean $print false, return html, otherwise, print it directly |
8dcd5deb |
595 | * @return <type> |
596 | */ |
fca079c5 |
597 | public function print_listing($listing = array(), $print=true) { |
7a3b93c1 |
598 | if (empty($listing)) { |
0f59046f |
599 | $listing = $this->get_listing(); |
600 | } |
fca079c5 |
601 | if (empty($listing)) { |
602 | $str = ''; |
603 | } else { |
604 | $count = 0; |
605 | $str = '<table>'; |
7a3b93c1 |
606 | foreach ($listing as $v) { |
fca079c5 |
607 | $str .= '<tr id="entry_'.$count.'">'; |
608 | $str .= '<td><input type="checkbox" /></td>'; |
609 | $str .= '<td>'.$v['name'].'</td>'; |
610 | $str .= '<td>'.$v['size'].'</td>'; |
611 | $str .= '<td>'.$v['date'].'</td>'; |
612 | $str .= '</tr>'; |
613 | $count++; |
614 | } |
d1fe3452 |
615 | $str .= '</table>'; |
82669dc4 |
616 | } |
7a3b93c1 |
617 | if ($print) { |
82669dc4 |
618 | echo $str; |
619 | return null; |
620 | } else { |
621 | return $str; |
622 | } |
1cf56396 |
623 | } |
eb239694 |
624 | |
f48fb4d6 |
625 | /** |
626 | * Return is the instance is visible |
627 | * (is the type visible ? is the context enable ?) |
628 | * @return boolean |
629 | */ |
630 | public function is_visible() { |
631 | $type = repository_get_type_by_id($this->typeid); |
632 | $instanceoptions = repository_static_function($type->get_typename(), 'get_instance_option_names'); |
633 | |
634 | if ($type->get_visible()) { |
635 | //if the instance is unique so it's visible, otherwise check if the instance has a enabled context |
636 | if (empty($instanceoptions) || $type->get_contextvisibility($this->context->contextlevel)) { |
637 | return true; |
638 | } |
639 | } |
640 | |
641 | return false; |
642 | } |
643 | |
eb239694 |
644 | /** |
66dc47bc |
645 | * Return the name of this instance, can be overridden. |
eb239694 |
646 | * @global <type> $DB |
647 | * @return <type> |
648 | */ |
7a3b93c1 |
649 | public function get_name() { |
d31af46a |
650 | global $DB; |
651 | // We always verify instance id from database, |
652 | // so we always know repository name before init |
653 | // a repository, so we don't enquery repository |
654 | // name from database again here. |
655 | if (isset($this->options['name'])) { |
656 | return $this->options['name']; |
657 | } else { |
658 | if ( $repo = $DB->get_record('repository_instances', array('id'=>$this->id)) ) { |
659 | return $repo->name; |
660 | } else { |
661 | return ''; |
662 | } |
663 | } |
664 | } |
aa754fe3 |
665 | |
b318bb6d |
666 | /** |
667 | * what kind of files will be in this repository? |
668 | * @return array return '*' means this repository support any files, otherwise |
669 | * return mimetypes of files, it can be an array |
670 | */ |
671 | public function supported_mimetype() { |
672 | // return array('text/plain', 'image/gif'); |
673 | return '*'; |
674 | } |
675 | |
676 | /** |
677 | * does it return a file url or a item_id |
678 | * @return string |
679 | */ |
680 | public function supported_return_value() { |
681 | // return 'link'; |
682 | // return 'ref_id'; |
683 | return '*'; |
684 | } |
685 | |
82669dc4 |
686 | /** |
3f24ea1e |
687 | * Provide repository instance information for Ajax |
8dcd5deb |
688 | * @global object $CFG |
4a65c39a |
689 | * @return object |
82669dc4 |
690 | */ |
b1339e98 |
691 | final public function ajax_info() { |
4a65c39a |
692 | global $CFG; |
693 | $repo = new stdclass; |
27051e43 |
694 | $repo->id = $this->id; |
d31af46a |
695 | $repo->name = $this->get_name(); |
4a65c39a |
696 | $repo->type = $this->options['type']; |
6fe8b022 |
697 | $repo->icon = $CFG->httpswwwroot.'/repository/'.$repo->type.'/icon.png'; |
4a65c39a |
698 | return $repo; |
699 | } |
1cf56396 |
700 | |
b1339e98 |
701 | /** |
702 | * Create an instance for this plug-in |
8dcd5deb |
703 | * @global object $CFG |
704 | * @global object $DB |
705 | * @param string $type the type of the repository |
706 | * @param integer $userid the user id |
707 | * @param object $context the context |
708 | * @param array $params the options for this instance |
709 | * @return <type> |
b1339e98 |
710 | */ |
948c2860 |
711 | final public static function create($type, $userid, $context, $params, $readonly=0) { |
b1339e98 |
712 | global $CFG, $DB; |
713 | $params = (array)$params; |
714 | require_once($CFG->dirroot . '/repository/'. $type . '/repository.class.php'); |
715 | $classname = 'repository_' . $type; |
3023078f |
716 | if ($repo = $DB->get_record('repository', array('type'=>$type))) { |
717 | $record = new stdclass; |
718 | $record->name = $params['name']; |
719 | $record->typeid = $repo->id; |
720 | $record->timecreated = time(); |
721 | $record->timemodified = time(); |
722 | $record->contextid = $context->id; |
948c2860 |
723 | $record->readonly = $readonly; |
3023078f |
724 | $record->userid = $userid; |
725 | $id = $DB->insert_record('repository_instances', $record); |
0a6221f9 |
726 | $options = array(); |
edb50637 |
727 | $configs = call_user_func($classname . '::get_instance_option_names'); |
1e08b5cf |
728 | if (!empty($configs)) { |
729 | foreach ($configs as $config) { |
730 | $options[$config] = $params[$config]; |
731 | } |
3023078f |
732 | } |
3a01a46a |
733 | |
3023078f |
734 | if (!empty($id)) { |
735 | unset($options['name']); |
c9f9f911 |
736 | $instance = repository_get_instance($id); |
3023078f |
737 | $instance->set_option($options); |
738 | return $id; |
739 | } else { |
740 | return null; |
b1339e98 |
741 | } |
b1339e98 |
742 | } else { |
743 | return null; |
744 | } |
745 | } |
8dcd5deb |
746 | |
82669dc4 |
747 | /** |
4a65c39a |
748 | * delete a repository instance |
8dcd5deb |
749 | * @global object $DB |
750 | * @return <type> |
82669dc4 |
751 | */ |
7a3b93c1 |
752 | final public function delete() { |
4a65c39a |
753 | global $DB; |
122defc5 |
754 | $DB->delete_records('repository_instances', array('id'=>$this->id)); |
4a65c39a |
755 | return true; |
756 | } |
8dcd5deb |
757 | |
4a65c39a |
758 | /** |
759 | * Hide/Show a repository |
8dcd5deb |
760 | * @global object $DB |
761 | * @param string $hide |
762 | * @return <type> |
4a65c39a |
763 | */ |
7a3b93c1 |
764 | final public function hide($hide = 'toggle') { |
4a65c39a |
765 | global $DB; |
766 | if ($entry = $DB->get_record('repository', array('id'=>$this->id))) { |
767 | if ($hide === 'toggle' ) { |
768 | if (!empty($entry->visible)) { |
769 | $entry->visible = 0; |
770 | } else { |
771 | $entry->visible = 1; |
772 | } |
773 | } else { |
774 | if (!empty($hide)) { |
775 | $entry->visible = 0; |
776 | } else { |
777 | $entry->visible = 1; |
778 | } |
779 | } |
780 | return $DB->update_record('repository', $entry); |
781 | } |
782 | return false; |
783 | } |
1cf56396 |
784 | |
785 | /** |
82669dc4 |
786 | * Cache login details for repositories |
8dcd5deb |
787 | * @global object $DB |
82669dc4 |
788 | * @param string $username |
789 | * @param string $password |
8dcd5deb |
790 | * @param integer $userid The id of specific user |
791 | * @return integer Id of the record |
1cf56396 |
792 | */ |
b6558c3b |
793 | public function store_login($username = '', $password = '', $userid = 1) { |
fca079c5 |
794 | global $DB; |
795 | |
796 | $repository = new stdclass; |
4a65c39a |
797 | if (!empty($this->id)) { |
798 | $repository->id = $this->id; |
19add4c0 |
799 | } else { |
800 | $repository->userid = $userid; |
801 | $repository->repositorytype = $this->type; |
b6558c3b |
802 | $repository->contextid = $this->context->id; |
19add4c0 |
803 | } |
fca079c5 |
804 | if ($entry = $DB->get_record('repository', $repository)) { |
805 | $repository->id = $entry->id; |
806 | $repository->username = $username; |
807 | $repository->password = $password; |
808 | return $DB->update_record('repository', $repository); |
809 | } else { |
810 | $repository->username = $username; |
811 | $repository->password = $password; |
812 | return $DB->insert_record('repository', $repository); |
813 | } |
1cf56396 |
814 | } |
815 | |
1cf56396 |
816 | /** |
4a65c39a |
817 | * Save settings for repository instance |
8dcd5deb |
818 | * $repo->set_option(array('api_key'=>'f2188bde132', 'name'=>'dongsheng')); |
819 | * @global object $DB |
820 | * @param array $options settings |
4a65c39a |
821 | * @return int Id of the record |
1cf56396 |
822 | */ |
7a3b93c1 |
823 | public function set_option($options = array()) { |
4a65c39a |
824 | global $DB; |
7a3b93c1 |
825 | |
122defc5 |
826 | if (!empty($options['name'])) { |
827 | $r = new object(); |
828 | $r->id = $this->id; |
829 | $r->name = $options['name']; |
830 | $DB->update_record('repository_instances', $r); |
831 | unset($options['name']); |
832 | } |
e53a97d1 |
833 | $result = true; |
27051e43 |
834 | foreach ($options as $name=>$value) { |
835 | if ($id = $DB->get_field('repository_instance_config', 'id', array('name'=>$name, 'instanceid'=>$this->id))) { |
836 | if ($value===null) { |
e53a97d1 |
837 | $result = $result && $DB->delete_records('repository_instance_config', array('name'=>$name, 'instanceid'=>$this->id)); |
27051e43 |
838 | } else { |
e53a97d1 |
839 | $result = $result && $DB->set_field('repository_instance_config', 'value', $value, array('id'=>$id)); |
27051e43 |
840 | } |
841 | } else { |
842 | if ($value===null) { |
843 | return true; |
844 | } |
845 | $config = new object(); |
846 | $config->instanceid = $this->id; |
847 | $config->name = $name; |
848 | $config->value = $value; |
e53a97d1 |
849 | $result = $result && $DB->insert_record('repository_instance_config', $config); |
27051e43 |
850 | } |
4a65c39a |
851 | } |
e53a97d1 |
852 | return $result; |
1cf56396 |
853 | } |
1cf56396 |
854 | |
4a65c39a |
855 | /** |
856 | * Get settings for repository instance |
8dcd5deb |
857 | * @global object $DB |
858 | * @param <type> $config |
4a65c39a |
859 | * @return array Settings |
860 | */ |
7a3b93c1 |
861 | public function get_option($config = '') { |
4a65c39a |
862 | global $DB; |
27051e43 |
863 | $entries = $DB->get_records('repository_instance_config', array('instanceid'=>$this->id)); |
864 | $ret = array(); |
865 | if (empty($entries)) { |
866 | return $ret; |
4a65c39a |
867 | } |
7a3b93c1 |
868 | foreach($entries as $entry) { |
27051e43 |
869 | $ret[$entry->name] = $entry->value; |
4a65c39a |
870 | } |
871 | if (!empty($config)) { |
872 | return $ret[$config]; |
873 | } else { |
874 | return $ret; |
875 | } |
876 | } |
bf1fccf0 |
877 | |
4a65c39a |
878 | /** |
879 | * Given a path, and perhaps a search, get a list of files. |
880 | * |
e6be3a69 |
881 | * The format of the returned array must be: |
f7639c37 |
882 | * array( |
f6812a21 |
883 | * 'path' => (string) path for the current folder |
f7639c37 |
884 | * 'dynload' => (bool) use dynamic loading, |
f6812a21 |
885 | * 'manage' => (string) link to file manager, |
f7639c37 |
886 | * 'nologin' => (bool) requires login, |
d31af46a |
887 | * 'nosearch' => (bool) no search link, |
f7639c37 |
888 | * 'upload' => array( // upload manager |
889 | * 'name' => (string) label of the form element, |
890 | * 'id' => (string) id of the form element |
891 | * ), |
892 | * 'list' => array( |
893 | * array( // file |
894 | * 'title' => (string) file name, |
3c9e53c0 |
895 | * 'date' => (string) file last modification time, usually userdate(...), |
f6812a21 |
896 | * 'size' => (int) file size, |
3c9e53c0 |
897 | * 'thumbnail' => (string) url to thumbnail for the file, |
336bb44b |
898 | * 'source' => plugin-dependent unique path to the file (id, url, path, etc.), |
899 | * 'url'=> the accessible url of file |
f7639c37 |
900 | * ), |
3c9e53c0 |
901 | * array( // folder - same as file, but no 'source'. |
f7639c37 |
902 | * 'title' => (string) folder name, |
f6812a21 |
903 | * 'path' => (string) path to this folder |
3c9e53c0 |
904 | * 'date' => (string) folder last modification time, usually userdate(...), |
f6812a21 |
905 | * 'size' => 0, |
3c9e53c0 |
906 | * 'thumbnail' => (string) url to thumbnail for the folder, |
907 | * 'children' => array( // an empty folder needs to have 'children' defined, but empty. |
908 | * // content (files and folders) |
f7639c37 |
909 | * ) |
e6be3a69 |
910 | * ), |
f7639c37 |
911 | * ) |
912 | * ) |
913 | * |
4a65c39a |
914 | * @param string $parent The parent path, this parameter can |
915 | * a folder name, or a identification of folder |
4a65c39a |
916 | * @return array the list of files, including meta infomation |
917 | */ |
353d5cf3 |
918 | abstract public function get_listing($parent = '/'); |
1cf56396 |
919 | |
fbd508b4 |
920 | /** |
353d5cf3 |
921 | * Search files in repository |
922 | * When doing global search, $search_text will be used as |
923 | * keyword. |
924 | * |
fbd508b4 |
925 | * @return mixed, see get_listing() |
926 | */ |
353d5cf3 |
927 | public function search($search_text) { |
928 | $list = array(); |
929 | $list['list'] = array(); |
930 | return false; |
fbd508b4 |
931 | } |
932 | |
d68c527f |
933 | /** |
934 | * Logout from repository instance |
935 | * By default, this function will return a login form |
936 | * |
937 | * @return string |
938 | */ |
939 | public function logout(){ |
940 | return $this->print_login(); |
941 | } |
942 | |
943 | /** |
944 | * To check whether the user is logged in. |
945 | * |
946 | * @return boolean |
947 | */ |
948 | public function check_login(){ |
949 | return true; |
950 | } |
951 | |
1cf56396 |
952 | |
4a65c39a |
953 | /** |
954 | * Show the login screen, if required |
955 | * This is an abstract function, it must be overriden. |
4a65c39a |
956 | */ |
1d66f2b2 |
957 | public function print_login(){ |
958 | return $this->get_listing(); |
959 | } |
1cf56396 |
960 | |
4a65c39a |
961 | /** |
962 | * Show the search screen, if required |
4a65c39a |
963 | * @return null |
964 | */ |
2b9feb5f |
965 | public function print_search() { |
966 | echo '<input type="hidden" name="repo_id" value="'.$this->id.'" />'; |
967 | echo '<input type="hidden" name="ctx_id" value="'.$this->context->id.'" />'; |
968 | echo '<input type="hidden" name="seekey" value="'.sesskey().'" />'; |
8d419e59 |
969 | echo '<label>'.get_string('keyword', 'repository').': </label><br/><input name="s" value="" /><br/>'; |
2b9feb5f |
970 | return true; |
971 | } |
4a65c39a |
972 | |
455860ce |
973 | /** |
974 | * is it possible to do glboal search? |
975 | * @return boolean |
976 | */ |
7a3b93c1 |
977 | public function global_search() { |
455860ce |
978 | return false; |
979 | } |
980 | |
8dcd5deb |
981 | /** |
a6600395 |
982 | * Defines operations that happen occasionally on cron |
8dcd5deb |
983 | * @return <type> |
984 | */ |
a6600395 |
985 | public function cron() { |
986 | return true; |
987 | } |
988 | |
7892948d |
989 | /** |
83a018ed |
990 | * function which is run when the type is created (moodle administrator add the plugin) |
3e0794ed |
991 | * @return boolean success or fail? |
7892948d |
992 | */ |
948c2860 |
993 | public static function plugin_init(){ |
3e0794ed |
994 | return true; |
7892948d |
995 | } |
996 | |
a6600395 |
997 | /** |
06e65e1e |
998 | * Edit/Create Admin Settings Moodle form |
999 | * @param object $ Moodle form (passed by reference) |
a6600395 |
1000 | */ |
daff8f50 |
1001 | public function type_config_form(&$mform) { |
4a65c39a |
1002 | } |
06e65e1e |
1003 | |
1004 | /** |
1005 | * Edit/Create Instance Settings Moodle form |
1006 | * @param object $ Moodle form (passed by reference) |
a6600395 |
1007 | */ |
06e65e1e |
1008 | public function instance_config_form(&$mform) { |
a6600395 |
1009 | } |
4a65c39a |
1010 | |
a6600395 |
1011 | /** |
1012 | * Return names of the general options |
1013 | * By default: no general option name |
1014 | * @return array |
1015 | */ |
1b79955a |
1016 | public static function get_type_option_names() { |
a6600395 |
1017 | return array(); |
1018 | } |
1019 | |
1020 | /** |
1021 | * Return names of the instance options |
1022 | * By default: no instance option name |
1023 | * @return array |
1024 | */ |
7a3b93c1 |
1025 | public static function get_instance_option_names() { |
a6600395 |
1026 | return array(); |
8b65d45c |
1027 | } |
119a4ae1 |
1028 | |
ce5e846c |
1029 | /** |
1030 | * Override it if you need to implement need mnet function |
1031 | * @return array |
1032 | */ |
119a4ae1 |
1033 | public static function mnet_publishes() { |
1034 | return array(); |
1035 | } |
1036 | |
8b65d45c |
1037 | } |
837ebb78 |
1038 | |
1039 | /** |
4a65c39a |
1040 | * exception class for repository api |
837ebb78 |
1041 | */ |
4a65c39a |
1042 | class repository_exception extends moodle_exception { |
8b65d45c |
1043 | } |
4ed43890 |
1044 | |
2057487c |
1045 | /** |
1046 | * Check context |
1047 | * @param int $ctx_id |
1048 | * @return boolean |
1049 | */ |
7a3b93c1 |
1050 | function repository_check_context($ctx_id) { |
2057487c |
1051 | global $USER; |
7a3b93c1 |
1052 | |
2057487c |
1053 | $context = get_context_instance_by_id($ctx_id); |
1054 | $level = $context->contextlevel; |
7a3b93c1 |
1055 | |
2057487c |
1056 | if ($level == CONTEXT_COURSE) { |
1057 | if (!has_capability('moodle/course:view', $context)) { |
1058 | return false; |
1059 | } else { |
1060 | return true; |
1061 | } |
7a3b93c1 |
1062 | } else if ($level == CONTEXT_USER) { |
2057487c |
1063 | $c = get_context_instance(CONTEXT_USER, $USER->id); |
1064 | if ($c->id == $ctx_id) { |
1065 | return true; |
1066 | } else { |
1067 | return false; |
1068 | } |
7a3b93c1 |
1069 | } else if ($level == CONTEXT_SYSTEM) { |
2057487c |
1070 | // it is always ok in system level |
70fbd90e |
1071 | return true; |
2057487c |
1072 | } |
1073 | return false; |
1074 | } |
4a65c39a |
1075 | |
bbcd4860 |
1076 | /** |
1077 | * Return all types that you a user can create/edit and which are also visible |
8f943eba |
1078 | * Note: Mostly used in order to know if at least one editable type can be set |
f48fb4d6 |
1079 | * @param object $context the context for which we want the editable types |
bbcd4860 |
1080 | * @return array types |
1081 | */ |
f48fb4d6 |
1082 | function repository_get_editable_types($context = null) { |
1083 | |
1084 | if (empty($context)) { |
1085 | $context = get_system_context(); |
1086 | } |
1087 | |
bbcd4860 |
1088 | $types= repository_get_types(true); |
1089 | $editabletypes = array(); |
7a3b93c1 |
1090 | foreach ($types as $type) { |
edb50637 |
1091 | $instanceoptionnames = repository_static_function($type->get_typename(), 'get_instance_option_names'); |
1092 | if (!empty($instanceoptionnames)) { |
f48fb4d6 |
1093 | if ($type->get_contextvisibility($context->contextlevel)) { |
1094 | $editabletypes[]=$type; |
1095 | } |
1096 | } |
bbcd4860 |
1097 | } |
1098 | return $editabletypes; |
1099 | } |
1100 | |
837ebb78 |
1101 | /** |
4a65c39a |
1102 | * Return repository instances |
8dcd5deb |
1103 | * @global object $DB |
1104 | * @global object $CFG |
1105 | * @global object $USER |
12c79bfd |
1106 | * @param object $contexts contexts for which the instances are set |
8dcd5deb |
1107 | * @param integer $userid |
46dd6bb0 |
1108 | * @param boolean $onlyvisible if visible == true, return visible instances only, |
4a65c39a |
1109 | * otherwise, return all instances |
a6600395 |
1110 | * @param string $type a type name to retrieve |
b318bb6d |
1111 | * @param string $filetypes supported file types |
1112 | * @param string $returnvalue supportted returned value |
4a65c39a |
1113 | * @return array repository instances |
837ebb78 |
1114 | */ |
b318bb6d |
1115 | function repository_get_instances($contexts=array(), $userid = null, $onlyvisible = true, $type=null, $filetypes = '*', $returnvalue = '*') { |
38e55442 |
1116 | global $DB, $CFG, $USER; |
7a3b93c1 |
1117 | |
38e55442 |
1118 | $params = array(); |
1265fc59 |
1119 | $sql = 'SELECT i.*, r.type AS repositorytype, r.sortorder, r.visible FROM {repository} r, {repository_instances} i WHERE '; |
46dd6bb0 |
1120 | $sql .= 'i.typeid = r.id '; |
7a3b93c1 |
1121 | |
4a65c39a |
1122 | if (!empty($userid) && is_numeric($userid)) { |
46dd6bb0 |
1123 | $sql .= ' AND (i.userid = 0 or i.userid = ?)'; |
4a65c39a |
1124 | $params[] = $userid; |
1125 | } |
7a3b93c1 |
1126 | |
12c79bfd |
1127 | foreach ($contexts as $context) { |
7a3b93c1 |
1128 | if (empty($firstcontext)) { |
12c79bfd |
1129 | $firstcontext = true; |
1130 | $sql .= ' AND ((i.contextid = ?)'; |
46dd6bb0 |
1131 | } else { |
12c79bfd |
1132 | $sql .= ' OR (i.contextid = ?)'; |
46dd6bb0 |
1133 | } |
12c79bfd |
1134 | $params[] = $context->id; |
38e55442 |
1135 | } |
7a3b93c1 |
1136 | |
7892948d |
1137 | if (!empty($firstcontext)) { |
1138 | $sql .=')'; |
12c79bfd |
1139 | } |
aca64b79 |
1140 | |
7a3b93c1 |
1141 | if ($onlyvisible == true) { |
4a65c39a |
1142 | $sql .= ' AND (r.visible = 1)'; |
1143 | } |
7a3b93c1 |
1144 | |
1145 | if (isset($type)) { |
a6600395 |
1146 | $sql .= ' AND (r.type = ?)'; |
1147 | $params[] = $type; |
1148 | } |
1265fc59 |
1149 | $sql .= ' order by r.sortorder, i.name'; |
7a3b93c1 |
1150 | |
1151 | if (!$repos = $DB->get_records_sql($sql, $params)) { |
38e55442 |
1152 | $repos = array(); |
1153 | } |
7a3b93c1 |
1154 | |
4a65c39a |
1155 | $ret = array(); |
7a3b93c1 |
1156 | foreach ($repos as $repo) { |
1157 | require_once($CFG->dirroot . '/repository/'. $repo->repositorytype.'/repository.class.php'); |
27051e43 |
1158 | $options['visible'] = $repo->visible; |
1159 | $options['name'] = $repo->name; |
1160 | $options['type'] = $repo->repositorytype; |
1161 | $options['typeid'] = $repo->typeid; |
f48fb4d6 |
1162 | $classname = 'repository_' . $repo->repositorytype;// |
1163 | |
1164 | $repository = new $classname($repo->id, $repo->contextid, $options, $repo->readonly); |
b318bb6d |
1165 | if ($filetypes !== '*' and $repository->supported_mimetype() !== '*') { |
1166 | $mimetypes = $repository->supported_mimetype(); |
1167 | $is_supported = false; |
1168 | foreach ($mimetypes as $type) { |
1169 | if (in_array($type, $filetypes)) { |
1170 | $is_supported = true; |
1171 | } |
1172 | } |
1173 | if (!$is_supported) { |
1174 | continue; |
1175 | } |
1176 | } |
1177 | if ($returnvalue !== '*' and $repository->supported_return_value() !== '*') { |
1178 | $tmp = $repository->supported_return_value(); |
1179 | if ($tmp == $returnvalue) { |
1180 | continue; |
1181 | } |
1182 | } |
efe018b4 |
1183 | if (!$onlyvisible || ($repository->is_visible() && !$repository->disabled)) { |
f48fb4d6 |
1184 | $ret[] = $repository; |
1185 | } |
4a65c39a |
1186 | } |
1187 | return $ret; |
38e55442 |
1188 | } |
4ed43890 |
1189 | |
837ebb78 |
1190 | /** |
1191 | * Get single repository instance |
8dcd5deb |
1192 | * @global object $DB |
1193 | * @global object $CFG |
1194 | * @param integer $id repository id |
837ebb78 |
1195 | * @return object repository instance |
1196 | */ |
7a3b93c1 |
1197 | function repository_get_instance($id) { |
19add4c0 |
1198 | global $DB, $CFG; |
27051e43 |
1199 | $sql = 'SELECT i.*, r.type AS repositorytype, r.visible FROM {repository} r, {repository_instances} i WHERE '; |
1200 | $sql .= 'i.typeid = r.id AND '; |
1201 | $sql .= 'i.id = '.$id; |
19add4c0 |
1202 | |
27051e43 |
1203 | if(!$instance = $DB->get_record_sql($sql)) { |
19add4c0 |
1204 | return false; |
1205 | } |
e6be3a69 |
1206 | require_once($CFG->dirroot . '/repository/'. $instance->repositorytype |
7a3b93c1 |
1207 | . '/repository.class.php'); |
19add4c0 |
1208 | $classname = 'repository_' . $instance->repositorytype; |
27051e43 |
1209 | $options['typeid'] = $instance->typeid; |
1210 | $options['type'] = $instance->repositorytype; |
1211 | $options['name'] = $instance->name; |
948c2860 |
1212 | return new $classname($instance->id, $instance->contextid, $options, $instance->readonly); |
19add4c0 |
1213 | } |
837ebb78 |
1214 | |
8dcd5deb |
1215 | /** |
66dc47bc |
1216 | * call a static function |
8dcd5deb |
1217 | * @global <type> $CFG |
1218 | * @param <type> $plugin |
1219 | * @param <type> $function |
a6600395 |
1220 | * @param type $nocallablereturnvalue default value if function not found |
1221 | * it's mostly used when you don't want to display an error but |
1222 | * return a boolean |
8dcd5deb |
1223 | * @return <type> |
1224 | */ |
4a65c39a |
1225 | function repository_static_function($plugin, $function) { |
97f7393d |
1226 | global $CFG; |
4a65c39a |
1227 | |
a6600395 |
1228 | //check that the plugin exists |
1229 | $typedirectory = $CFG->dirroot . '/repository/'. $plugin . '/repository.class.php'; |
7a3b93c1 |
1230 | if (!file_exists($typedirectory)) { |
1231 | throw new repository_exception('invalidplugin', 'repository'); |
a6600395 |
1232 | } |
1233 | |
4a65c39a |
1234 | $pname = null; |
1235 | if (is_object($plugin) || is_array($plugin)) { |
1236 | $plugin = (object)$plugin; |
1237 | $pname = $plugin->name; |
1238 | } else { |
1239 | $pname = $plugin; |
97f7393d |
1240 | } |
4a65c39a |
1241 | |
1242 | $args = func_get_args(); |
1243 | if (count($args) <= 2) { |
1244 | $args = array(); |
1245 | } |
1246 | else { |
1247 | array_shift($args); |
1248 | array_shift($args); |
1249 | } |
1250 | |
a6600395 |
1251 | require_once($typedirectory); |
4a65c39a |
1252 | return call_user_func_array(array('repository_' . $plugin, $function), $args); |
97f7393d |
1253 | } |
d8eb6e18 |
1254 | |
837ebb78 |
1255 | /** |
1256 | * Move file from download folder to file pool using FILE API |
8dcd5deb |
1257 | * @global object $DB |
1258 | * @global object $CFG |
1259 | * @global object $USER |
1260 | * @param string $path file path in download folder |
1261 | * @param string $name file name |
1262 | * @param integer $itemid item id to identify a file in filepool |
1263 | * @param string $filearea file area |
837ebb78 |
1264 | * @return array information of file in file pool |
1265 | */ |
c9260130 |
1266 | function repository_move_to_filepool($path, $name, $itemid, $filearea = 'user_draft') { |
d8eb6e18 |
1267 | global $DB, $CFG, $USER; |
1268 | $context = get_context_instance(CONTEXT_USER, $USER->id); |
313cc398 |
1269 | $now = time(); |
d8eb6e18 |
1270 | $entry = new object(); |
55b4bb1d |
1271 | $entry->filearea = $filearea; |
d8eb6e18 |
1272 | $entry->contextid = $context->id; |
1273 | $entry->filename = $name; |
c9260130 |
1274 | $entry->filepath = '/'.uniqid().'/'; |
313cc398 |
1275 | $entry->timecreated = $now; |
1276 | $entry->timemodified = $now; |
c2762f06 |
1277 | if(is_numeric($itemid)) { |
1278 | $entry->itemid = $itemid; |
1279 | } else { |
1280 | $entry->itemid = 0; |
1281 | } |
d8eb6e18 |
1282 | $entry->mimetype = mimeinfo('type', $path); |
1283 | $entry->userid = $USER->id; |
1284 | $fs = get_file_storage(); |
1285 | $browser = get_file_browser(); |
1286 | if ($file = $fs->create_file_from_pathname($entry, $path)) { |
c9260130 |
1287 | $delete = unlink($path); |
d8eb6e18 |
1288 | $ret = $browser->get_file_info($context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename()); |
7a3b93c1 |
1289 | if(!empty($ret)) { |
c0fa8cba |
1290 | return array('url'=>$ret->get_url(),'id'=>$file->get_itemid(), 'file'=>$file->get_filename()); |
3023078f |
1291 | } else { |
1292 | return null; |
1293 | } |
d8eb6e18 |
1294 | } else { |
1295 | return null; |
1296 | } |
1297 | } |
1298 | |
1e08b5cf |
1299 | function repository_download_btn($repo_id, $ctx_id, $sesskey, $title, $src, $returnurl = '') { |
1300 | global $CFG; |
1301 | if (empty($returnurl)) { |
1302 | $returnurl = get_referer(); |
1303 | } |
1304 | $str = '<form action="'.$CFG->httpswwwroot.'/repository/ws.php">'; |
1305 | $str .= ' <input type="hidden" name="sesskey" value="'.$sesskey.'" />'; |
1306 | $str .= ' <input type="hidden" name="ctx_id" value="'.$ctx_id.'" />'; |
1307 | $str .= ' <input type="hidden" name="repo_id" value="'.$repo_id.'" />'; |
1308 | $str .= ' <input type="hidden" name="file" value="'.$src.'" />'; |
1309 | $str .= ' <input type="hidden" name="action" value="download" />'; |
1310 | $str .= ' <input type="hidden" name="returnurl" value="'.$returnurl.'" />'; |
1311 | $str .= ' <input type="text" name="title" value="'.$title.'" />'; |
1312 | $str .= ' <input type="submit" value="Select it!" />'; |
1313 | $str .= '</form>'; |
1314 | return $str; |
1315 | } |
1316 | |
5a3b9db9 |
1317 | /** |
1318 | * Save file to local filesystem pool |
1319 | * @param string $elname name of element |
5a3b9db9 |
1320 | * @param string $filearea |
1321 | * @param string $filepath |
1322 | * @param string $filename - use specified filename, if not specified name of uploaded file used |
1323 | * @param bool $override override file if exists |
5a3b9db9 |
1324 | * @return mixed stored_file object or false if error; may throw exception if duplicate found |
1325 | */ |
313cc398 |
1326 | function repository_store_to_filepool($elname, $filearea='user_draft', $filepath='/', $filename = '', $override = false) { |
5a3b9db9 |
1327 | global $USER; |
1328 | if (!isset($_FILES[$elname])) { |
1329 | return false; |
1330 | } |
1331 | |
313cc398 |
1332 | if (!$filename) { |
1333 | $filename = $_FILES[$elname]['name']; |
1334 | } |
5a3b9db9 |
1335 | $context = get_context_instance(CONTEXT_USER, $USER->id); |
1336 | $itemid = (int)substr(hexdec(uniqid()), 0, 9)+rand(1,100); |
1337 | $fs = get_file_storage(); |
1338 | $browser = get_file_browser(); |
1339 | |
1340 | if ($file = $fs->get_file($context->id, $filearea, $itemid, $filepath, $filename)) { |
1341 | if ($override) { |
1342 | $file->delete(); |
1343 | } else { |
1344 | return false; |
1345 | } |
1346 | } |
1347 | |
1348 | $file_record = new object(); |
1349 | $file_record->contextid = $context->id; |
1350 | $file_record->filearea = $filearea; |
1351 | $file_record->itemid = $itemid; |
1352 | $file_record->filepath = $filepath; |
1353 | $file_record->filename = $filename; |
1354 | $file_record->userid = $USER->id; |
1355 | |
1356 | $file = $fs->create_file_from_pathname($file_record, $_FILES[$elname]['tmp_name']); |
1357 | $info = $browser->get_file_info($context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename()); |
1358 | $ret = array('url'=>$info->get_url(),'id'=>$itemid, 'file'=>$file->get_filename()); |
1359 | return $ret; |
1360 | } |
1361 | |
e3ca0f3a |
1362 | /** |
1363 | * Return the user arborescence in a format to be returned by the function get_listing |
1364 | * @global <type> $CFG |
1365 | * @param <type> $search |
1366 | * @return <type> |
1367 | */ |
1368 | function repository_get_user_file_tree($search = ""){ |
1369 | global $CFG; |
1370 | $ret = array(); |
1371 | $ret['nologin'] = true; |
1372 | $ret['manage'] = $CFG->wwwroot .'/files/index.php'; // temporary |
1373 | $browser = get_file_browser(); |
1374 | $itemid = null; |
1375 | $filename = null; |
1376 | $filearea = null; |
1377 | $path = '/'; |
1378 | $ret['dynload'] = false; |
1379 | |
1380 | if ($fileinfo = $browser->get_file_info(get_system_context(), $filearea, $itemid, $path, $filename)) { |
1381 | |
1382 | $ret['path'] = array(); |
1383 | $params = $fileinfo->get_params(); |
1384 | $filearea = $params['filearea']; |
1385 | $ret['path'][] = repository_encode_path($filearea, $path, $fileinfo->get_visible_name()); |
1386 | if ($fileinfo->is_directory()) { |
1387 | $level = $fileinfo->get_parent(); |
1388 | while ($level) { |
1389 | $params = $level->get_params(); |
1390 | $ret['path'][] = repository_encode_path($params['filearea'], $params['filepath'], $level->get_visible_name()); |
1391 | $level = $level->get_parent(); |
1392 | } |
1393 | } |
1394 | $filecount = repository_build_tree($fileinfo, $search, $ret['dynload'], $ret['list']); |
1395 | $ret['path'] = array_reverse($ret['path']); |
1396 | } |
1397 | |
1398 | if (empty($ret['list'])) { |
1399 | //exit(mnet_server_fault(9016, get_string('emptyfilelist', 'repository_local'))); |
1400 | throw new Exception('emptyfilelist'); |
1401 | } else { |
1402 | return $ret; |
1403 | } |
1404 | |
1405 | } |
1406 | |
1407 | /** |
1408 | * |
1409 | * @param <type> $filearea |
1410 | * @param <type> $path |
1411 | * @param <type> $visiblename |
1412 | * @return <type> |
1413 | */ |
1414 | function repository_encode_path($filearea, $path, $visiblename) { |
1415 | return array('path'=>serialize(array($filearea, $path)), 'name'=>$visiblename); |
1416 | } |
1417 | |
1418 | /** |
1419 | * Builds a tree of files This function is |
1420 | * then called recursively. |
1421 | * |
1422 | * @param $fileinfo an object returned by file_browser::get_file_info() |
1423 | * @param $search searched string |
1424 | * @param $dynamicmode bool no recursive call is done when in dynamic mode |
1425 | * @param $list - the array containing the files under the passed $fileinfo |
1426 | * @returns int the number of files found |
1427 | * |
1428 | * todo: take $search into account, and respect a threshold for dynamic loading |
1429 | */ |
1430 | function repository_build_tree($fileinfo, $search, $dynamicmode, &$list) { |
1431 | global $CFG; |
1432 | |
1433 | $filecount = 0; |
1434 | $children = $fileinfo->get_children(); |
1435 | |
1436 | foreach ($children as $child) { |
1437 | $filename = $child->get_visible_name(); |
1438 | $filesize = $child->get_filesize(); |
1439 | $filesize = $filesize ? display_size($filesize) : ''; |
1440 | $filedate = $child->get_timemodified(); |
1441 | $filedate = $filedate ? userdate($filedate) : ''; |
1442 | $filetype = $child->get_mimetype(); |
1443 | |
1444 | if ($child->is_directory()) { |
1445 | $path = array(); |
1446 | $level = $child->get_parent(); |
1447 | while ($level) { |
1448 | $params = $level->get_params(); |
1449 | $path[] = repository_encode_path($params['filearea'], $params['filepath'], $level->get_visible_name()); |
1450 | $level = $level->get_parent(); |
1451 | } |
1452 | |
1453 | $tmp = array( |
1454 | 'title' => $child->get_visible_name(), |
1455 | 'size' => 0, |
1456 | 'date' => $filedate, |
1457 | 'path' => array_reverse($path), |
1458 | 'thumbnail' => $CFG->pixpath .'/f/folder.gif' |
1459 | ); |
1460 | |
1461 | //if ($dynamicmode && $child->is_writable()) { |
1462 | // $tmp['children'] = array(); |
1463 | //} else { |
1464 | // if folder name matches search, we send back all files contained. |
3a01a46a |
1465 | $_search = $search; |
1466 | if ($search && stristr($tmp['title'], $search) !== false) { |
1467 | $_search = false; |
1468 | } |
1469 | $tmp['children'] = array(); |
1470 | $_filecount = repository_build_tree($child, $_search, $dynamicmode, $tmp['children']); |
1471 | if ($search && $_filecount) { |
1472 | $tmp['expanded'] = 1; |
1473 | } |
e3ca0f3a |
1474 | |
1475 | //} |
1476 | |
3a01a46a |
1477 | //Uncomment this following line if you wanna display all directory ()even empty |
1478 | //if (!$search || $_filecount || (stristr($tmp['title'], $search) !== false)) { |
1479 | if ($_filecount) { |
e3ca0f3a |
1480 | $filecount += $_filecount; |
3a01a46a |
1481 | $list[] = $tmp; |
e3ca0f3a |
1482 | } |
1483 | |
1484 | } else { // not a directory |
1485 | // skip the file, if we're in search mode and it's not a match |
1486 | if ($search && (stristr($filename, $search) === false)) { |
1487 | continue; |
1488 | } |
1489 | $params = $child->get_params(); |
1490 | $source = serialize(array($params['contextid'], $params['filearea'], $params['itemid'], $params['filepath'], $params['filename'])); |
1491 | $list[] = array( |
1492 | 'title' => $filename, |
1493 | 'size' => $filesize, |
1494 | 'date' => $filedate, |
1495 | //'source' => $child->get_url(), |
1496 | 'source' => base64_encode($source), |
1497 | 'thumbnail' => $CFG->pixpath .'/f/'. mimeinfo_from_type("icon", $filetype) |
1498 | ); |
1499 | $filecount++; |
1500 | } |
1501 | } |
1502 | |
1503 | return $filecount; |
1504 | } |
1505 | |
1506 | |
8dcd5deb |
1507 | /** |
1508 | * TODO: write comment |
1509 | */ |
a6600395 |
1510 | final class repository_instance_form extends moodleform { |
4a65c39a |
1511 | protected $instance; |
1512 | protected $plugin; |
1513 | |
8dcd5deb |
1514 | /** |
1515 | * TODO: write comment |
1516 | * @global <type> $CFG |
1517 | */ |
4a65c39a |
1518 | public function definition() { |
1519 | global $CFG; |
1520 | // type of plugin, string |
1521 | $this->plugin = $this->_customdata['plugin']; |
27051e43 |
1522 | $this->typeid = $this->_customdata['typeid']; |
faaa613d |
1523 | $this->contextid = $this->_customdata['contextid']; |
4a65c39a |
1524 | $this->instance = (isset($this->_customdata['instance']) |
1525 | && is_subclass_of($this->_customdata['instance'], 'repository')) |
1526 | ? $this->_customdata['instance'] : null; |
1527 | |
1528 | $mform =& $this->_form; |
1529 | $strrequired = get_string('required'); |
1530 | |
1531 | $mform->addElement('hidden', 'edit', ($this->instance) ? $this->instance->id : 0); |
1532 | $mform->addElement('hidden', 'new', $this->plugin); |
1533 | $mform->addElement('hidden', 'plugin', $this->plugin); |
27051e43 |
1534 | $mform->addElement('hidden', 'typeid', $this->typeid); |
faaa613d |
1535 | $mform->addElement('hidden', 'contextid', $this->contextid); |
4a65c39a |
1536 | |
1537 | $mform->addElement('text', 'name', get_string('name'), 'maxlength="100" size="30"'); |
1538 | $mform->addRule('name', $strrequired, 'required', null, 'client'); |
1539 | |
1e97f196 |
1540 | |
f48fb4d6 |
1541 | //add fields |
1542 | if (!$this->instance) { |
1543 | $result = repository_static_function($this->plugin, 'instance_config_form', $mform); |
1544 | } |
1545 | else { |
1546 | $data = array(); |
1547 | $data['name'] = $this->instance->name; |
1548 | if (!$this->instance->readonly) { |
1549 | $result = $this->instance->instance_config_form($mform); |
1550 | // and set the data if we have some. |
1e97f196 |
1551 | foreach ($this->instance->get_instance_option_names() as $config) { |
1552 | if (!empty($this->instance->$config)) { |
1553 | $data[$config] = $this->instance->$config; |
1554 | } else { |
1555 | $data[$config] = ''; |
1556 | } |
27051e43 |
1557 | } |
4a65c39a |
1558 | } |
f48fb4d6 |
1559 | $this->set_data($data); |
1e97f196 |
1560 | } |
1561 | |
46dd6bb0 |
1562 | $this->add_action_buttons(true, get_string('save','repository')); |
4a65c39a |
1563 | } |
1564 | |
8dcd5deb |
1565 | /** |
1566 | * TODO: write comment |
1567 | * @global <type> $DB |
1568 | * @param <type> $data |
1569 | * @return <type> |
1570 | */ |
4a65c39a |
1571 | public function validation($data) { |
1572 | global $DB; |
1573 | |
1574 | $errors = array(); |
27051e43 |
1575 | if ($DB->count_records('repository_instances', array('name' => $data['name'], 'typeid' => $data['typeid'])) > 1) { |
4a65c39a |
1576 | $errors = array('name' => get_string('err_uniquename', 'repository')); |
1577 | } |
1578 | |
4a65c39a |
1579 | return $errors; |
1580 | } |
1581 | } |
a6600395 |
1582 | |
1583 | |
1584 | /** |
1585 | * Display a form with the general option fields of a type |
1586 | */ |
c295f9ff |
1587 | final class repository_type_form extends moodleform { |
a6600395 |
1588 | protected $instance; |
1589 | protected $plugin; |
1590 | |
1591 | /** |
1592 | * Definition of the moodleform |
1593 | * @global object $CFG |
1594 | */ |
1595 | public function definition() { |
1596 | global $CFG; |
1597 | // type of plugin, string |
1598 | $this->plugin = $this->_customdata['plugin']; |
1599 | $this->instance = (isset($this->_customdata['instance']) |
1600 | && is_a($this->_customdata['instance'], 'repository_type')) |
1601 | ? $this->_customdata['instance'] : null; |
1602 | |
1603 | $mform =& $this->_form; |
1604 | $strrequired = get_string('required'); |
4d5948f1 |
1605 | |
a6600395 |
1606 | $mform->addElement('hidden', 'edit', ($this->instance) ? $this->instance->get_typename() : 0); |
1607 | $mform->addElement('hidden', 'new', $this->plugin); |
1608 | $mform->addElement('hidden', 'plugin', $this->plugin); |
8f943eba |
1609 | |
06e65e1e |
1610 | // let the plugin add its specific fields |
1611 | if (!$this->instance) { |
daff8f50 |
1612 | $result = repository_static_function($this->plugin, 'type_config_form', $mform); |
a6600395 |
1613 | } else { |
7a3b93c1 |
1614 | $classname = 'repository_' . $this->instance->get_typename(); |
daff8f50 |
1615 | $result = call_user_func(array($classname,'type_config_form'),$mform); |
a6600395 |
1616 | } |
1617 | |
f48fb4d6 |
1618 | //add "enable course/user instances" checkboxes if multiple instances are allowed |
1619 | $instanceoptionnames = repository_static_function($this->plugin, 'get_instance_option_names'); |
1620 | if (!empty($instanceoptionnames)){ |
1621 | $mform->addElement('checkbox', 'enablecourseinstances', get_string('enablecourseinstances', 'repository')); |
1622 | $mform->addElement('checkbox', 'enableuserinstances', get_string('enableuserinstances', 'repository')); |
1623 | } |
1624 | |
1625 | // set the data if we have some. |
a6600395 |
1626 | if ($this->instance) { |
1627 | $data = array(); |
1b79955a |
1628 | $option_names = call_user_func(array($classname,'get_type_option_names')); |
f48fb4d6 |
1629 | if (!empty($instanceoptionnames)){ |
1630 | $option_names[] = 'enablecourseinstances'; |
1631 | $option_names[] = 'enableuserinstances'; |
1632 | } |
1633 | |
a6600395 |
1634 | $instanceoptions = $this->instance->get_options(); |
1635 | foreach ($option_names as $config) { |
1636 | if (!empty($instanceoptions[$config])) { |
1637 | $data[$config] = $instanceoptions[$config]; |
1638 | } else { |
1639 | $data[$config] = ''; |
1640 | } |
1641 | } |
1642 | $this->set_data($data); |
1643 | } |
f48fb4d6 |
1644 | |
46dd6bb0 |
1645 | $this->add_action_buttons(true, get_string('save','repository')); |
a6600395 |
1646 | } |
a6600395 |
1647 | } |
1648 | |
1649 | |
1650 | /** |
1651 | * Display a repository instance list (with edit/delete/create links) |
1652 | * @global object $CFG |
1653 | * @global object $USER |
1654 | * @param object $context the context for which we display the instance |
a6600395 |
1655 | * @param string $typename if set, we display only one type of instance |
1656 | */ |
7a3b93c1 |
1657 | function repository_display_instances_list($context, $typename = null) { |
1658 | global $CFG, $USER; |
2a06d06e |
1659 | |
7a3b93c1 |
1660 | $output = print_box_start('generalbox','',true); |
1661 | //if the context is SYSTEM, so we call it from administration page |
1662 | $admin = ($context->id == SYSCONTEXTID) ? true : false; |
1663 | if ($admin) { |
1664 | $baseurl = $CFG->httpswwwroot . '/admin/repositoryinstance.php?sesskey=' . sesskey(); |
1665 | $output .= "<div ><h2 style='text-align: center'>" . get_string('siteinstances', 'repository') . " "; |
1666 | $output .= "</h2></div>"; |
1667 | } else { |
1668 | $baseurl = $CFG->httpswwwroot . '/repository/manage_instances.php?contextid=' . $context->id . '&sesskey=' . sesskey(); |
1669 | } |
1670 | |
1671 | $namestr = get_string('name'); |
1672 | $pluginstr = get_string('plugin', 'repository'); |
1673 | $settingsstr = get_string('settings'); |
1674 | $deletestr = get_string('delete'); |
1675 | $updown = get_string('updown', 'repository'); |
7a3b93c1 |
1676 | //retrieve list of instances. In administration context we want to display all |
1677 | //instances of a type, even if this type is not visible. In course/user context we |
1678 | //want to display only visible instances, but for every type types. The repository_get_instances() |
1679 | //third parameter displays only visible type. |
1680 | $instances = repository_get_instances(array($context),null,!$admin,$typename); |
1681 | $instancesnumber = count($instances); |
1682 | $alreadyplugins = array(); |
1683 | |
1684 | $table = new StdClass; |
1685 | $table->head = array($namestr, $pluginstr, $deletestr, $settingsstr); |
1686 | $table->align = array('left', 'left', 'center','center'); |
1687 | $table->data = array(); |
1688 | |
1689 | $updowncount = 1; |
1690 | |
1691 | foreach ($instances as $i) { |
1692 | $settings = ''; |
948c2860 |
1693 | $delete = ''; |
1e97f196 |
1694 | $settings .= '<a href="' . $baseurl . '&type='.$typename.'&edit=' . $i->id . '">' . $settingsstr . '</a>' . "\n"; |
948c2860 |
1695 | if (!$i->readonly) { |
948c2860 |
1696 | $delete .= '<a href="' . $baseurl . '&type='.$typename.'&delete=' . $i->id . '">' . $deletestr . '</a>' . "\n"; |
1697 | } |
7a3b93c1 |
1698 | |
1699 | $type = repository_get_type_by_id($i->typeid); |
1700 | $table->data[] = array($i->name, $type->get_readablename(), $delete, $settings); |
1701 | |
1702 | //display a grey row if the type is defined as not visible |
1703 | if (isset($type) && !$type->get_visible()) { |
1704 | $table->rowclass[] = 'dimmed_text'; |
1705 | } else { |
1706 | $table->rowclass[] = ''; |
1707 | } |
1708 | |
1709 | if (!in_array($i->name, $alreadyplugins)) { |
1710 | $alreadyplugins[] = $i->name; |
1711 | } |
1712 | } |
1713 | $output .= print_table($table, true); |
1714 | $instancehtml = '<div>'; |
1715 | $addable = 0; |
1716 | |
1717 | //if no type is set, we can create all type of instance |
1718 | if (!$typename) { |
1719 | $instancehtml .= '<h3>'; |
1720 | $instancehtml .= get_string('createrepository', 'repository'); |
1721 | $instancehtml .= '</h3><ul>'; |
f48fb4d6 |
1722 | $types = repository_get_editable_types($context); |
1723 | foreach ($types as $type) { |
7a3b93c1 |
1724 | if (!empty($type) && $type->get_visible()) { |
f48fb4d6 |
1725 | $instanceoptionnames = repository_static_function($type->get_typename(), 'get_instance_option_names'); |
edb50637 |
1726 | if (!empty($instanceoptionnames)) { |
f48fb4d6 |
1727 | $instancehtml .= '<li><a href="'.$baseurl.'&new='.$type->get_typename().'">'.get_string('create', 'repository') |
1728 | .' "'.get_string('repositoryname', 'repository_'.$type->get_typename()).'" ' |
7a3b93c1 |
1729 | .get_string('instance', 'repository').'</a></li>'; |
1730 | $addable++; |
1731 | } |
a6600395 |
1732 | } |
1733 | } |
7a3b93c1 |
1734 | $instancehtml .= '</ul>'; |
a6600395 |
1735 | |
edb50637 |
1736 | } else { |
1737 | $instanceoptionnames = repository_static_function($typename, 'get_instance_option_names'); |
1738 | if (!empty($instanceoptionnames)) { //create a unique type of instance |
7a3b93c1 |
1739 | $addable = 1; |
1740 | $instancehtml .= "<form action='".$baseurl."&new=".$typename."' method='post'> |
1741 | <p style='text-align:center'><input type='submit' value='".get_string('createinstance', 'repository')."'/></p> |
7892948d |
1742 | </form>"; |
edb50637 |
1743 | } |
7a3b93c1 |
1744 | } |
1745 | |
1746 | if ($addable) { |
1747 | $instancehtml .= '</div>'; |
1748 | $output .= $instancehtml; |
1749 | } |
a6600395 |
1750 | |
7a3b93c1 |
1751 | $output .= print_box_end(true); |
a6600395 |
1752 | |
7a3b93c1 |
1753 | //print the list + creation links |
1754 | print($output); |
a6600395 |
1755 | } |