Merged from MOODLE_15_STABLE: merging check_db_compat function for backwards compatab...
[moodle.git] / mod / resource / lib.php
CommitLineData
d1290cec 1<?php // $Id$
2a439ba7 2
5925d0ef 3if (!isset($CFG->resource_framesize)) {
4 set_config("resource_framesize", 130);
ec81373f 5}
92a419a2 6
66c25030 7if (!isset($CFG->resource_websearch)) {
8 set_config("resource_websearch", "http://google.com/");
ec81373f 9}
66c25030 10
5e91dd3f 11if (!isset($CFG->resource_defaulturl)) {
12 set_config("resource_defaulturl", "http://");
ec81373f 13}
3bfe3922 14
15if (!isset($CFG->resource_filterexternalpages)) {
16 set_config("resource_filterexternalpages", false);
ec81373f 17}
5e91dd3f 18
d18830fe 19if (!isset($CFG->resource_secretphrase)) {
20 set_config("resource_secretphrase", random_string(20));
ec81373f 21}
d18830fe 22
83891eda 23if (!isset($CFG->resource_popup)) {
24 set_config("resource_popup", "");
ec81373f 25}
83891eda 26
33935242 27if (!isset($CFG->resource_windowsettings)) {
28 set_config("resource_windowsettings", "0");
ec81373f 29}
33935242 30
31if (!isset($CFG->resource_parametersettings)) {
32 set_config("resource_parametersettings", "0");
ec81373f 33}
33935242 34
713d78ea 35if (!isset($CFG->resource_allowlocalfiles)) {
36 set_config("resource_allowlocalfiles", "0");
37}
38
37147357 39if (!isset($CFG->resource_hide_repository)) {
40 set_config("resource_hide_repository", "1");
41}
42
713d78ea 43define('RESOURCE_LOCALPATH', 'LOCALPATH');
44
ec81373f 45$RESOURCE_WINDOW_OPTIONS = array('resizable', 'scrollbars', 'directories', 'location',
2e708fa0 46 'menubar', 'toolbar', 'status', 'height', 'width');
3d30a455 47
83891eda 48foreach ($RESOURCE_WINDOW_OPTIONS as $popupoption) {
49 $popupoption = "resource_popup$popupoption";
50 if (!isset($CFG->$popupoption)) {
2e708fa0 51 if ($popupoption == 'resource_popupheight') {
83891eda 52 set_config($popupoption, 450);
2e708fa0 53 } else if ($popupoption == 'resource_popupwidth') {
83891eda 54 set_config($popupoption, 620);
55 } else {
2e708fa0 56 set_config($popupoption, 'checked');
83891eda 57 }
ec81373f 58 }
83891eda 59}
60
d18830fe 61/**
62* resource_base is the base class for resource types
63*
64* This class provides all the functionality for a resource
65*/
66
67class resource_base {
68
69var $cm;
70var $course;
71var $resource;
72
73
74/**
75* Constructor for the base resource class
76*
77* Constructor for the base resource class.
78* If cmid is set create the cm, course, resource objects.
6aac6eef 79* and do some checks to make sure people can be here, and so on.
d18830fe 80*
81* @param cmid integer, the current course module id - not set for new resources
82*/
83function resource_base($cmid=0) {
84
6aac6eef 85 global $CFG;
3cc63301 86 global $course; // Ugly hack, needed for course language ugly hack
6aac6eef 87
d18830fe 88 if ($cmid) {
89 if (! $this->cm = get_record("course_modules", "id", $cmid)) {
90 error("Course Module ID was incorrect");
91 }
92
93 if (! $this->course = get_record("course", "id", $this->cm->course)) {
94 error("Course is misconfigured");
95 }
96
3cc63301 97 $course = $this->course; // Make it a global so we can see it later
98
ec81373f 99 require_course_login($this->course, true, $this->cm);
6aac6eef 100
d18830fe 101 if (! $this->resource = get_record("resource", "id", $this->cm->instance)) {
102 error("Resource ID was incorrect");
103 }
6aac6eef 104
105 $this->strresource = get_string("modulename", "resource");
106 $this->strresources = get_string("modulenameplural", "resource");
107
108 if ($this->course->category) {
6aac6eef 109 $this->navigation = "<a target=\"{$CFG->framename}\" href=\"$CFG->wwwroot/course/view.php?id={$this->course->id}\">{$this->course->shortname}</a> -> ".
110 "<a target=\"{$CFG->framename}\" href=\"index.php?id={$this->course->id}\">$this->strresources</a> ->";
111 } else {
ec81373f 112 $this->navigation = "<a target=\"{$CFG->framename}\" href=\"index.php?id={$this->course->id}\">$this->strresources</a> ->";
6aac6eef 113 }
114
115 if (!$this->cm->visible and !isteacher($this->course->id)) {
116 $pagetitle = strip_tags($this->course->shortname.': '.$this->strresource);
117 print_header($pagetitle, $this->course->fullname, "$this->navigation $this->strresource", "", "", true, '', navmenu($this->course, $this->cm));
118 notice(get_string("activityiscurrentlyhidden"), "$CFG->wwwroot/course/view.php?id={$this->course->id}");
119 }
ec81373f 120 }
d18830fe 121}
122
123
6aac6eef 124/**
125* Display function does nothing in the base class
126*/
d18830fe 127function display() {
6aac6eef 128
d18830fe 129}
130
131
0440482f 132/**
133* Display the resource with the course blocks.
134*/
135function display_course_blocks_start() {
136
137 global $CFG;
138 global $USER;
139
140 require_once($CFG->libdir.'/blocklib.php');
141 require_once($CFG->libdir.'/pagelib.php');
142
143 $PAGE = page_create_object(PAGE_COURSE_VIEW, $this->course->id);
144 $this->PAGE = $PAGE;
145 $pageblocks = blocks_setup($PAGE);
146
147 $blocks_preferred_width = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]), 210);
148
149/// Print the page header
150
151 if (!empty($edit) && $PAGE->user_allowed_editing()) {
152 if ($edit == 'on') {
153 $USER->editing = true;
154 } else if ($edit == 'off') {
155 $USER->editing = false;
156 }
157 }
158 $morebreadcrumbs = array($this->strresources => 'index.php?id='.$this->course->id,
159 $this->resource->name => '');
160
161 $PAGE->print_header($this->course->shortname.': %fullname%', $morebreadcrumbs);
162
163 echo '<table id="layout-table"><tr>';
164
165 if((blocks_have_content($pageblocks, BLOCK_POS_LEFT) || $PAGE->user_is_editing())) {
166 echo '<td style="width: '.$blocks_preferred_width.'px;" id="left-column">';
167 blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT);
168 echo '</td>';
169 }
170
171 echo '<td id="middle-column">';
172 echo '<div id="resource">';
173
174}
175
176
177/**
178 * Finish displaying the resource with the course blocks
179 */
180function display_course_blocks_end() {
181
182 global $CFG;
183
184 $PAGE = $this->PAGE;
185 $pageblocks = blocks_setup($PAGE);
186 $blocks_preferred_width = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]), 210);
187
188 echo '</div>';
189 echo '</td>';
190
191 if((blocks_have_content($pageblocks, BLOCK_POS_RIGHT) || $PAGE->user_is_editing())) {
192 echo '<td style="width: '.$blocks_preferred_width.'px;" id="right-column">';
193 blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT);
194 echo '</td>';
195 }
196
197 echo '</tr></table>';
198
199 print_footer($this->course);
200
201}
202
203
1aef6fb7 204function setup(&$form) {
d18830fe 205 global $CFG, $usehtmleditor;
206
207 if (! empty($form->course)) {
208 if (! $this->course = get_record("course", "id", $form->course)) {
209 error("Course is misconfigured");
210 }
211 }
212
213 if (empty($form->name)) {
214 $form->name = "";
215 }
216 if (empty($form->type)) {
217 $form->type = "";
218 }
219 if (empty($form->summary)) {
220 $form->summary = "";
221 }
222 if (empty($form->reference)) {
223 $form->reference = "";
224 }
225 if (empty($form->alltext)) {
226 $form->alltext = "";
227 }
1aef6fb7 228 if (empty($form->options)) {
229 $form->options = "";
230 }
d18830fe 231 $nohtmleditorneeded = true;
232
6da4b261 233 print_heading_with_help(get_string("resourcetype$form->type", 'resource'), $form->type, 'resource/type');
d18830fe 234
235 include("$CFG->dirroot/mod/resource/type/common.html");
236}
237
238
239function setup_end() {
240 global $CFG;
241
242 include("$CFG->dirroot/mod/resource/type/common_end.html");
243}
244
245
246function add_instance($resource) {
ec81373f 247// Given an object containing all the necessary data,
248// (defined by the form in mod.html) this function
249// will create a new instance and return the id number
cccb016a 250// of the new instance.
2a439ba7 251
86aa7ccf 252 global $RESOURCE_WINDOW_OPTIONS;
253
cccb016a 254 $resource->timemodified = time();
2a439ba7 255
d18830fe 256 if (isset($resource->windowpopup)) {
7c990f68 257 if ($resource->windowpopup) {
258 $optionlist = array();
259 foreach ($RESOURCE_WINDOW_OPTIONS as $option) {
260 if (isset($resource->$option)) {
261 $optionlist[] = $option."=".$resource->$option;
262 }
86aa7ccf 263 }
7c990f68 264 $resource->popup = implode(',', $optionlist);
d18830fe 265 $resource->options = "";
7c990f68 266 } else {
267 if (isset($resource->framepage)) {
268 $resource->options = "frame";
269 } else {
270 $resource->options = "";
271 }
272 $resource->popup = "";
d18830fe 273 }
86aa7ccf 274 }
275
33935242 276 if (isset($resource->parametersettingspref)) {
277 set_user_preference('resource_parametersettingspref', $resource->parametersettingspref);
278 }
279 if (isset($resource->windowsettingspref)) {
280 set_user_preference('resource_windowsettingspref', $resource->windowsettingspref);
281 }
282
cccb016a 283 return insert_record("resource", $resource);
284}
2a439ba7 285
cccb016a 286
d18830fe 287function update_instance($resource) {
ec81373f 288// Given an object containing all the necessary data,
289// (defined by the form in mod.html) this function
cccb016a 290// will update an existing instance with new data.
291
86aa7ccf 292 global $RESOURCE_WINDOW_OPTIONS;
293
cccb016a 294 $resource->id = $resource->instance;
295 $resource->timemodified = time();
296
d18830fe 297 if (isset($resource->windowpopup)) {
7c990f68 298 if ($resource->windowpopup) {
299 $optionlist = array();
300 foreach ($RESOURCE_WINDOW_OPTIONS as $option) {
301 if (isset($resource->$option)) {
302 $optionlist[] = $option."=".$resource->$option;
303 }
86aa7ccf 304 }
7c990f68 305 $resource->popup = implode(',', $optionlist);
d18830fe 306 $resource->options = "";
7c990f68 307 } else {
308 if (isset($resource->framepage)) {
309 $resource->options = "frame";
310 } else {
311 $resource->options = "";
312 }
313 $resource->popup = "";
d18830fe 314 }
86aa7ccf 315 }
316
33935242 317 if (isset($resource->parametersettingspref)) {
318 set_user_preference('resource_parametersettingspref', $resource->parametersettingspref);
319 }
320 if (isset($resource->windowsettingspref)) {
321 set_user_preference('resource_windowsettingspref', $resource->windowsettingspref);
322 }
323
cccb016a 324 return update_record("resource", $resource);
325}
326
327
d18830fe 328function delete_instance($id) {
ec81373f 329// Given an ID of an instance of this module,
330// this function will permanently delete the instance
331// and any data that depends on it.
cccb016a 332
333 if (! $resource = get_record("resource", "id", "$id")) {
334 return false;
2a439ba7 335 }
336
cccb016a 337 $result = true;
338
339 if (! delete_records("resource", "id", "$resource->id")) {
340 $result = false;
2a439ba7 341 }
342
cccb016a 343 return $result;
2a439ba7 344}
cccb016a 345
2a439ba7 346
d18830fe 347
348} /// end of class definition
349
350
351
352function resource_add_instance($resource) {
353 global $CFG;
ec81373f 354
79035d46 355 $resource->type = clean_filename($resource->type); // Just to be safe
356
d18830fe 357 require_once("$CFG->dirroot/mod/resource/type/$resource->type/resource.class.php");
1aef6fb7 358 $resourceclass = "resource_$resource->type";
359 $res = new $resourceclass();
d18830fe 360
361 return $res->add_instance($resource);
362}
363
364function resource_update_instance($resource) {
365 global $CFG;
ec81373f 366
79035d46 367 $resource->type = clean_filename($resource->type); // Just to be safe
368
d18830fe 369 require_once("$CFG->dirroot/mod/resource/type/$resource->type/resource.class.php");
1aef6fb7 370 $resourceclass = "resource_$resource->type";
371 $res = new $resourceclass();
d18830fe 372
373 return $res->update_instance($resource);
374}
375
376function resource_delete_instance($id) {
377 global $CFG;
ec81373f 378
d18830fe 379 if (! $resource = get_record("resource", "id", "$id")) {
380 return false;
381 }
79035d46 382
383 $resource->type = clean_filename($resource->type); // Just to be safe
ec81373f 384
d18830fe 385 require_once("$CFG->dirroot/mod/resource/type/$resource->type/resource.class.php");
1aef6fb7 386 $resourceclass = "resource_$resource->type";
387 $res = new $resourceclass();
d18830fe 388
389 return $res->delete_instance($id);
390}
391
392
2a439ba7 393function resource_user_outline($course, $user, $mod, $resource) {
ec81373f 394 if ($logs = get_records_select("log", "userid='$user->id' AND module='resource'
ebc3bd2b 395 AND action='view' AND info='$resource->id'", "time ASC")) {
2a439ba7 396
397 $numviews = count($logs);
398 $lastlog = array_pop($logs);
399
400 $result->info = get_string("numviews", "", $numviews);
401 $result->time = $lastlog->time;
402
403 return $result;
404 }
405 return NULL;
406}
407
408
409function resource_user_complete($course, $user, $mod, $resource) {
9fad2dec 410 global $CFG;
2a439ba7 411
ec81373f 412 if ($logs = get_records_select("log", "userid='$user->id' AND module='resource'
ebc3bd2b 413 AND action='view' AND info='$resource->id'", "time ASC")) {
2a439ba7 414 $numviews = count($logs);
415 $lastlog = array_pop($logs);
416
417 $strmostrecently = get_string("mostrecently");
418 $strnumviews = get_string("numviews", "", $numviews);
419
420 echo "$strnumviews - $strmostrecently ".userdate($lastlog->time);
421
422 } else {
4282d7dd 423 print_string("neverseen", "resource");
2a439ba7 424 }
425}
426
84caf038 427function resource_get_participants($resourceid) {
428//Returns the users with data in one resource
429//(NONE, byt must exists on EVERY mod !!)
430
431 return false;
432}
2a439ba7 433
8dddba42 434function resource_get_coursemodule_info($coursemodule) {
ec81373f 435/// Given a course_module object, this function returns any
8dddba42 436/// "extra" information that may be needed when printing
437/// this activity in a course listing.
438///
439/// See get_array_of_activities() in course/lib.php
440///
441
9d361034 442 global $CFG;
443
444 $info = NULL;
445
8dddba42 446 if ($resource = get_record("resource", "id", $coursemodule->instance)) {
85e8239e 447 if (!empty($resource->popup)) {
657e7903 448 $info->extra = urlencode("target=\"resource$resource->id\" onclick=\"return ".
839f2456 449 "openpopup('/mod/resource/view.php?inpopup=true&amp;id=".
8dddba42 450 $coursemodule->id.
d18830fe 451 "','resource$resource->id','$resource->popup');\"");
8dddba42 452 }
9d361034 453
f1e0649c 454 require_once($CFG->libdir.'/filelib.php');
9d361034 455
85e8239e 456 if ($resource->type == 'file') {
ec81373f 457 $icon = mimeinfo("icon", $resource->reference);
9d361034 458 if ($icon != 'unknown.gif') {
ec81373f 459 $info->icon ="f/$icon";
85e8239e 460 } else {
ec81373f 461 $info->icon ="f/web.gif";
9d361034 462 }
d18830fe 463 } else if ($resource->type == 'directory') {
ec81373f 464 $info->icon ="f/folder.gif";
9d361034 465 }
8dddba42 466 }
467
9d361034 468 return $info;
8dddba42 469}
ec81373f 470
8367faba 471function resource_fetch_remote_file ($cm, $url, $headers = "" ) {
3bfe3922 472/// Snoopy is an HTTP client in PHP
473
474 global $CFG;
475
476 require_once("$CFG->libdir/snoopy/Snoopy.class.inc");
477
b2b8471e 478 $client = new Snoopy();
ec81373f 479 $ua = 'Moodle/'. $CFG->release . ' (+http://moodle.org';
bf46cd22 480 if ( $CFG->resource_usecache ) {
481 $ua = $ua . ')';
482 } else {
483 $ua = $ua . '; No cache)';
484 }
485 $client->agent = $ua;
486 $client->read_timeout = 5;
487 $client->use_gzip = true;
b2b8471e 488 if (is_array($headers) ) {
489 $client->rawheaders = $headers;
490 }
ec81373f 491
b2b8471e 492 @$client->fetch($url);
bf46cd22 493 if ( $client->status >= 200 && $client->status < 300 ) {
494 $tags = array("A" => "href=",
495 "IMG" => "src=",
496 "LINK" => "href=",
497 "AREA" => "href=",
498 "FRAME" => "src=",
499 "IFRAME" => "src=",
500 "FORM" => "action=");
ec81373f 501
bf46cd22 502 foreach ($tags as $tag => $key) {
839f2456 503 $prefix = "fetch.php?id=$cm->id&amp;url=";
bf46cd22 504 if ( $tag == "IMG" or $tag == "LINK" or $tag == "FORM") {
505 $prefix = "";
506 }
507 $client->results = resource_redirect_tags($client->results, $url, $tag, $key,$prefix);
508 }
509 } else {
510 if ( $client->status >= 400 && $client->status < 500) {
511 $client->results = get_string("fetchclienterror","resource"); // Client error
512 } elseif ( $client->status >= 500 && $client->status < 600) {
513 $client->results = get_string("fetchservererror","resource"); // Server error
514 } else {
515 $client->results = get_string("fetcherror","resource"); // Redirection? HEAD? Unknown error.
af65e103 516 }
af65e103 517 }
b2b8471e 518 return $client;
af65e103 519}
520
521function resource_redirect_tags($text, $url, $tagtoparse, $keytoparse,$prefix = "" ) {
bf46cd22 522 $valid = 1;
af65e103 523 if ( strpos($url,"?") == FALSE ) {
524 $valid = 1;
525 }
526 if ( $valid ) {
527 $lastpoint = strrpos($url,".");
528 $lastslash = strrpos($url,"/");
529 if ( $lastpoint > $lastslash ) {
530 $root = substr($url,0,$lastslash+1);
531 } else {
532 $root = $url;
533 }
ec81373f 534 if ( $root == "http://" or
af65e103 535 $root == "https://") {
536 $root = $url;
537 }
538 if ( substr($root,strlen($root)-1) == '/' ) {
539 $root = substr($root,0,-1);
540 }
ec81373f 541
af65e103 542 $mainroot = $root;
543 $lastslash = strrpos($mainroot,"/");
544 while ( $lastslash > 9) {
545 $mainroot = substr($mainroot,0,$lastslash);
ec81373f 546
af65e103 547 $lastslash = strrpos($mainroot,"/");
548 }
8dddba42 549
ec81373f 550 $regex = "/<$tagtoparse (.+?)>/is";
551 $count = preg_match_all($regex, $text, $hrefs);
af65e103 552 for ( $i = 0; $i < $count; $i++) {
553 $tag = $hrefs[1][$i];
ec81373f 554
af65e103 555 $poshref = strpos(strtolower($tag),strtolower($keytoparse));
556 $start = $poshref + strlen($keytoparse);
557 $left = substr($tag,0,$start);
558 if ( $tag[$start] == '"' ) {
559 $left .= '"';
560 $start++;
561 }
562 $posspace = strpos($tag," ", $start+1);
563 $right = "";
564 if ( $posspace != FALSE) {
565 $right = substr($tag, $posspace);
566 }
567 $end = strlen($tag)-1;
568 if ( $tag[$end] == '"' ) {
569 $right = '"' . $right;
570 }
571 $finalurl = substr($tag,$start,$end-$start+$diff);
572 // Here, we could have these possible values for $finalurl:
573 // file.ext Add current root dir
574 // http://(domain) don't care
575 // http://(domain)/ don't care
576 // http://(domain)/folder don't care
577 // http://(domain)/folder/ don't care
578 // http://(domain)/folder/file.ext don't care
579 // folder/ Add current root dir
580 // folder/file.ext Add current root dir
581 // /folder/ Add main root dir
582 // /folder/file.ext Add main root dir
583
584 // Special case: If finalurl contains a ?, it won't be parsed
bf46cd22 585 $valid = 1;
af65e103 586
587 if ( strpos($finalurl,"?") == FALSE ) {
588 $valid = 1;
589 }
590 if ( $valid ) {
591 if ( $finalurl[0] == "/" ) {
592 $finalurl = $mainroot . $finalurl;
ec81373f 593 } elseif ( strtolower(substr($finalurl,0,7)) != "http://" and
af65e103 594 strtolower(substr($finalurl,0,8)) != "https://") {
595 if ( $finalurl[0] == "/") {
596 $finalurl = $mainroot . $finalurl;
597 } else {
598 $finalurl = "$root/$finalurl";
599 }
600 }
ec81373f 601
af65e103 602 $text = str_replace($tag,"$left$prefix$finalurl$right",$text);
603 }
604 }
605 }
606 return $text;
607}
8dddba42 608
d18830fe 609function resource_is_url($path) {
427c8ccb 610 if (strpos($path, '://')) { // eg http:// https:// ftp:// etc
d18830fe 611 return true;
612 }
427c8ccb 613 if (strpos($path, '/') === 0) { // Starts with slash
614 return true;
615 }
616 return false;
d18830fe 617}
618
6da4b261 619function resource_get_resource_types() {
620/// Returns a menu of current resource types, in standard order
37147357 621 global $resource_standard_order, $CFG;
6da4b261 622
623 $resources = array();
624
625 /// Standard resource types
3d30a455 626 $standardresources = array('text','html','file','directory');
6da4b261 627 foreach ($standardresources as $resourcetype) {
628 $resources[$resourcetype] = get_string("resourcetype$resourcetype", 'resource');
629 }
630
631 /// Drop-in extra resource types
632 $resourcetypes = get_list_of_plugins('mod/resource/type');
633 foreach ($resourcetypes as $resourcetype) {
37147357 634 if (!empty($CFG->{'resource_hide_'.$resourcetype})) { // Not wanted
635 continue;
636 }
6da4b261 637 if (!in_array($resourcetype, $resources)) {
638 $resources[$resourcetype] = get_string("resourcetype$resourcetype", 'resource');
639 }
640 }
641 return $resources;
642}
2a439ba7 643?>