Commit | Line | Data |
---|---|---|
58a27a74 | 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/>. | |
17 | ||
18 | /** | |
19 | * Mandatory public API of url module | |
20 | * | |
11e41f1a | 21 | * @package mod_url |
2b641d15 PS |
22 | * @copyright 2009 Petr Skoda {@link http://skodak.org} |
23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
58a27a74 | 24 | */ |
25 | ||
2b641d15 PS |
26 | defined('MOODLE_INTERNAL') || die; |
27 | ||
58a27a74 | 28 | /** |
29 | * List of features supported in URL module | |
30 | * @param string $feature FEATURE_xx constant for requested feature | |
31 | * @return mixed True if module supports feature, false if not, null if doesn't know | |
32 | */ | |
33 | function url_supports($feature) { | |
34 | switch($feature) { | |
35 | case FEATURE_MOD_ARCHETYPE: return MOD_ARCHETYPE_RESOURCE; | |
36 | case FEATURE_GROUPS: return false; | |
37 | case FEATURE_GROUPINGS: return false; | |
58a27a74 | 38 | case FEATURE_MOD_INTRO: return true; |
39 | case FEATURE_COMPLETION_TRACKS_VIEWS: return true; | |
40 | case FEATURE_GRADE_HAS_GRADE: return false; | |
41 | case FEATURE_GRADE_OUTCOMES: return false; | |
e6e79f84 | 42 | case FEATURE_BACKUP_MOODLE2: return true; |
3e4c2435 | 43 | case FEATURE_SHOW_DESCRIPTION: return true; |
58a27a74 | 44 | |
45 | default: return null; | |
46 | } | |
47 | } | |
48 | ||
58a27a74 | 49 | /** |
50 | * This function is used by the reset_course_userdata function in moodlelib. | |
51 | * @param $data the data submitted from the reset course. | |
52 | * @return array status array | |
53 | */ | |
54 | function url_reset_userdata($data) { | |
0d14fcbc AA |
55 | |
56 | // Any changes to the list of dates that needs to be rolled should be same during course restore and course reset. | |
57 | // See MDL-9367. | |
58 | ||
58a27a74 | 59 | return array(); |
60 | } | |
61 | ||
62 | /** | |
b2b4ec30 RT |
63 | * List the actions that correspond to a view of this module. |
64 | * This is used by the participation report. | |
65 | * | |
66 | * Note: This is not used by new logging system. Event with | |
67 | * crud = 'r' and edulevel = LEVEL_PARTICIPATING will | |
68 | * be considered as view action. | |
69 | * | |
58a27a74 | 70 | * @return array |
71 | */ | |
72 | function url_get_view_actions() { | |
cf051cc4 | 73 | return array('view', 'view all'); |
58a27a74 | 74 | } |
75 | ||
76 | /** | |
b2b4ec30 RT |
77 | * List the actions that correspond to a post of this module. |
78 | * This is used by the participation report. | |
79 | * | |
80 | * Note: This is not used by new logging system. Event with | |
81 | * crud = ('c' || 'u' || 'd') and edulevel = LEVEL_PARTICIPATING | |
82 | * will be considered as post action. | |
83 | * | |
58a27a74 | 84 | * @return array |
85 | */ | |
86 | function url_get_post_actions() { | |
cf051cc4 | 87 | return array('update', 'add'); |
58a27a74 | 88 | } |
89 | ||
90 | /** | |
91 | * Add url instance. | |
92 | * @param object $data | |
93 | * @param object $mform | |
94 | * @return int new url instance id | |
95 | */ | |
96 | function url_add_instance($data, $mform) { | |
48f69e41 PS |
97 | global $CFG, $DB; |
98 | ||
99 | require_once($CFG->dirroot.'/mod/url/locallib.php'); | |
58a27a74 | 100 | |
101 | $parameters = array(); | |
102 | for ($i=0; $i < 100; $i++) { | |
103 | $parameter = "parameter_$i"; | |
104 | $variable = "variable_$i"; | |
105 | if (empty($data->$parameter) or empty($data->$variable)) { | |
106 | continue; | |
107 | } | |
108 | $parameters[$data->$parameter] = $data->$variable; | |
109 | } | |
110 | $data->parameters = serialize($parameters); | |
111 | ||
112 | $displayoptions = array(); | |
113 | if ($data->display == RESOURCELIB_DISPLAY_POPUP) { | |
114 | $displayoptions['popupwidth'] = $data->popupwidth; | |
115 | $displayoptions['popupheight'] = $data->popupheight; | |
116 | } | |
117 | if (in_array($data->display, array(RESOURCELIB_DISPLAY_AUTO, RESOURCELIB_DISPLAY_EMBED, RESOURCELIB_DISPLAY_FRAME))) { | |
58a27a74 | 118 | $displayoptions['printintro'] = (int)!empty($data->printintro); |
119 | } | |
120 | $data->displayoptions = serialize($displayoptions); | |
121 | ||
48f69e41 | 122 | $data->externalurl = url_fix_submitted_url($data->externalurl); |
58a27a74 | 123 | |
124 | $data->timemodified = time(); | |
125 | $data->id = $DB->insert_record('url', $data); | |
126 | ||
b3bd7a66 MN |
127 | $completiontimeexpected = !empty($data->completionexpected) ? $data->completionexpected : null; |
128 | \core_completion\api::update_completion_date_event($data->coursemodule, 'url', $data->id, $completiontimeexpected); | |
129 | ||
58a27a74 | 130 | return $data->id; |
131 | } | |
132 | ||
133 | /** | |
134 | * Update url instance. | |
135 | * @param object $data | |
136 | * @param object $mform | |
137 | * @return bool true | |
138 | */ | |
139 | function url_update_instance($data, $mform) { | |
140 | global $CFG, $DB; | |
141 | ||
48f69e41 PS |
142 | require_once($CFG->dirroot.'/mod/url/locallib.php'); |
143 | ||
58a27a74 | 144 | $parameters = array(); |
145 | for ($i=0; $i < 100; $i++) { | |
146 | $parameter = "parameter_$i"; | |
147 | $variable = "variable_$i"; | |
148 | if (empty($data->$parameter) or empty($data->$variable)) { | |
149 | continue; | |
150 | } | |
151 | $parameters[$data->$parameter] = $data->$variable; | |
152 | } | |
153 | $data->parameters = serialize($parameters); | |
154 | ||
155 | $displayoptions = array(); | |
156 | if ($data->display == RESOURCELIB_DISPLAY_POPUP) { | |
157 | $displayoptions['popupwidth'] = $data->popupwidth; | |
158 | $displayoptions['popupheight'] = $data->popupheight; | |
159 | } | |
160 | if (in_array($data->display, array(RESOURCELIB_DISPLAY_AUTO, RESOURCELIB_DISPLAY_EMBED, RESOURCELIB_DISPLAY_FRAME))) { | |
58a27a74 | 161 | $displayoptions['printintro'] = (int)!empty($data->printintro); |
162 | } | |
163 | $data->displayoptions = serialize($displayoptions); | |
164 | ||
48f69e41 | 165 | $data->externalurl = url_fix_submitted_url($data->externalurl); |
58a27a74 | 166 | |
167 | $data->timemodified = time(); | |
168 | $data->id = $data->instance; | |
169 | ||
170 | $DB->update_record('url', $data); | |
171 | ||
b3bd7a66 MN |
172 | $completiontimeexpected = !empty($data->completionexpected) ? $data->completionexpected : null; |
173 | \core_completion\api::update_completion_date_event($data->coursemodule, 'url', $data->id, $completiontimeexpected); | |
174 | ||
58a27a74 | 175 | return true; |
176 | } | |
177 | ||
178 | /** | |
179 | * Delete url instance. | |
180 | * @param int $id | |
181 | * @return bool true | |
182 | */ | |
183 | function url_delete_instance($id) { | |
184 | global $DB; | |
185 | ||
186 | if (!$url = $DB->get_record('url', array('id'=>$id))) { | |
187 | return false; | |
188 | } | |
189 | ||
b3bd7a66 MN |
190 | $cm = get_coursemodule_from_instance('url', $id); |
191 | \core_completion\api::update_completion_date_event($cm->id, 'url', $id, null); | |
192 | ||
58a27a74 | 193 | // note: all context files are deleted automatically |
194 | ||
195 | $DB->delete_records('url', array('id'=>$url->id)); | |
196 | ||
197 | return true; | |
198 | } | |
199 | ||
58a27a74 | 200 | /** |
201 | * Given a course_module object, this function returns any | |
202 | * "extra" information that may be needed when printing | |
203 | * this activity in a course listing. | |
204 | * | |
205 | * See {@link get_array_of_activities()} in course/lib.php | |
206 | * | |
207 | * @param object $coursemodule | |
3c620d7f | 208 | * @return cached_cm_info info |
58a27a74 | 209 | */ |
210 | function url_get_coursemodule_info($coursemodule) { | |
211 | global $CFG, $DB; | |
212 | require_once("$CFG->dirroot/mod/url/locallib.php"); | |
213 | ||
3e4c2435 | 214 | if (!$url = $DB->get_record('url', array('id'=>$coursemodule->instance), |
3b0168ce | 215 | 'id, name, display, displayoptions, externalurl, parameters, intro, introformat')) { |
58a27a74 | 216 | return NULL; |
217 | } | |
218 | ||
3e4c2435 | 219 | $info = new cached_cm_info(); |
58a27a74 | 220 | $info->name = $url->name; |
221 | ||
222 | //note: there should be a way to differentiate links from normal resources | |
bb128107 | 223 | $info->icon = url_guess_icon($url->externalurl, 24); |
58a27a74 | 224 | |
225 | $display = url_get_final_display_type($url); | |
226 | ||
227 | if ($display == RESOURCELIB_DISPLAY_POPUP) { | |
228 | $fullurl = "$CFG->wwwroot/mod/url/view.php?id=$coursemodule->id&redirect=1"; | |
229 | $options = empty($url->displayoptions) ? array() : unserialize($url->displayoptions); | |
230 | $width = empty($options['popupwidth']) ? 620 : $options['popupwidth']; | |
231 | $height = empty($options['popupheight']) ? 450 : $options['popupheight']; | |
232 | $wh = "width=$width,height=$height,toolbar=no,location=no,menubar=no,copyhistory=no,status=no,directories=no,scrollbars=yes,resizable=yes"; | |
3e4c2435 | 233 | $info->onclick = "window.open('$fullurl', '', '$wh'); return false;"; |
58a27a74 | 234 | |
235 | } else if ($display == RESOURCELIB_DISPLAY_NEW) { | |
236 | $fullurl = "$CFG->wwwroot/mod/url/view.php?id=$coursemodule->id&redirect=1"; | |
3e4c2435 | 237 | $info->onclick = "window.open('$fullurl'); return false;"; |
58a27a74 | 238 | |
3e4c2435 | 239 | } |
240 | ||
241 | if ($coursemodule->showdescription) { | |
242 | // Convert intro to html. Do not filter cached version, filters run at display time. | |
243 | $info->content = format_module_intro('url', $url, $coursemodule->id, false); | |
58a27a74 | 244 | } |
245 | ||
246 | return $info; | |
247 | } | |
248 | ||
b1627a92 DC |
249 | /** |
250 | * Return a list of page types | |
251 | * @param string $pagetype current page type | |
252 | * @param stdClass $parentcontext Block's parent context | |
253 | * @param stdClass $currentcontext Current context of block | |
254 | */ | |
b38e2e28 | 255 | function url_page_type_list($pagetype, $parentcontext, $currentcontext) { |
b1627a92 DC |
256 | $module_pagetype = array('mod-url-*'=>get_string('page-mod-url-x', 'url')); |
257 | return $module_pagetype; | |
258 | } | |
ec0d6ea2 DC |
259 | |
260 | /** | |
261 | * Export URL resource contents | |
262 | * | |
263 | * @return array of file content | |
264 | */ | |
265 | function url_export_contents($cm, $baseurl) { | |
266 | global $CFG, $DB; | |
267 | require_once("$CFG->dirroot/mod/url/locallib.php"); | |
268 | $contents = array(); | |
6fd7b70f | 269 | $context = context_module::instance($cm->id); |
ec0d6ea2 | 270 | |
74df2951 | 271 | $course = $DB->get_record('course', array('id'=>$cm->course), '*', MUST_EXIST); |
1b126c08 | 272 | $urlrecord = $DB->get_record('url', array('id'=>$cm->instance), '*', MUST_EXIST); |
ec0d6ea2 | 273 | |
1b126c08 | 274 | $fullurl = str_replace('&', '&', url_get_full_url($urlrecord, $cm, $course)); |
ec0d6ea2 DC |
275 | $isurl = clean_param($fullurl, PARAM_URL); |
276 | if (empty($isurl)) { | |
277 | return null; | |
278 | } | |
279 | ||
280 | $url = array(); | |
281 | $url['type'] = 'url'; | |
e13c152e | 282 | $url['filename'] = clean_param(format_string($urlrecord->name), PARAM_FILE); |
ec0d6ea2 DC |
283 | $url['filepath'] = null; |
284 | $url['filesize'] = 0; | |
285 | $url['fileurl'] = $fullurl; | |
286 | $url['timecreated'] = null; | |
1b126c08 | 287 | $url['timemodified'] = $urlrecord->timemodified; |
ec0d6ea2 DC |
288 | $url['sortorder'] = null; |
289 | $url['userid'] = null; | |
290 | $url['author'] = null; | |
291 | $url['license'] = null; | |
292 | $contents[] = $url; | |
293 | ||
294 | return $contents; | |
295 | } | |
32528f94 DS |
296 | |
297 | /** | |
298 | * Register the ability to handle drag and drop file uploads | |
299 | * @return array containing details of the files / types the mod can handle | |
300 | */ | |
6b8b0b2e | 301 | function url_dndupload_register() { |
32528f94 DS |
302 | return array('types' => array( |
303 | array('identifier' => 'url', 'message' => get_string('createurl', 'url')) | |
304 | )); | |
305 | } | |
306 | ||
307 | /** | |
308 | * Handle a file that has been uploaded | |
309 | * @param object $uploadinfo details of the file / content that has been uploaded | |
310 | * @return int instance id of the newly created mod | |
311 | */ | |
6b8b0b2e | 312 | function url_dndupload_handle($uploadinfo) { |
abed5d65 DS |
313 | // Gather all the required data. |
314 | $data = new stdClass(); | |
315 | $data->course = $uploadinfo->course->id; | |
316 | $data->name = $uploadinfo->displayname; | |
317 | $data->intro = '<p>'.$uploadinfo->displayname.'</p>'; | |
318 | $data->introformat = FORMAT_HTML; | |
319 | $data->externalurl = clean_param($uploadinfo->content, PARAM_URL); | |
320 | $data->timemodified = time(); | |
16d77f18 | 321 | $data->coursemodule = $uploadinfo->coursemodule; |
32528f94 | 322 | |
abed5d65 | 323 | // Set the display options to the site defaults. |
32528f94 | 324 | $config = get_config('url'); |
abed5d65 DS |
325 | $data->display = $config->display; |
326 | $data->popupwidth = $config->popupwidth; | |
327 | $data->popupheight = $config->popupheight; | |
abed5d65 | 328 | $data->printintro = $config->printintro; |
32528f94 | 329 | |
abed5d65 | 330 | return url_add_instance($data, null); |
32528f94 | 331 | } |
f3fe1b8b JL |
332 | |
333 | /** | |
334 | * Mark the activity completed (if required) and trigger the course_module_viewed event. | |
335 | * | |
336 | * @param stdClass $url url object | |
337 | * @param stdClass $course course object | |
338 | * @param stdClass $cm course module object | |
339 | * @param stdClass $context context object | |
340 | * @since Moodle 3.0 | |
341 | */ | |
342 | function url_view($url, $course, $cm, $context) { | |
343 | ||
344 | // Trigger course_module_viewed event. | |
345 | $params = array( | |
346 | 'context' => $context, | |
347 | 'objectid' => $url->id | |
348 | ); | |
349 | ||
350 | $event = \mod_url\event\course_module_viewed::create($params); | |
351 | $event->add_record_snapshot('course_modules', $cm); | |
352 | $event->add_record_snapshot('course', $course); | |
353 | $event->add_record_snapshot('url', $url); | |
354 | $event->trigger(); | |
355 | ||
356 | // Completion. | |
357 | $completion = new completion_info($course); | |
358 | $completion->set_module_viewed($cm); | |
359 | } | |
02a73d76 JL |
360 | |
361 | /** | |
362 | * Check if the module has any update that affects the current user since a given time. | |
363 | * | |
364 | * @param cm_info $cm course module data | |
365 | * @param int $from the time to check updates from | |
366 | * @param array $filter if we need to check only specific updates | |
367 | * @return stdClass an object with the different type of areas indicating if they were updated or not | |
368 | * @since Moodle 3.2 | |
369 | */ | |
370 | function url_check_updates_since(cm_info $cm, $from, $filter = array()) { | |
371 | $updates = course_check_module_updates_since($cm, $from, array('content'), $filter); | |
372 | return $updates; | |
373 | } | |
b3bd7a66 MN |
374 | |
375 | /** | |
59391e80 MN |
376 | * This function receives a calendar event and returns the action associated with it, or null if there is none. |
377 | * | |
378 | * This is used by block_myoverview in order to display the event appropriately. If null is returned then the event | |
379 | * is not displayed on the block. | |
b3bd7a66 | 380 | * |
e1cd93ce | 381 | * @param calendar_event $event |
b3bd7a66 | 382 | * @param \core_calendar\action_factory $factory |
dcb7662e | 383 | * @param int $userid ID override for calendar events |
01f96180 | 384 | * @return \core_calendar\local\event\entities\action_interface|null |
b3bd7a66 | 385 | */ |
e1cd93ce | 386 | function mod_url_core_calendar_provide_event_action(calendar_event $event, |
dcb7662e P |
387 | \core_calendar\action_factory $factory, $userid = 0) { |
388 | ||
389 | global $USER; | |
390 | if (empty($userid)) { | |
391 | $userid = $USER->id; | |
392 | } | |
393 | ||
394 | $cm = get_fast_modinfo($event->courseid, $userid)->instances['url'][$event->instance]; | |
b3bd7a66 | 395 | |
50d845e3 | 396 | $completion = new \completion_info($cm->get_course()); |
b3bd7a66 | 397 | |
dcb7662e | 398 | $completiondata = $completion->get_data($cm, false, $userid); |
b3bd7a66 MN |
399 | |
400 | if ($completiondata->completionstate != COMPLETION_INCOMPLETE) { | |
401 | return null; | |
402 | } | |
403 | ||
404 | return $factory->create_instance( | |
405 | get_string('view'), | |
406 | new \moodle_url('/mod/url/view.php', ['id' => $cm->id]), | |
407 | 1, | |
408 | true | |
409 | ); | |
410 | } |