Merged fix from stable
[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
1aef6fb7 132function setup(&$form) {
d18830fe 133 global $CFG, $usehtmleditor;
134
135 if (! empty($form->course)) {
136 if (! $this->course = get_record("course", "id", $form->course)) {
137 error("Course is misconfigured");
138 }
139 }
140
141 if (empty($form->name)) {
142 $form->name = "";
143 }
144 if (empty($form->type)) {
145 $form->type = "";
146 }
147 if (empty($form->summary)) {
148 $form->summary = "";
149 }
150 if (empty($form->reference)) {
151 $form->reference = "";
152 }
153 if (empty($form->alltext)) {
154 $form->alltext = "";
155 }
1aef6fb7 156 if (empty($form->options)) {
157 $form->options = "";
158 }
d18830fe 159 $nohtmleditorneeded = true;
160
6da4b261 161 print_heading_with_help(get_string("resourcetype$form->type", 'resource'), $form->type, 'resource/type');
d18830fe 162
163 include("$CFG->dirroot/mod/resource/type/common.html");
164}
165
166
167function setup_end() {
168 global $CFG;
169
170 include("$CFG->dirroot/mod/resource/type/common_end.html");
171}
172
173
174function add_instance($resource) {
ec81373f 175// Given an object containing all the necessary data,
176// (defined by the form in mod.html) this function
177// will create a new instance and return the id number
cccb016a 178// of the new instance.
2a439ba7 179
86aa7ccf 180 global $RESOURCE_WINDOW_OPTIONS;
181
cccb016a 182 $resource->timemodified = time();
2a439ba7 183
d18830fe 184 if (isset($resource->windowpopup)) {
7c990f68 185 if ($resource->windowpopup) {
186 $optionlist = array();
187 foreach ($RESOURCE_WINDOW_OPTIONS as $option) {
188 if (isset($resource->$option)) {
189 $optionlist[] = $option."=".$resource->$option;
190 }
86aa7ccf 191 }
7c990f68 192 $resource->popup = implode(',', $optionlist);
d18830fe 193 $resource->options = "";
7c990f68 194 } else {
195 if (isset($resource->framepage)) {
196 $resource->options = "frame";
197 } else {
198 $resource->options = "";
199 }
200 $resource->popup = "";
d18830fe 201 }
86aa7ccf 202 }
203
33935242 204 if (isset($resource->parametersettingspref)) {
205 set_user_preference('resource_parametersettingspref', $resource->parametersettingspref);
206 }
207 if (isset($resource->windowsettingspref)) {
208 set_user_preference('resource_windowsettingspref', $resource->windowsettingspref);
209 }
210
cccb016a 211 return insert_record("resource", $resource);
212}
2a439ba7 213
cccb016a 214
d18830fe 215function update_instance($resource) {
ec81373f 216// Given an object containing all the necessary data,
217// (defined by the form in mod.html) this function
cccb016a 218// will update an existing instance with new data.
219
86aa7ccf 220 global $RESOURCE_WINDOW_OPTIONS;
221
cccb016a 222 $resource->id = $resource->instance;
223 $resource->timemodified = time();
224
d18830fe 225 if (isset($resource->windowpopup)) {
7c990f68 226 if ($resource->windowpopup) {
227 $optionlist = array();
228 foreach ($RESOURCE_WINDOW_OPTIONS as $option) {
229 if (isset($resource->$option)) {
230 $optionlist[] = $option."=".$resource->$option;
231 }
86aa7ccf 232 }
7c990f68 233 $resource->popup = implode(',', $optionlist);
d18830fe 234 $resource->options = "";
7c990f68 235 } else {
236 if (isset($resource->framepage)) {
237 $resource->options = "frame";
238 } else {
239 $resource->options = "";
240 }
241 $resource->popup = "";
d18830fe 242 }
86aa7ccf 243 }
244
33935242 245 if (isset($resource->parametersettingspref)) {
246 set_user_preference('resource_parametersettingspref', $resource->parametersettingspref);
247 }
248 if (isset($resource->windowsettingspref)) {
249 set_user_preference('resource_windowsettingspref', $resource->windowsettingspref);
250 }
251
cccb016a 252 return update_record("resource", $resource);
253}
254
255
d18830fe 256function delete_instance($id) {
ec81373f 257// Given an ID of an instance of this module,
258// this function will permanently delete the instance
259// and any data that depends on it.
cccb016a 260
261 if (! $resource = get_record("resource", "id", "$id")) {
262 return false;
2a439ba7 263 }
264
cccb016a 265 $result = true;
266
267 if (! delete_records("resource", "id", "$resource->id")) {
268 $result = false;
2a439ba7 269 }
270
cccb016a 271 return $result;
2a439ba7 272}
cccb016a 273
2a439ba7 274
d18830fe 275
276} /// end of class definition
277
278
279
280function resource_add_instance($resource) {
281 global $CFG;
ec81373f 282
79035d46 283 $resource->type = clean_filename($resource->type); // Just to be safe
284
d18830fe 285 require_once("$CFG->dirroot/mod/resource/type/$resource->type/resource.class.php");
1aef6fb7 286 $resourceclass = "resource_$resource->type";
287 $res = new $resourceclass();
d18830fe 288
289 return $res->add_instance($resource);
290}
291
292function resource_update_instance($resource) {
293 global $CFG;
ec81373f 294
79035d46 295 $resource->type = clean_filename($resource->type); // Just to be safe
296
d18830fe 297 require_once("$CFG->dirroot/mod/resource/type/$resource->type/resource.class.php");
1aef6fb7 298 $resourceclass = "resource_$resource->type";
299 $res = new $resourceclass();
d18830fe 300
301 return $res->update_instance($resource);
302}
303
304function resource_delete_instance($id) {
305 global $CFG;
ec81373f 306
d18830fe 307 if (! $resource = get_record("resource", "id", "$id")) {
308 return false;
309 }
79035d46 310
311 $resource->type = clean_filename($resource->type); // Just to be safe
ec81373f 312
d18830fe 313 require_once("$CFG->dirroot/mod/resource/type/$resource->type/resource.class.php");
1aef6fb7 314 $resourceclass = "resource_$resource->type";
315 $res = new $resourceclass();
d18830fe 316
317 return $res->delete_instance($id);
318}
319
320
2a439ba7 321function resource_user_outline($course, $user, $mod, $resource) {
ec81373f 322 if ($logs = get_records_select("log", "userid='$user->id' AND module='resource'
ebc3bd2b 323 AND action='view' AND info='$resource->id'", "time ASC")) {
2a439ba7 324
325 $numviews = count($logs);
326 $lastlog = array_pop($logs);
327
328 $result->info = get_string("numviews", "", $numviews);
329 $result->time = $lastlog->time;
330
331 return $result;
332 }
333 return NULL;
334}
335
336
337function resource_user_complete($course, $user, $mod, $resource) {
9fad2dec 338 global $CFG;
2a439ba7 339
ec81373f 340 if ($logs = get_records_select("log", "userid='$user->id' AND module='resource'
ebc3bd2b 341 AND action='view' AND info='$resource->id'", "time ASC")) {
2a439ba7 342 $numviews = count($logs);
343 $lastlog = array_pop($logs);
344
345 $strmostrecently = get_string("mostrecently");
346 $strnumviews = get_string("numviews", "", $numviews);
347
348 echo "$strnumviews - $strmostrecently ".userdate($lastlog->time);
349
350 } else {
4282d7dd 351 print_string("neverseen", "resource");
2a439ba7 352 }
353}
354
84caf038 355function resource_get_participants($resourceid) {
356//Returns the users with data in one resource
357//(NONE, byt must exists on EVERY mod !!)
358
359 return false;
360}
2a439ba7 361
8dddba42 362function resource_get_coursemodule_info($coursemodule) {
ec81373f 363/// Given a course_module object, this function returns any
8dddba42 364/// "extra" information that may be needed when printing
365/// this activity in a course listing.
366///
367/// See get_array_of_activities() in course/lib.php
368///
369
9d361034 370 global $CFG;
371
372 $info = NULL;
373
8dddba42 374 if ($resource = get_record("resource", "id", $coursemodule->instance)) {
85e8239e 375 if (!empty($resource->popup)) {
657e7903 376 $info->extra = urlencode("target=\"resource$resource->id\" onclick=\"return ".
839f2456 377 "openpopup('/mod/resource/view.php?inpopup=true&amp;id=".
8dddba42 378 $coursemodule->id.
d18830fe 379 "','resource$resource->id','$resource->popup');\"");
8dddba42 380 }
9d361034 381
f1e0649c 382 require_once($CFG->libdir.'/filelib.php');
9d361034 383
85e8239e 384 if ($resource->type == 'file') {
ec81373f 385 $icon = mimeinfo("icon", $resource->reference);
9d361034 386 if ($icon != 'unknown.gif') {
ec81373f 387 $info->icon ="f/$icon";
85e8239e 388 } else {
ec81373f 389 $info->icon ="f/web.gif";
9d361034 390 }
d18830fe 391 } else if ($resource->type == 'directory') {
ec81373f 392 $info->icon ="f/folder.gif";
9d361034 393 }
8dddba42 394 }
395
9d361034 396 return $info;
8dddba42 397}
ec81373f 398
8367faba 399function resource_fetch_remote_file ($cm, $url, $headers = "" ) {
3bfe3922 400/// Snoopy is an HTTP client in PHP
401
402 global $CFG;
403
404 require_once("$CFG->libdir/snoopy/Snoopy.class.inc");
405
b2b8471e 406 $client = new Snoopy();
ec81373f 407 $ua = 'Moodle/'. $CFG->release . ' (+http://moodle.org';
bf46cd22 408 if ( $CFG->resource_usecache ) {
409 $ua = $ua . ')';
410 } else {
411 $ua = $ua . '; No cache)';
412 }
413 $client->agent = $ua;
414 $client->read_timeout = 5;
415 $client->use_gzip = true;
b2b8471e 416 if (is_array($headers) ) {
417 $client->rawheaders = $headers;
418 }
ec81373f 419
b2b8471e 420 @$client->fetch($url);
bf46cd22 421 if ( $client->status >= 200 && $client->status < 300 ) {
422 $tags = array("A" => "href=",
423 "IMG" => "src=",
424 "LINK" => "href=",
425 "AREA" => "href=",
426 "FRAME" => "src=",
427 "IFRAME" => "src=",
428 "FORM" => "action=");
ec81373f 429
bf46cd22 430 foreach ($tags as $tag => $key) {
839f2456 431 $prefix = "fetch.php?id=$cm->id&amp;url=";
bf46cd22 432 if ( $tag == "IMG" or $tag == "LINK" or $tag == "FORM") {
433 $prefix = "";
434 }
435 $client->results = resource_redirect_tags($client->results, $url, $tag, $key,$prefix);
436 }
437 } else {
438 if ( $client->status >= 400 && $client->status < 500) {
439 $client->results = get_string("fetchclienterror","resource"); // Client error
440 } elseif ( $client->status >= 500 && $client->status < 600) {
441 $client->results = get_string("fetchservererror","resource"); // Server error
442 } else {
443 $client->results = get_string("fetcherror","resource"); // Redirection? HEAD? Unknown error.
af65e103 444 }
af65e103 445 }
b2b8471e 446 return $client;
af65e103 447}
448
449function resource_redirect_tags($text, $url, $tagtoparse, $keytoparse,$prefix = "" ) {
bf46cd22 450 $valid = 1;
af65e103 451 if ( strpos($url,"?") == FALSE ) {
452 $valid = 1;
453 }
454 if ( $valid ) {
455 $lastpoint = strrpos($url,".");
456 $lastslash = strrpos($url,"/");
457 if ( $lastpoint > $lastslash ) {
458 $root = substr($url,0,$lastslash+1);
459 } else {
460 $root = $url;
461 }
ec81373f 462 if ( $root == "http://" or
af65e103 463 $root == "https://") {
464 $root = $url;
465 }
466 if ( substr($root,strlen($root)-1) == '/' ) {
467 $root = substr($root,0,-1);
468 }
ec81373f 469
af65e103 470 $mainroot = $root;
471 $lastslash = strrpos($mainroot,"/");
472 while ( $lastslash > 9) {
473 $mainroot = substr($mainroot,0,$lastslash);
ec81373f 474
af65e103 475 $lastslash = strrpos($mainroot,"/");
476 }
8dddba42 477
ec81373f 478 $regex = "/<$tagtoparse (.+?)>/is";
479 $count = preg_match_all($regex, $text, $hrefs);
af65e103 480 for ( $i = 0; $i < $count; $i++) {
481 $tag = $hrefs[1][$i];
ec81373f 482
af65e103 483 $poshref = strpos(strtolower($tag),strtolower($keytoparse));
484 $start = $poshref + strlen($keytoparse);
485 $left = substr($tag,0,$start);
486 if ( $tag[$start] == '"' ) {
487 $left .= '"';
488 $start++;
489 }
490 $posspace = strpos($tag," ", $start+1);
491 $right = "";
492 if ( $posspace != FALSE) {
493 $right = substr($tag, $posspace);
494 }
495 $end = strlen($tag)-1;
496 if ( $tag[$end] == '"' ) {
497 $right = '"' . $right;
498 }
499 $finalurl = substr($tag,$start,$end-$start+$diff);
500 // Here, we could have these possible values for $finalurl:
501 // file.ext Add current root dir
502 // http://(domain) don't care
503 // http://(domain)/ don't care
504 // http://(domain)/folder don't care
505 // http://(domain)/folder/ don't care
506 // http://(domain)/folder/file.ext don't care
507 // folder/ Add current root dir
508 // folder/file.ext Add current root dir
509 // /folder/ Add main root dir
510 // /folder/file.ext Add main root dir
511
512 // Special case: If finalurl contains a ?, it won't be parsed
bf46cd22 513 $valid = 1;
af65e103 514
515 if ( strpos($finalurl,"?") == FALSE ) {
516 $valid = 1;
517 }
518 if ( $valid ) {
519 if ( $finalurl[0] == "/" ) {
520 $finalurl = $mainroot . $finalurl;
ec81373f 521 } elseif ( strtolower(substr($finalurl,0,7)) != "http://" and
af65e103 522 strtolower(substr($finalurl,0,8)) != "https://") {
523 if ( $finalurl[0] == "/") {
524 $finalurl = $mainroot . $finalurl;
525 } else {
526 $finalurl = "$root/$finalurl";
527 }
528 }
ec81373f 529
af65e103 530 $text = str_replace($tag,"$left$prefix$finalurl$right",$text);
531 }
532 }
533 }
534 return $text;
535}
8dddba42 536
d18830fe 537function resource_is_url($path) {
427c8ccb 538 if (strpos($path, '://')) { // eg http:// https:// ftp:// etc
d18830fe 539 return true;
540 }
427c8ccb 541 if (strpos($path, '/') === 0) { // Starts with slash
542 return true;
543 }
544 return false;
d18830fe 545}
546
6da4b261 547function resource_get_resource_types() {
548/// Returns a menu of current resource types, in standard order
37147357 549 global $resource_standard_order, $CFG;
6da4b261 550
551 $resources = array();
552
553 /// Standard resource types
3d30a455 554 $standardresources = array('text','html','file','directory');
6da4b261 555 foreach ($standardresources as $resourcetype) {
556 $resources[$resourcetype] = get_string("resourcetype$resourcetype", 'resource');
557 }
558
559 /// Drop-in extra resource types
560 $resourcetypes = get_list_of_plugins('mod/resource/type');
561 foreach ($resourcetypes as $resourcetype) {
37147357 562 if (!empty($CFG->{'resource_hide_'.$resourcetype})) { // Not wanted
563 continue;
564 }
6da4b261 565 if (!in_array($resourcetype, $resources)) {
566 $resources[$resourcetype] = get_string("resourcetype$resourcetype", 'resource');
567 }
568 }
569 return $resources;
570}
2a439ba7 571?>