3 define('RESOURCE_LOCALPATH', 'LOCALPATH');
5 global $RESOURCE_WINDOW_OPTIONS; // must be global because it might be included from a function!
6 $RESOURCE_WINDOW_OPTIONS = array('resizable', 'scrollbars', 'directories', 'location',
7 'menubar', 'toolbar', 'status', 'width', 'height');
9 if (!isset($CFG->resource_hide_repository
)) {
10 set_config("resource_hide_repository", "1");
14 * resource_base is the base class for resource types
16 * This class provides all the functionality for a resource
27 * Constructor for the base resource class
29 * Constructor for the base resource class.
30 * If cmid is set create the cm, course, resource objects.
31 * and do some checks to make sure people can be here, and so on.
33 * @param cmid integer, the current course module id - not set for new resources
35 function resource_base($cmid=0) {
38 $this->navlinks
= array();
41 if (! $this->cm
= get_coursemodule_from_id('resource', $cmid)) {
42 error("Course Module ID was incorrect");
45 if (! $this->course
= get_record("course", "id", $this->cm
->course
)) {
46 error("Course is misconfigured");
49 if (! $this->resource = get_record("resource", "id", $this->cm
->instance
)) {
50 error("Resource ID was incorrect");
53 $this->strresource
= get_string("modulename", "resource");
54 $this->strresources
= get_string("modulenameplural", "resource");
56 if (!$this->cm
->visible
and !has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_MODULE
, $this->cm
->id
))) {
57 $pagetitle = strip_tags($this->course
->shortname
.': '.$this->strresource
);
58 $navigation = build_navigation($this->navlinks
, $this->cm
);
60 print_header($pagetitle, $this->course
->fullname
, $navigation, "", "", true, '', navmenu($this->course
, $this->cm
));
61 notice(get_string("activityiscurrentlyhidden"), "$CFG->wwwroot/course/view.php?id={$this->course->id}");
65 $this->course
= $COURSE;
71 * Display function does nothing in the base class
79 * Display the resource with the course blocks.
81 function display_course_blocks_start() {
87 require_once($CFG->libdir
.'/blocklib.php');
88 require_once($CFG->libdir
.'/pagelib.php');
89 require_once($CFG->dirroot
.'/course/lib.php'); //required by some blocks
91 $PAGE = page_create_object(PAGE_COURSE_VIEW
, $this->course
->id
);
93 $pageblocks = blocks_setup($PAGE);
95 $blocks_preferred_width = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT
]), 210);
97 /// Print the page header
99 $edit = optional_param('edit', -1, PARAM_BOOL
);
101 if (($edit != -1) and $PAGE->user_allowed_editing()) {
102 $USER->editing
= $edit;
105 $morenavlinks = array($this->strresources
=> 'index.php?id='.$this->course
->id
,
106 $this->resource->name
=> '');
108 $PAGE->print_header($this->course
->shortname
.': %fullname%', $morenavlinks, "", "",
109 update_module_button($this->cm
->id
, $this->course
->id
, $this->strresource
));
111 echo '<table id="layout-table"><tr>';
113 $lt = (empty($THEME->layouttable
)) ?
array('left', 'middle', 'right') : $THEME->layouttable
;
114 foreach ($lt as $column) {
116 if ($column == 'middle') break;
118 foreach ($lt1 as $column) {
121 if((blocks_have_content($pageblocks, BLOCK_POS_LEFT
) ||
$PAGE->user_is_editing())) {
122 echo '<td style="width: '.$blocks_preferred_width.'px;" id="left-column">';
123 print_container_start();
124 blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT
);
125 print_container_end();
131 echo '<td id="middle-column">';
132 print_container_start(false, 'middle-column-wrap');
133 echo '<div id="resource">';
137 if((blocks_have_content($pageblocks, BLOCK_POS_RIGHT
) ||
$PAGE->user_is_editing())) {
138 echo '<td style="width: '.$blocks_preferred_width.'px;" id="right-column">';
139 print_container_start();
140 blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT
);
141 print_container_end();
151 * Finish displaying the resource with the course blocks
153 function display_course_blocks_end() {
159 $pageblocks = blocks_setup($PAGE);
160 $blocks_preferred_width = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT
]), 210);
162 $lt = (empty($THEME->layouttable
)) ?
array('left', 'middle', 'right') : $THEME->layouttable
;
163 foreach ($lt as $column) {
164 if ($column != 'middle') {
166 } else if ($column == 'middle') {
170 foreach ($lt as $column) {
173 if((blocks_have_content($pageblocks, BLOCK_POS_LEFT
) ||
$PAGE->user_is_editing())) {
174 echo '<td style="width: '.$blocks_preferred_width.'px;" id="left-column">';
175 print_container_start();
176 blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT
);
177 print_container_end();
184 print_container_end();
189 if((blocks_have_content($pageblocks, BLOCK_POS_RIGHT
) ||
$PAGE->user_is_editing())) {
190 echo '<td style="width: '.$blocks_preferred_width.'px;" id="right-column">';
191 print_container_start();
192 blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT
);
193 print_container_end();
200 echo '</tr></table>';
202 print_footer($this->course
);
207 function add_instance($resource) {
208 // Given an object containing all the necessary data,
209 // (defined by the form in mod.html) this function
210 // will create a new instance and return the id number
211 // of the new instance.
213 $resource->timemodified
= time();
215 return insert_record("resource", $resource);
219 function update_instance($resource) {
220 // Given an object containing all the necessary data,
221 // (defined by the form in mod.html) this function
222 // will update an existing instance with new data.
224 $resource->id
= $resource->instance
;
225 $resource->timemodified
= time();
227 return update_record("resource", $resource);
231 function delete_instance($resource) {
232 // Given an object containing the resource data
233 // this function will permanently delete the instance
234 // and any data that depends on it.
238 if (! delete_records("resource", "id", "$resource->id")) {
245 function setup_elements(&$mform) {
246 //override to add your own options
249 function setup_preprocessing(&$default_values){
250 //override to add your own options
253 } /// end of class definition
257 function resource_add_instance($resource) {
260 $resource->type
= clean_param($resource->type
, PARAM_SAFEDIR
); // Just to be safe
262 require_once("$CFG->dirroot/mod/resource/type/$resource->type/resource.class.php");
263 $resourceclass = "resource_$resource->type";
264 $res = new $resourceclass();
266 return $res->add_instance($resource);
269 function resource_update_instance($resource) {
272 $resource->type
= clean_param($resource->type
, PARAM_SAFEDIR
); // Just to be safe
274 require_once("$CFG->dirroot/mod/resource/type/$resource->type/resource.class.php");
275 $resourceclass = "resource_$resource->type";
276 $res = new $resourceclass();
278 return $res->update_instance($resource);
281 function resource_delete_instance($id) {
284 if (! $resource = get_record("resource", "id", "$id")) {
288 $resource->type
= clean_param($resource->type
, PARAM_SAFEDIR
); // Just to be safe
290 require_once("$CFG->dirroot/mod/resource/type/$resource->type/resource.class.php");
291 $resourceclass = "resource_$resource->type";
292 $res = new $resourceclass();
294 return $res->delete_instance($resource);
298 function resource_user_outline($course, $user, $mod, $resource) {
299 if ($logs = get_records_select("log", "userid='$user->id' AND module='resource'
300 AND action='view' AND info='$resource->id'", "time ASC")) {
302 $numviews = count($logs);
303 $lastlog = array_pop($logs);
305 $result = new object();
306 $result->info
= get_string("numviews", "", $numviews);
307 $result->time
= $lastlog->time
;
315 function resource_user_complete($course, $user, $mod, $resource) {
318 if ($logs = get_records_select("log", "userid='$user->id' AND module='resource'
319 AND action='view' AND info='$resource->id'", "time ASC")) {
320 $numviews = count($logs);
321 $lastlog = array_pop($logs);
323 $strmostrecently = get_string("mostrecently");
324 $strnumviews = get_string("numviews", "", $numviews);
326 echo "$strnumviews - $strmostrecently ".userdate($lastlog->time
);
329 print_string("neverseen", "resource");
333 function resource_get_participants($resourceid) {
334 //Returns the users with data in one resource
335 //(NONE, byt must exists on EVERY mod !!)
340 function resource_get_coursemodule_info($coursemodule) {
341 /// Given a course_module object, this function returns any
342 /// "extra" information that may be needed when printing
343 /// this activity in a course listing.
345 /// See get_array_of_activities() in course/lib.php
352 if ($resource = get_record("resource", "id", $coursemodule->instance
, '', '', '', '', 'id, popup, reference, type, name')) {
353 $info = new object();
354 $info->name
= $resource->name
;
355 if (!empty($resource->popup
)) {
356 $info->extra
= urlencode("onclick=\"this.target='resource$resource->id'; return ".
357 "openpopup('/mod/resource/view.php?inpopup=true&id=".
359 "','resource$resource->id','$resource->popup');\"");
362 require_once($CFG->libdir
.'/filelib.php');
364 if ($resource->type
== 'file') {
365 $icon = mimeinfo("icon", $resource->reference
);
366 if ($icon != 'unknown.gif') {
367 $info->icon
="f/$icon";
369 $info->icon
="f/web.gif";
371 } else if ($resource->type
== 'directory') {
372 $info->icon
="f/folder.gif";
379 function resource_fetch_remote_file ($cm, $url, $headers = "" ) {
380 /// Snoopy is an HTTP client in PHP
384 require_once("$CFG->libdir/snoopy/Snoopy.class.inc");
386 $client = new Snoopy();
387 $ua = 'Moodle/'. $CFG->release
. ' (+http://moodle.org';
388 if ( $CFG->resource_usecache
) {
391 $ua = $ua . '; No cache)';
393 $client->agent
= $ua;
394 $client->read_timeout
= 5;
395 $client->use_gzip
= true;
396 if (is_array($headers) ) {
397 $client->rawheaders
= $headers;
400 @$client->fetch($url);
401 if ( $client->status
>= 200 && $client->status
< 300 ) {
402 $tags = array("A" => "href=",
408 "FORM" => "action=");
410 foreach ($tags as $tag => $key) {
411 $prefix = "fetch.php?id=$cm->id&url=";
412 if ( $tag == "IMG" or $tag == "LINK" or $tag == "FORM") {
415 $client->results
= resource_redirect_tags($client->results
, $url, $tag, $key,$prefix);
418 if ( $client->status
>= 400 && $client->status
< 500) {
419 $client->results
= get_string("fetchclienterror","resource"); // Client error
420 } elseif ( $client->status
>= 500 && $client->status
< 600) {
421 $client->results
= get_string("fetchservererror","resource"); // Server error
423 $client->results
= get_string("fetcherror","resource"); // Redirection? HEAD? Unknown error.
429 function resource_redirect_tags($text, $url, $tagtoparse, $keytoparse,$prefix = "" ) {
431 if ( strpos($url,"?") == FALSE ) {
435 $lastpoint = strrpos($url,".");
436 $lastslash = strrpos($url,"/");
437 if ( $lastpoint > $lastslash ) {
438 $root = substr($url,0,$lastslash+
1);
442 if ( $root == "http://" or
443 $root == "https://") {
446 if ( substr($root,strlen($root)-1) == '/' ) {
447 $root = substr($root,0,-1);
451 $lastslash = strrpos($mainroot,"/");
452 while ( $lastslash > 9) {
453 $mainroot = substr($mainroot,0,$lastslash);
455 $lastslash = strrpos($mainroot,"/");
458 $regex = "/<$tagtoparse (.+?)>/is";
459 $count = preg_match_all($regex, $text, $hrefs);
460 for ( $i = 0; $i < $count; $i++
) {
461 $tag = $hrefs[1][$i];
463 $poshref = strpos(strtolower($tag),strtolower($keytoparse));
464 $start = $poshref +
strlen($keytoparse);
465 $left = substr($tag,0,$start);
466 if ( $tag[$start] == '"' ) {
470 $posspace = strpos($tag," ", $start+
1);
472 if ( $posspace != FALSE) {
473 $right = substr($tag, $posspace);
475 $end = strlen($tag)-1;
476 if ( $tag[$end] == '"' ) {
477 $right = '"' . $right;
479 $finalurl = substr($tag,$start,$end-$start+
$diff);
480 // Here, we could have these possible values for $finalurl:
481 // file.ext Add current root dir
482 // http://(domain) don't care
483 // http://(domain)/ don't care
484 // http://(domain)/folder don't care
485 // http://(domain)/folder/ don't care
486 // http://(domain)/folder/file.ext don't care
487 // folder/ Add current root dir
488 // folder/file.ext Add current root dir
489 // /folder/ Add main root dir
490 // /folder/file.ext Add main root dir
492 // Special case: If finalurl contains a ?, it won't be parsed
495 if ( strpos($finalurl,"?") == FALSE ) {
499 if ( $finalurl[0] == "/" ) {
500 $finalurl = $mainroot . $finalurl;
501 } elseif ( strtolower(substr($finalurl,0,7)) != "http://" and
502 strtolower(substr($finalurl,0,8)) != "https://") {
503 if ( $finalurl[0] == "/") {
504 $finalurl = $mainroot . $finalurl;
506 $finalurl = "$root/$finalurl";
510 $text = str_replace($tag,"$left$prefix$finalurl$right",$text);
517 function resource_is_url($path) {
518 if (strpos($path, '://')) { // eg http:// https:// ftp:// etc
521 if (strpos($path, '/') === 0) { // Starts with slash
527 function resource_get_types() {
532 $standardresources = array('text','html','file','directory');
533 foreach ($standardresources as $resourcetype) {
534 $type = new object();
535 $type->modclass
= MOD_CLASS_RESOURCE
;
536 $type->name
= $resourcetype;
537 $type->type
= "resource&type=$resourcetype";
538 $type->typestr
= get_string("resourcetype$resourcetype", 'resource');
542 /// Drop-in extra resource types
543 $resourcetypes = get_list_of_plugins('mod/resource/type');
544 foreach ($resourcetypes as $resourcetype) {
545 if (!empty($CFG->{'resource_hide_'.$resourcetype})) { // Not wanted
548 if (!in_array($resourcetype, $standardresources)) {
549 $type = new object();
550 $type->modclass
= MOD_CLASS_RESOURCE
;
551 $type->name
= $resourcetype;
552 $type->type
= "resource&type=$resourcetype";
553 $type->typestr
= get_string("resourcetype$resourcetype", 'resource');
561 function resource_get_view_actions() {
562 return array('view','view all');
565 function resource_get_post_actions() {
569 function resource_renamefiles($course, $wdir, $oldname, $name) {
572 $status = '<p align=\"center\"><strong>'.get_string('affectedresources', 'resource').':</strong><ul>';
575 $old = trim($wdir.'/'.$oldname, '/');
576 $new = trim($wdir.'/'.$name, '/');
578 $sql = "SELECT r.id, r.reference, r.name, cm.id AS cmid
579 FROM {$CFG->prefix}resource r,
580 {$CFG->prefix}course_modules cm,
581 {$CFG->prefix}modules m
582 WHERE r.course = '{$course->id}'
583 AND m.name = 'resource'
585 AND cm.instance = r.id
586 AND (r.type = 'file' OR r.type = 'directory')
587 AND (r.reference LIKE '{$old}/%' OR r.reference = '{$old}')";
588 if ($resources = get_records_sql($sql)) {
589 foreach ($resources as $resource) {
591 $r->id
= $resource->id
;
593 if ($resource->reference
== $old) {
594 $r->reference
= addslashes($new);
596 $r->reference
= addslashes(preg_replace('|^'.preg_quote($old, '|').'/|', $new.'/', $resource->reference
));
598 if ($r->reference
!== '') {
600 $status .= "<li><a href=\"$CFG->wwwroot/mod/resource/view.php?id=$resource->cmid\" target=\"_blank\">$resource->name</a>: $resource->reference ==> $r->reference</li>";
601 if (!empty($CFG->resource_autofilerename
)) {
602 if (!update_record('resource', $r)) {
603 error("Error updating resource with ID $r->id.");
609 $status .= '</ul></p>';
613 if (empty($CFG->resource_autofilerename
)) {
614 notify(get_string('warningdisabledrename', 'resource'));
619 function resource_delete_warning($course, $files) {
624 foreach($files as $key=>$file) {
625 $files[$key] = trim($file, '/');
627 $sql = "SELECT r.id, r.reference, r.name, cm.id AS cmid
628 FROM {$CFG->prefix}resource r,
629 {$CFG->prefix}course_modules cm,
630 {$CFG->prefix}modules m
631 WHERE r.course = '{$course->id}'
632 AND m.name = 'resource'
634 AND cm.instance = r.id
635 AND (r.type = 'file' OR r.type = 'directory')";
636 if ($resources = get_records_sql($sql)) {
637 foreach ($resources as $resource) {
638 if ($resource->reference
== '') {
639 continue; // top shared directory does not prevent anything
641 if (in_array($resource->reference
, $files)) {
642 $found[$resource->id
] = $resource;
644 foreach($files as $file) {
645 if (preg_match('|^'.preg_quote($file, '|').'/|', $resource->reference
)) {
646 $found[$resource->id
] = $resource;
653 if (!empty($found)) {
655 print_simple_box_start("center");
656 echo '<p><strong>'.get_string('affectedresources', 'resource').':</strong><ul>';
657 foreach($found as $resource) {
658 echo "<li><a href=\"$CFG->wwwroot/mod/resource/view.php?id=$resource->cmid\" target=\"_blank\">$resource->name</a>: $resource->reference</li>";
661 print_simple_box_end();
670 * This function is used by the reset_course_userdata function in moodlelib.
671 * @param $data the data submitted from the reset course.
672 * @return array status array
674 function resource_reset_userdata($data) {
679 * Returns all other caps used in module
681 function resource_get_extra_capabilities() {
682 return array('moodle/site:accessallgroups');