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 |
25 | require_once($CFG->libdir.'/portfoliolib.php'); |
26 | |
28f672b2 |
27 | /** RESOURCE_LOCALPATH = LOCALPATH */ |
713d78ea |
28 | define('RESOURCE_LOCALPATH', 'LOCALPATH'); |
29 | |
28f672b2 |
30 | /** |
31 | * @global array $RESOURCE_WINDOW_OPTIONS |
32 | * @name $RESOURCE_WINDOW_OPTIONS |
33 | */ |
220a90c5 |
34 | global $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 |
46 | class 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 |
307 | function 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 |
325 | function 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 |
344 | function 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 |
369 | function 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 |
395 | function 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 |
420 | function 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 |
436 | function 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&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 |
479 | function 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 |
571 | function 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 |
586 | function 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&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&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 |
623 | function resource_get_view_actions() { |
624 | return array('view','view all'); |
625 | } |
626 | |
28f672b2 |
627 | /** |
628 | * @return array |
629 | */ |
f3221af9 |
630 | function 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 |
642 | function 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 |
696 | function 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 | */ |
752 | function 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 | */ |
761 | function 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 |
770 | class 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 | */ |
917 | function 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 | */ |
940 | function 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 | } |