MDL-19142 assignment/backup&restore: support backing up and restoring third party...
[moodle.git] / mod / resource / lib.php
CommitLineData
28f672b2 1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
2a439ba7 17
28f672b2 18/**
19 * @package mod-resource
20 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22 */
23
24/** Require {@link portfoliolib.php} */
214b1cf7 25require_once($CFG->libdir.'/portfoliolib.php');
26
28f672b2 27/** RESOURCE_LOCALPATH = LOCALPATH */
713d78ea 28define('RESOURCE_LOCALPATH', 'LOCALPATH');
29
28f672b2 30/**
31 * @global array $RESOURCE_WINDOW_OPTIONS
32 * @name $RESOURCE_WINDOW_OPTIONS
33 */
220a90c5 34global $RESOURCE_WINDOW_OPTIONS; // must be global because it might be included from a function!
ec81373f 35$RESOURCE_WINDOW_OPTIONS = array('resizable', 'scrollbars', 'directories', 'location',
6d77bd61 36 'menubar', 'toolbar', 'status', 'width', 'height');
3d30a455 37
d18830fe 38/**
28f672b2 39 * resource_base is the base class for resource types
40 *
41 * This class provides all the functionality for a resource
42 * @package mod-resource
43 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
44 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
45 */
d18830fe 46class resource_base {
47
65634a81 48 var $cm;
49 var $course;
50 var $resource;
65634a81 51 var $navlinks;
52
53 /**
28f672b2 54 * Constructor for the base resource class
55 *
56 * Constructor for the base resource class.
57 * If cmid is set create the cm, course, resource objects.
58 * and do some checks to make sure people can be here, and so on.
59 *
60 * @global stdClass
61 * @global object
62 * @global object
63 * @uses CONTEXT_MODULE
64 * @param int $cmid the current course module id - not set for new resources
65 */
65634a81 66 function resource_base($cmid=0) {
5f5cd33c 67 global $CFG, $COURSE, $DB;
65634a81 68
bddd9f6f 69 $this->navlinks = array();
65634a81 70
71 if ($cmid) {
72 if (! $this->cm = get_coursemodule_from_id('resource', $cmid)) {
baa336f0 73 print_error('invalidcoursemodule');
65634a81 74 }
75
5f5cd33c 76 if (! $this->course = $DB->get_record("course", array("id"=>$this->cm->course))) {
baa336f0 77 print_error('coursemisconf');
65634a81 78 }
79
5f5cd33c 80 if (! $this->resource = $DB->get_record("resource", array("id"=>$this->cm->instance))) {
baa336f0 81 print_error('invalidid', 'resource');
65634a81 82 }
83
84 $this->strresource = get_string("modulename", "resource");
85 $this->strresources = get_string("modulenameplural", "resource");
86
65634a81 87 if (!$this->cm->visible and !has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_MODULE, $this->cm->id))) {
88 $pagetitle = strip_tags($this->course->shortname.': '.$this->strresource);
38e179a4 89 $navigation = build_navigation($this->navlinks, $this->cm);
65634a81 90
38e179a4 91 print_header($pagetitle, $this->course->fullname, $navigation, "", "", true, '', navmenu($this->course, $this->cm));
65634a81 92 notice(get_string("activityiscurrentlyhidden"), "$CFG->wwwroot/course/view.php?id={$this->course->id}");
93 }
d18830fe 94
65634a81 95 } else {
96 $this->course = $COURSE;
d18830fe 97 }
65634a81 98 }
6aac6eef 99
6aac6eef 100
65634a81 101 /**
102 * Display function does nothing in the base class
103 */
104 function display() {
6aac6eef 105
ec81373f 106 }
d18830fe 107
108
65634a81 109 /**
28f672b2 110 * Display the resource with the course blocks.
28f672b2 111 */
65634a81 112 function display_course_blocks_start() {
d4a03c00 113 global $CFG, $USER, $PAGE;
0440482f 114
65634a81 115 /// Print the page header
65634a81 116 $edit = optional_param('edit', -1, PARAM_BOOL);
0440482f 117
65634a81 118 if (($edit != -1) and $PAGE->user_allowed_editing()) {
119 $USER->editing = $edit;
120 }
d2b23346 121
65634a81 122 $morenavlinks = array($this->strresources => 'index.php?id='.$this->course->id,
123 $this->resource->name => '');
d2b23346 124
5d1381c2 125 $PAGE->print_header($this->course->shortname.': %fullname%', $morenavlinks, "", "",
ca29e37d 126 update_module_button($this->cm->id, $this->course->id, $this->strresource));
65634a81 127 }
0440482f 128
129
65634a81 130 /**
131 * Finish displaying the resource with the course blocks
132 */
133 function display_course_blocks_end() {
5f5cd33c 134 global $CFG, $THEME;
0440482f 135
65634a81 136 $PAGE = $this->PAGE;
137 $pageblocks = blocks_setup($PAGE);
138 $blocks_preferred_width = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]), 210);
0440482f 139
f58fcc82 140 $lt = (empty($THEME->layouttable)) ? array('left', 'middle', 'right') : $THEME->layouttable;
141 foreach ($lt as $column) {
142 if ($column != 'middle') {
143 array_shift($lt);
144 } else if ($column == 'middle') {
145 break;
146 }
147 }
148 foreach ($lt as $column) {
149 switch ($column) {
150 case 'left':
151 if((blocks_have_content($pageblocks, BLOCK_POS_LEFT) || $PAGE->user_is_editing())) {
152 echo '<td style="width: '.$blocks_preferred_width.'px;" id="left-column">';
153 print_container_start();
154 blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT);
155 print_container_end();
156 echo '</td>';
157 }
158 break;
159
160 case 'middle':
161 echo '</div>';
162 print_container_end();
163 echo '</td>';
164 break;
165
166 case 'right':
167 if((blocks_have_content($pageblocks, BLOCK_POS_RIGHT) || $PAGE->user_is_editing())) {
168 echo '<td style="width: '.$blocks_preferred_width.'px;" id="right-column">';
169 print_container_start();
170 blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT);
171 print_container_end();
172 echo '</td>';
173 }
174 break;
175 }
65634a81 176 }
0440482f 177
65634a81 178 echo '</tr></table>';
0440482f 179
65634a81 180 print_footer($this->course);
181
182 }
0440482f 183
28f672b2 184 /**
185 * Given an object containing all the necessary data,
186 * (defined by the form in mod_form.php) this function
187 * will create a new instance and return the id number
188 * of the new instance.
189 *
190 * @global object
191 * @param object $resource
192 * @return int|bool
193 */
65634a81 194 function add_instance($resource) {
c18269c7 195 global $DB;
2a439ba7 196
65634a81 197 $resource->timemodified = time();
2a439ba7 198
c18269c7 199 return $DB->insert_record("resource", $resource);
65634a81 200 }
2a439ba7 201
28f672b2 202 /**
203 * Given an object containing all the necessary data,
204 * (defined by the form in mod_form.php) this function
205 * will update an existing instance with new data.
206 *
207 * @global object
208 * @param object $resource
209 * @return bool
210 */
65634a81 211 function update_instance($resource) {
c18269c7 212 global $DB;
cccb016a 213
65634a81 214 $resource->id = $resource->instance;
215 $resource->timemodified = time();
cccb016a 216
c18269c7 217 return $DB->update_record("resource", $resource);
65634a81 218 }
cccb016a 219
28f672b2 220 /**
221 * Given an object containing the resource data
222 * this function will permanently delete the instance
223 * and any data that depends on it.
224 *
225 * @global object
226 * @param object $resource
227 * @return bool
228 */
65634a81 229 function delete_instance($resource) {
c18269c7 230 global $DB;
cccb016a 231
65634a81 232 $result = true;
cccb016a 233
c18269c7 234 if (! $DB->delete_records("resource", array("id"=>$resource->id))) {
65634a81 235 $result = false;
236 }
2a439ba7 237
65634a81 238 return $result;
239 }
cccb016a 240
28f672b2 241 /**
242 *
243 */
65634a81 244 function setup_elements(&$mform) {
245 //override to add your own options
246 }
2a439ba7 247
28f672b2 248 /**
249 *
250 */
65634a81 251 function setup_preprocessing(&$default_values){
252 //override to add your own options
253 }
d18830fe 254
28f672b2 255 /**
256 * @todo penny implement later - see MDL-15758
257 */
d67bfc32 258 function portfolio_prepare_package_uploaded($exporter) {
3efe78df 259 // @todo penny implement later - see MDL-15758
260
261 }
262
28f672b2 263 /**
264 * @uses FORMAT_MOODLE
265 * @uses FORMAT_HTML
266 * @param object $exporter
267 * @param bool $text
268 * @return int|bool
269 */
d67bfc32 270 function portfolio_prepare_package_online($exporter, $text=false) {
96a38422 271 $filename = clean_filename($this->cm->name . '.' . 'html');
ffcfd8a7 272 $formatoptions = (object)array('noclean' => true);
3efe78df 273 $format = (($text) ? FORMAT_MOODLE : FORMAT_HTML);
274 $content = format_text($this->resource->alltext, $format, $formatoptions, $this->course->id);
6be1dcae 275 return $exporter->write_new_file($content, $filename, false);
3efe78df 276 }
277
28f672b2 278 /**
279 * @param bool $text
280 * @uses FORMAT_MOODLE
281 * @uses FORMAT_HTML
282 * @return string
283 */
ffcfd8a7 284 function portfolio_get_sha1_online($text=false) {
285 $formatoptions = (object)array('noclean' => true);
286 $format = (($text) ? FORMAT_MOODLE : FORMAT_HTML);
287 $content = format_text($this->resource->alltext, $format, $formatoptions, $this->course->id);
288 return sha1($content);
289 }
290
28f672b2 291 /**
292 * @todo penny implement later.
293 */
ffcfd8a7 294 function portfolio_get_sha1_uploaded() {
295 // @todo penny implement later.
296 }
297
d18830fe 298} /// end of class definition
299
300
28f672b2 301/**
302 * @global stdClass
303 * @uses PARAM_SAFEDIR
304 * @param object $resource
305 * @return int|bool
306 */
d18830fe 307function resource_add_instance($resource) {
308 global $CFG;
ec81373f 309
1b1d3422 310 $resource->type = clean_param($resource->type, PARAM_SAFEDIR); // Just to be safe
79035d46 311
d18830fe 312 require_once("$CFG->dirroot/mod/resource/type/$resource->type/resource.class.php");
1aef6fb7 313 $resourceclass = "resource_$resource->type";
314 $res = new $resourceclass();
d18830fe 315
316 return $res->add_instance($resource);
317}
318
28f672b2 319/**
320 * @global stdClass
321 * @uses PARAM_SAFEDIR
322 * @param object $resource
323 * @return bool
324 */
d18830fe 325function resource_update_instance($resource) {
326 global $CFG;
ec81373f 327
1b1d3422 328 $resource->type = clean_param($resource->type, PARAM_SAFEDIR); // Just to be safe
79035d46 329
d18830fe 330 require_once("$CFG->dirroot/mod/resource/type/$resource->type/resource.class.php");
1aef6fb7 331 $resourceclass = "resource_$resource->type";
332 $res = new $resourceclass();
d18830fe 333
334 return $res->update_instance($resource);
335}
336
28f672b2 337/**
338 * @global stdClass
339 * @global object
340 * @uses PARAM_SAFEDIR
341 * @param int $id
342 * @return bool
343 */
d18830fe 344function resource_delete_instance($id) {
c18269c7 345 global $CFG, $DB;
ec81373f 346
c18269c7 347 if (! $resource = $DB->get_record("resource", array("id"=>$id))) {
d18830fe 348 return false;
349 }
79035d46 350
1b1d3422 351 $resource->type = clean_param($resource->type, PARAM_SAFEDIR); // Just to be safe
ec81373f 352
d18830fe 353 require_once("$CFG->dirroot/mod/resource/type/$resource->type/resource.class.php");
1aef6fb7 354 $resourceclass = "resource_$resource->type";
355 $res = new $resourceclass();
d18830fe 356
f0c6abbf 357 return $res->delete_instance($resource);
d18830fe 358}
359
28f672b2 360/**
361 *
362 * @global object
363 * @param object $course
364 * @param object $user
365 * @param object $mod
366 * @param object $resource
367 * @return object|null
368 */
2a439ba7 369function resource_user_outline($course, $user, $mod, $resource) {
5f5cd33c 370 global $DB;
371
372 if ($logs = $DB->get_records("log", array('userid'=>$user->id, 'module'=>'resource',
373 'action'=>'view', 'info'=>$resource->id), "time ASC")) {
2a439ba7 374
375 $numviews = count($logs);
376 $lastlog = array_pop($logs);
377
9f741612 378 $result = new object();
2a439ba7 379 $result->info = get_string("numviews", "", $numviews);
380 $result->time = $lastlog->time;
381
382 return $result;
383 }
384 return NULL;
385}
386
28f672b2 387/**
388 * @global stdClass
389 * @global object
390 * @param object $course
391 * @param object $user
392 * @param object $mod
393 * @param object $resource
394 */
2a439ba7 395function resource_user_complete($course, $user, $mod, $resource) {
5f5cd33c 396 global $CFG, $DB;
2a439ba7 397
5f5cd33c 398 if ($logs = $DB->get_records("log", array('userid'=>$user->id, 'module'=>'resource',
399 'action'=>'view', 'info'=>$resource->id), "time ASC")) {
2a439ba7 400 $numviews = count($logs);
401 $lastlog = array_pop($logs);
402
403 $strmostrecently = get_string("mostrecently");
404 $strnumviews = get_string("numviews", "", $numviews);
405
406 echo "$strnumviews - $strmostrecently ".userdate($lastlog->time);
407
408 } else {
4282d7dd 409 print_string("neverseen", "resource");
2a439ba7 410 }
411}
412
28f672b2 413/**
414 * Returns the users with data in one resource
415 * (NONE, byt must exists on EVERY mod !!)
416 *
417 * @param int $resourceid
418 * @return bool false
419 */
84caf038 420function resource_get_participants($resourceid) {
84caf038 421 return false;
422}
2a439ba7 423
28f672b2 424/**
425 * Given a course_module object, this function returns any
426 * "extra" information that may be needed when printing
427 * this activity in a course listing.
428 *
429 * See {@link get_array_of_activities()} in course/lib.php
430 *
431 * @global stdClass
432 * @global object
433 * @param object $coursemodule
434 * @return object info
435 */
8dddba42 436function resource_get_coursemodule_info($coursemodule) {
5f5cd33c 437 global $CFG, $DB;
9d361034 438
439 $info = NULL;
440
5f5cd33c 441 if ($resource = $DB->get_record("resource", array("id"=>$coursemodule->instance), 'id, popup, reference, type, name')) {
dd97c328 442 $info = new object();
1ea543df 443 $info->name = $resource->name;
85e8239e 444 if (!empty($resource->popup)) {
bfca8b17 445 $info->extra = urlencode("onclick=\"this.target='resource$resource->id'; return ".
839f2456 446 "openpopup('/mod/resource/view.php?inpopup=true&amp;id=".
8dddba42 447 $coursemodule->id.
d18830fe 448 "','resource$resource->id','$resource->popup');\"");
8dddba42 449 }
9d361034 450
f1e0649c 451 require_once($CFG->libdir.'/filelib.php');
9d361034 452
c93dae38 453 $customicon = $CFG->dirroot.'/mod/resource/type/'.$resource->type.'/icon.gif';
85e8239e 454 if ($resource->type == 'file') {
ec81373f 455 $icon = mimeinfo("icon", $resource->reference);
9d361034 456 if ($icon != 'unknown.gif') {
ec81373f 457 $info->icon ="f/$icon";
85e8239e 458 } else {
ec81373f 459 $info->icon ="f/web.gif";
9d361034 460 }
d18830fe 461 } else if ($resource->type == 'directory') {
ec81373f 462 $info->icon ="f/folder.gif";
c93dae38 463 } else if (file_exists($customicon)) {
464 $info->icon ='mod/resource/type/'.$resource->type.'/icon.gif';
9d361034 465 }
8dddba42 466 }
467
9d361034 468 return $info;
8dddba42 469}
ec81373f 470
28f672b2 471/**
472 * @param string $text
473 * @param string $url
474 * @param string $tagtoparse
475 * @param string $keytoparse
476 * @param string $prefix
477 * @return string
478 */
af65e103 479function resource_redirect_tags($text, $url, $tagtoparse, $keytoparse,$prefix = "" ) {
bf46cd22 480 $valid = 1;
af65e103 481 if ( strpos($url,"?") == FALSE ) {
482 $valid = 1;
483 }
484 if ( $valid ) {
485 $lastpoint = strrpos($url,".");
486 $lastslash = strrpos($url,"/");
487 if ( $lastpoint > $lastslash ) {
488 $root = substr($url,0,$lastslash+1);
489 } else {
490 $root = $url;
491 }
ec81373f 492 if ( $root == "http://" or
af65e103 493 $root == "https://") {
494 $root = $url;
495 }
496 if ( substr($root,strlen($root)-1) == '/' ) {
497 $root = substr($root,0,-1);
498 }
ec81373f 499
af65e103 500 $mainroot = $root;
501 $lastslash = strrpos($mainroot,"/");
502 while ( $lastslash > 9) {
503 $mainroot = substr($mainroot,0,$lastslash);
ec81373f 504
af65e103 505 $lastslash = strrpos($mainroot,"/");
506 }
8dddba42 507
ec81373f 508 $regex = "/<$tagtoparse (.+?)>/is";
509 $count = preg_match_all($regex, $text, $hrefs);
af65e103 510 for ( $i = 0; $i < $count; $i++) {
511 $tag = $hrefs[1][$i];
ec81373f 512
af65e103 513 $poshref = strpos(strtolower($tag),strtolower($keytoparse));
514 $start = $poshref + strlen($keytoparse);
515 $left = substr($tag,0,$start);
516 if ( $tag[$start] == '"' ) {
517 $left .= '"';
518 $start++;
519 }
520 $posspace = strpos($tag," ", $start+1);
521 $right = "";
522 if ( $posspace != FALSE) {
523 $right = substr($tag, $posspace);
524 }
525 $end = strlen($tag)-1;
526 if ( $tag[$end] == '"' ) {
527 $right = '"' . $right;
528 }
529 $finalurl = substr($tag,$start,$end-$start+$diff);
530 // Here, we could have these possible values for $finalurl:
531 // file.ext Add current root dir
532 // http://(domain) don't care
533 // http://(domain)/ don't care
534 // http://(domain)/folder don't care
535 // http://(domain)/folder/ don't care
536 // http://(domain)/folder/file.ext don't care
537 // folder/ Add current root dir
538 // folder/file.ext Add current root dir
539 // /folder/ Add main root dir
540 // /folder/file.ext Add main root dir
541
542 // Special case: If finalurl contains a ?, it won't be parsed
bf46cd22 543 $valid = 1;
af65e103 544
545 if ( strpos($finalurl,"?") == FALSE ) {
546 $valid = 1;
547 }
548 if ( $valid ) {
549 if ( $finalurl[0] == "/" ) {
550 $finalurl = $mainroot . $finalurl;
ec81373f 551 } elseif ( strtolower(substr($finalurl,0,7)) != "http://" and
af65e103 552 strtolower(substr($finalurl,0,8)) != "https://") {
553 if ( $finalurl[0] == "/") {
554 $finalurl = $mainroot . $finalurl;
555 } else {
556 $finalurl = "$root/$finalurl";
557 }
558 }
ec81373f 559
af65e103 560 $text = str_replace($tag,"$left$prefix$finalurl$right",$text);
561 }
562 }
563 }
564 return $text;
565}
8dddba42 566
28f672b2 567/**
568 * @param string $path
569 * @return bool
570 */
d18830fe 571function resource_is_url($path) {
427c8ccb 572 if (strpos($path, '://')) { // eg http:// https:// ftp:// etc
d18830fe 573 return true;
574 }
427c8ccb 575 if (strpos($path, '/') === 0) { // Starts with slash
576 return true;
577 }
578 return false;
d18830fe 579}
580
28f672b2 581/**
582 * @global stdClass
583 * @uses MOD_CLASS_RESOURCE
584 * @return array
585 */
89bfeee0 586function resource_get_types() {
9f741612 587 global $CFG;
588
89bfeee0 589 $types = array();
6da4b261 590
3d30a455 591 $standardresources = array('text','html','file','directory');
6da4b261 592 foreach ($standardresources as $resourcetype) {
89bfeee0 593 $type = new object();
594 $type->modclass = MOD_CLASS_RESOURCE;
d81f018f 595 $type->name = $resourcetype;
89bfeee0 596 $type->type = "resource&amp;type=$resourcetype";
6b60b000 597 $type->typestr = resource_get_name($resourcetype);
89bfeee0 598 $types[] = $type;
6da4b261 599 }
600
601 /// Drop-in extra resource types
17da2e6f 602 $resourcetypes = get_plugin_list('resource');
603 foreach ($resourcetypes as $resourcetype => $dir) {
37147357 604 if (!empty($CFG->{'resource_hide_'.$resourcetype})) { // Not wanted
605 continue;
606 }
89bfeee0 607 if (!in_array($resourcetype, $standardresources)) {
608 $type = new object();
609 $type->modclass = MOD_CLASS_RESOURCE;
d81f018f 610 $type->name = $resourcetype;
89bfeee0 611 $type->type = "resource&amp;type=$resourcetype";
13ca1e06 612 $type->typestr = resource_get_name($resourcetype);
89bfeee0 613 $types[] = $type;
6da4b261 614 }
615 }
89bfeee0 616
617 return $types;
6da4b261 618}
f3221af9 619
28f672b2 620/**
621 * @return array
622 */
f3221af9 623function resource_get_view_actions() {
624 return array('view','view all');
625}
626
28f672b2 627/**
628 * @return array
629 */
f3221af9 630function resource_get_post_actions() {
631 return array();
632}
633
28f672b2 634/**
635 * @global stdClass
636 * @global object
637 * @param object $course
638 * @param string $wdir
639 * @param string $oldname
640 * @param string $name
641 */
a69be0d8 642function resource_renamefiles($course, $wdir, $oldname, $name) {
5f5cd33c 643 global $CFG, $DB;
a69be0d8 644
645 $status = '<p align=\"center\"><strong>'.get_string('affectedresources', 'resource').':</strong><ul>';
646 $updates = false;
647
648 $old = trim($wdir.'/'.$oldname, '/');
649 $new = trim($wdir.'/'.$name, '/');
650
651 $sql = "SELECT r.id, r.reference, r.name, cm.id AS cmid
5f5cd33c 652 FROM {resource} r, {course_modules} cm, {modules} m
653 WHERE r.course = :courseid
654 AND m.name = 'resource'
655 AND cm.module = m.id
656 AND cm.instance = r.id
657 AND (r.type = 'file' OR r.type = 'directory')
658 AND (r.reference LIKE :old1 OR r.reference = :old2)";
659 $params = array('courseid'=>$course->id, 'old1'=>"{$old}/%", 'old2'=>$old);
660 if ($resources = $DB->get_records_sql($sql, $params)) {
a69be0d8 661 foreach ($resources as $resource) {
662 $r = new object();
663 $r->id = $resource->id;
664 $r->reference = '';
665 if ($resource->reference == $old) {
5f5cd33c 666 $r->reference = $new;
a69be0d8 667 } else {
5f5cd33c 668 $r->reference = preg_replace('|^'.preg_quote($old, '|').'/|', $new.'/', $resource->reference);
a69be0d8 669 }
670 if ($r->reference !== '') {
671 $updates = true;
672 $status .= "<li><a href=\"$CFG->wwwroot/mod/resource/view.php?id=$resource->cmid\" target=\"_blank\">$resource->name</a>: $resource->reference ==> $r->reference</li>";
673 if (!empty($CFG->resource_autofilerename)) {
a8c31db2 674 $DB->update_record('resource', $r);
a69be0d8 675 }
676 }
677 }
678 }
679 $status .= '</ul></p>';
680
681 if ($updates) {
682 echo $status;
683 if (empty($CFG->resource_autofilerename)) {
684 notify(get_string('warningdisabledrename', 'resource'));
685 }
686 }
687}
688
28f672b2 689/**
690 * @global stdClass
691 * @global object
692 * @param object $course
693 * @param array $files
694 * @return bool
695 */
a69be0d8 696function resource_delete_warning($course, $files) {
5f5cd33c 697 global $CFG, $DB;
a69be0d8 698
699 $found = array();
700
701 foreach($files as $key=>$file) {
702 $files[$key] = trim($file, '/');
703 }
704 $sql = "SELECT r.id, r.reference, r.name, cm.id AS cmid
5f5cd33c 705 FROM {resource} r,
706 {course_modules} cm,
707 {modules} m
708 WHERE r.course = ?
709 AND m.name = 'resource'
710 AND cm.module = m.id
711 AND cm.instance = r.id
712 AND (r.type = 'file' OR r.type = 'directory')";
713 if ($resources = $DB->get_records_sql($sql, array($course->id))) {
a69be0d8 714 foreach ($resources as $resource) {
715 if ($resource->reference == '') {
716 continue; // top shared directory does not prevent anything
717 }
718 if (in_array($resource->reference, $files)) {
719 $found[$resource->id] = $resource;
720 } else {
721 foreach($files as $file) {
722 if (preg_match('|^'.preg_quote($file, '|').'/|', $resource->reference)) {
723 $found[$resource->id] = $resource;
724 }
725 }
726 }
727 }
728 }
729
730 if (!empty($found)) {
731
732 print_simple_box_start("center");
733 echo '<p><strong>'.get_string('affectedresources', 'resource').':</strong><ul>';
734 foreach($found as $resource) {
735 echo "<li><a href=\"$CFG->wwwroot/mod/resource/view.php?id=$resource->cmid\" target=\"_blank\">$resource->name</a>: $resource->reference</li>";
736 }
737 echo '</ul></p>';
738 print_simple_box_end();
739
740 return true;
741 } else {
742 return false;
743 }
744}
745
0b5a80a1 746/**
747 * This function is used by the reset_course_userdata function in moodlelib.
28f672b2 748 *
0b5a80a1 749 * @param $data the data submitted from the reset course.
750 * @return array status array
751 */
752function resource_reset_userdata($data) {
753 return array();
754}
f432bebf 755
756/**
757 * Returns all other caps used in module
28f672b2 758 *
759 * @return array
f432bebf 760 */
761function resource_get_extra_capabilities() {
762 return array('moodle/site:accessallgroups');
763}
764
28f672b2 765/**
766 * @package mod-resource
767 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
768 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
769 */
3efe78df 770class resource_portfolio_caller extends portfolio_module_caller_base {
771
772 private $resource;
773 private $resourcefile;
774
28f672b2 775 /**
776 * @return array
777 */
0d06b6fd 778 public static function expected_callbackargs() {
779 return array(
780 'id' => true,
781 );
782 }
783
28f672b2 784 /**
785 * @global stdClass
786 * @global object
787 */
0d06b6fd 788 public function load_data() {
789 global $CFG, $DB;
790 if (!$this->cm = get_coursemodule_from_instance('resource', $this->id)) {
3bb8a2c7 791 throw new portfolio_caller_exception('invalidid');
3efe78df 792 }
793 $this->cm->type = $DB->get_field('resource', 'type', array('id' => $this->cm->instance));
794 $resourceclass = 'resource_'. $this->cm->type;
795 $this->resourcefile = $CFG->dirroot.'/mod/resource/type/'.$this->cm->type.'/resource.class.php';
796 require_once($this->resourcefile);
797 $this->resource= new $resourceclass($this->cm->id);
759204f8 798 if (!is_callable(array($this->resource, 'portfolio_prepare_package')) || !is_callable(array($this->resource, 'portfolio_get_sha1'))) {
c5046670 799 throw new portfolio_exception('portfolionotimplemented', 'resource', null, $this->cm->type);
800 }
0d06b6fd 801 $this->supportedformats = array(self::type_to_format($this->cm->type));
802 }
803
28f672b2 804 /**
805 * @uses PORTFOLIO_FORMAT_FILE
806 * @uses PORTFOLIO_FORMAT_PLAINHTML
807 * @uses PORTFOLIO_FORMAT_TEXT
808 * @param string $type
809 * @return string
810 */
0d06b6fd 811 public static function type_to_format($type) {
ea0de12f 812 // this is kind of yuk... but there's just not good enough OO here
813 $format = PORTFOLIO_FORMAT_FILE;
0d06b6fd 814 switch ($type) {
ea0de12f 815 case 'html':
6be1dcae 816 $format = PORTFOLIO_FORMAT_PLAINHTML;
ea0de12f 817 case 'text':
818 $format = PORTFOLIO_FORMAT_TEXT;
819 case 'file':
e4af1dee 820 // $format = portfolio_format_from_file($file); // change after we switch upload type resources over to new files api.
ea0de12f 821 }
0d06b6fd 822 return $format;
3efe78df 823 }
824
28f672b2 825 /**
826 * @global stdClass
827 * @return void
828 */
3efe78df 829 public function __wakeup() {
654119b5 830 global $CFG;
831 if (empty($CFG)) {
832 return; // too early yet
833 }
3efe78df 834 require_once($this->resourcefile);
835 $this->resource = unserialize(serialize($this->resource));
836 }
837
28f672b2 838 /**
839 * @todo penny check filesize if the type is uploadey (not implemented yet)
840 * like this: return portfolio_expected_time_file($this->file); or whatever
841 *
842 * @return string
843 */
3efe78df 844 public function expected_time() {
3efe78df 845 return PORTFOLIO_TIME_LOW;
846 }
847
28f672b2 848 /**
849 *
850 */
d67bfc32 851 public function prepare_package() {
852 return $this->resource->portfolio_prepare_package($this->exporter);
3efe78df 853 }
854
28f672b2 855 /**
856 * @uses CONTEXT_MODULE
857 * @return bool
858 */
3efe78df 859 public function check_permissions() {
494e47e4 860 return has_capability('mod/resource:exportresource', get_context_instance(CONTEXT_MODULE, $this->cm->id));
3efe78df 861 }
862
28f672b2 863 /**
864 * @uses CONTEXT_MODULE
865 * @param object $resource
866 * @param mixed $format
867 * @param bool $return
868 * @return mixed
869 */
866d543f 870 public static function add_button($resource, $format=null, $return=false) {
494e47e4 871 if (!has_capability('mod/resource:exportresource', get_context_instance(CONTEXT_MODULE, $resource->cm->id))) {
872 return;
873 }
ffcfd8a7 874 if (!is_callable(array($resource, 'portfolio_prepare_package')) || !is_callable(array($resource, 'portfolio_get_sha1'))) {
3efe78df 875 debugging(get_string('portfolionotimplemented', 'resource'));
876 return false;
877 }
759204f8 878 $callersupports = array(self::type_to_format($resource->resource->type));
879 if ($resource->resource->type == 'file') {
e4af1dee 880 // $callersupports = array(portfolio_format_from_file($file);
881 }
0d06b6fd 882 $button = new portfolio_add_button();
883 $button->set_callback_options('resource_portfolio_caller', array('id' => $resource->cm->instance), '/mod/resource/lib.php');
884 $button->set_formats($callersupports);
885 if ($return) {
886 return $button->to_html($format);
887 }
888 $button->render($format);
3efe78df 889 }
ffcfd8a7 890
28f672b2 891 /**
892 * @return string
893 */
ffcfd8a7 894 public function get_sha1() {
895 return $this->resource->portfolio_get_sha1();
896 }
897
28f672b2 898 /**
899 * @return string
900 */
ffcfd8a7 901 public static function display_name() {
902 return get_string('modulename', 'resource');
903 }
3efe78df 904}
905
18a2a0cb 906/**
28f672b2 907 * @uses FEATURE_GROUPS
908 * @uses FEATURE_GROUPINGS
909 * @uses FEATURE_GROUPMEMBERSONLY
910 * @uses FEATURE_MOD_INTRO
911 * @uses FEATURE_COMPLETION_TRACKS_VIEWS
912 * @uses FEATURE_GRADE_HAS_GRADE
913 * @uses FEATURE_GRADE_OUTCOMES
18a2a0cb 914 * @param string $feature FEATURE_xx constant for requested feature
28f672b2 915 * @return mixed True if module supports feature, false if not, null if doesn't know
18a2a0cb 916 */
917function resource_supports($feature) {
918 switch($feature) {
42f103be 919 case FEATURE_GROUPS: return false;
920 case FEATURE_GROUPINGS: return false;
921 case FEATURE_GROUPMEMBERSONLY: return true;
dc5c2bd9 922 case FEATURE_MOD_INTRO: return true;
18a2a0cb 923 case FEATURE_COMPLETION_TRACKS_VIEWS: return true;
42f103be 924 case FEATURE_GRADE_HAS_GRADE: return false;
925 case FEATURE_GRADE_OUTCOMES: return false;
17da2e6f 926 case FEATURE_MOD_SUBPLUGINS: return array('resource'=>'mod/resource/type'); // to be removed in 2.0
42f103be 927
18a2a0cb 928 default: return null;
929 }
930}
931
13ca1e06 932/**
933 * Returns the full name of the given resource type. The name can
934 * either be set at the resource type level or at the resource module
935 * level.
936 *
937 * @param string $type shortname (or directory name) of the resource type
28f672b2 938 * @return string
13ca1e06 939 */
940function resource_get_name($type) {
941 $name = get_string("resourcetype$type", "resource_$type");
942 if (substr($name, 0, 2) === '[[') {
943 $name = get_string("resourcetype$type", 'resource');
944 }
945 return $name;
946}