3 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
19 * Private url module utility functions
23 * @copyright 2009 Petr Skoda {@link http://skodak.org}
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 defined('MOODLE_INTERNAL') || die;
29 require_once("$CFG->libdir/filelib.php");
30 require_once("$CFG->libdir/resourcelib.php");
31 require_once("$CFG->dirroot/mod/url/lib.php");
34 * Return full url with all extra parameters
37 * @param object $course
40 function url_get_full_url($url, $cm, $course, $config=null) {
42 $parameters = empty($url->parameters) ? array() : unserialize($url->parameters);
44 if (empty($parameters)) {
46 return $url->externalurl;
50 $config = get_config('url');
52 $paramvalues = url_get_variable_values($url, $cm, $course, $config);
54 foreach ($parameters as $parse=>$parameter) {
55 if (isset($paramvalues[$parameter])) {
56 $parameters[$parse] = urlencode($parse).'='.urlencode($paramvalues[$parameter]);
58 unset($parameters[$parse]);
62 if (empty($parameters)) {
63 // easy - no params available
64 return $url->externalurl;
67 if (stripos($url->externalurl, 'teamspeak://') === 0) {
68 return $url->externalurl.'?'.implode('?', $parameters);
70 $join = (strpos($url->externalurl, '?') === false) ? '?' : '&';
71 return $url->externalurl.$join.implode('&', $parameters);
79 * @param object $course
82 function url_print_header($url, $cm, $course) {
83 global $PAGE, $OUTPUT;
85 $PAGE->set_title($course->shortname.': '.$url->name);
86 $PAGE->set_heading($course->fullname);
87 $PAGE->set_activity_record($url);
88 echo $OUTPUT->header();
95 * @param object $course
96 * @param bool $ignoresettings print even if not specified in modedit
99 function url_print_heading($url, $cm, $course, $ignoresettings=false) {
102 $options = empty($url->displayoptions) ? array() : unserialize($url->displayoptions);
104 if ($ignoresettings or !empty($options['printheading'])) {
105 echo $OUTPUT->heading(format_string($url->name), 2, 'main', 'urlheading');
110 * Print url introduction.
113 * @param object $course
114 * @param bool $ignoresettings print even if not specified in modedit
117 function url_print_intro($url, $cm, $course, $ignoresettings=false) {
120 $options = empty($url->displayoptions) ? array() : unserialize($url->displayoptions);
121 if ($ignoresettings or !empty($options['printintro'])) {
122 if (trim(strip_tags($url->intro))) {
123 echo $OUTPUT->box_start('mod_introbox', 'urlintro');
124 echo format_module_intro('url', $url, $cm->id);
125 echo $OUTPUT->box_end();
131 * Display url frames.
134 * @param object $course
135 * @return does not return
137 function url_display_frame($url, $cm, $course) {
138 global $PAGE, $OUTPUT, $CFG;
140 $frame = optional_param('frameset', 'main', PARAM_ALPHA);
142 if ($frame === 'top') {
143 $PAGE->set_pagelayout('frametop');
144 url_print_header($url, $cm, $course);
145 url_print_heading($url, $cm, $course);
146 url_print_intro($url, $cm, $course);
147 echo $OUTPUT->footer();
151 $config = get_config('url');
152 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
153 $exteurl = url_get_full_url($url, $cm, $course, $config);
154 $navurl = "$CFG->wwwroot/mod/url/view.php?id=$cm->id&frameset=top";
155 $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
156 $courseshortname = format_string($course->shortname, true, array('context' => $coursecontext));
157 $title = strip_tags($courseshortname.': '.format_string($url->name));
158 $framesize = $config->framesize;
159 $modulename = s(get_string('modulename','url'));
160 $dir = get_string('thisdirection', 'langconfig');
163 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
166 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
167 <title>$title</title>
169 <frameset rows="$framesize,*">
170 <frame src="$navurl" title="$modulename"/>
171 <frame src="$exteurl" title="$modulename"/>
176 @header('Content-Type: text/html; charset=utf-8');
183 * Print url info and link.
186 * @param object $course
187 * @return does not return
189 function url_print_workaround($url, $cm, $course) {
192 url_print_header($url, $cm, $course);
193 url_print_heading($url, $cm, $course, true);
194 url_print_intro($url, $cm, $course, true);
196 $fullurl = url_get_full_url($url, $cm, $course);
198 $display = url_get_final_display_type($url);
199 if ($display == RESOURCELIB_DISPLAY_POPUP) {
200 $options = empty($url->displayoptions) ? array() : unserialize($url->displayoptions);
201 $width = empty($options['popupwidth']) ? 620 : $options['popupwidth'];
202 $height = empty($options['popupheight']) ? 450 : $options['popupheight'];
203 $wh = "width=$width,height=$height,toolbar=no,location=no,menubar=no,copyhistory=no,status=no,directories=no,scrollbars=yes,resizable=yes";
204 $extra = "onclick=\"window.open('$fullurl', '', '$wh'); return false;\"";
206 } else if ($display == RESOURCELIB_DISPLAY_NEW) {
207 $extra = "onclick=\"this.target='_blank';\"";
213 echo '<div class="urlworkaround">';
214 print_string('clicktoopen', 'url', "<a href=\"$fullurl\" $extra>$fullurl</a>");
217 echo $OUTPUT->footer();
222 * Display embedded url file.
225 * @param object $course
226 * @param stored_file $file main file
227 * @return does not return
229 function url_display_embed($url, $cm, $course) {
230 global $CFG, $PAGE, $OUTPUT;
232 $mimetype = resourcelib_guess_url_mimetype($url->externalurl);
233 $fullurl = url_get_full_url($url, $cm, $course);
236 $link = html_writer::tag('a', $fullurl, array('href'=>str_replace('&', '&', $fullurl)));
237 $clicktoopen = get_string('clicktoopen', 'url', $link);
239 $extension = resourcelib_get_extension($url->externalurl);
241 if (in_array($mimetype, array('image/gif','image/jpeg','image/png'))) { // It's an image
242 $code = resourcelib_embed_image($fullurl, $title);
244 } else if ($mimetype == 'audio/mp3') {
246 $code = resourcelib_embed_mp3($fullurl, $title, $clicktoopen);
248 } else if ($mimetype == 'video/x-flv' or $extension === 'f4v') {
250 $code = resourcelib_embed_flashvideo($fullurl, $title, $clicktoopen);
252 } else if ($mimetype == 'application/x-shockwave-flash') {
254 $code = resourcelib_embed_flash($fullurl, $title, $clicktoopen);
256 } else if (substr($mimetype, 0, 10) == 'video/x-ms') {
257 // Windows Media Player file
258 $code = resourcelib_embed_mediaplayer($fullurl, $title, $clicktoopen);
260 } else if ($mimetype == 'video/quicktime') {
262 $code = resourcelib_embed_quicktime($fullurl, $title, $clicktoopen);
264 } else if ($mimetype == 'video/mpeg') {
266 $code = resourcelib_embed_mpeg($fullurl, $title, $clicktoopen);
268 } else if ($mimetype == 'audio/x-pn-realaudio-plugin') {
270 $code = resourcelib_embed_real($fullurl, $title, $clicktoopen);
273 // anything else - just try object tag enlarged as much as possible
274 $code = resourcelib_embed_general($fullurl, $title, $clicktoopen, $mimetype);
277 url_print_header($url, $cm, $course);
278 url_print_heading($url, $cm, $course);
282 url_print_intro($url, $cm, $course);
284 echo $OUTPUT->footer();
289 * Decide the best diaply format.
291 * @return int display type constant
293 function url_get_final_display_type($url) {
296 if ($url->display != RESOURCELIB_DISPLAY_AUTO) {
297 return $url->display;
300 // detect links to local moodle pages
301 if (strpos($url->externalurl, $CFG->wwwroot) === 0) {
302 if (strpos($url->externalurl, 'file.php') === false and strpos($url->externalurl, '.php') !== false ) {
303 // most probably our moodle page with navigation
304 return RESOURCELIB_DISPLAY_OPEN;
308 static $download = array('application/zip', 'application/x-tar', 'application/g-zip', // binary formats
309 'application/pdf', 'text/html'); // these are known to cause trouble for external links, sorry
310 static $embed = array('image/gif', 'image/jpeg', 'image/png', 'image/svg+xml', // images
311 'application/x-shockwave-flash', 'video/x-flv', 'video/x-ms-wm', // video formats
312 'video/quicktime', 'video/mpeg', 'video/mp4',
313 'audio/mp3', 'audio/x-realaudio-plugin', 'x-realaudio-plugin', // audio formats,
316 $mimetype = resourcelib_guess_url_mimetype($url->externalurl);
318 if (in_array($mimetype, $download)) {
319 return RESOURCELIB_DISPLAY_DOWNLOAD;
321 if (in_array($mimetype, $embed)) {
322 return RESOURCELIB_DISPLAY_EMBED;
325 // let the browser deal with it somehow
326 return RESOURCELIB_DISPLAY_OPEN;
330 * Get the parameters that may be appended to URL
331 * @param object $config url module config options
332 * @return array array describing opt groups
334 function url_get_variable_options($config) {
338 $options[''] = array('' => get_string('chooseavariable', 'url'));
340 $options[get_string('course')] = array(
342 'coursefullname' => get_string('fullnamecourse'),
343 'courseshortname' => get_string('shortnamecourse'),
344 'courseidnumber' => get_string('idnumbercourse'),
345 'coursesummary' => get_string('summary'),
346 'courseformat' => get_string('format'),
349 $options[get_string('modulename', 'url')] = array(
350 'urlinstance' => 'id',
352 'urlname' => get_string('name'),
353 'urlidnumber' => get_string('idnumbermod'),
356 $options[get_string('miscellaneous')] = array(
357 'sitename' => get_string('fullsitename'),
358 'serverurl' => get_string('serverurl', 'url'),
359 'currenttime' => get_string('time'),
360 'lang' => get_string('language'),
362 if (!empty($config->secretphrase)) {
363 $options[get_string('miscellaneous')]['encryptedcode'] = get_string('encryptedcode');
366 $options[get_string('user')] = array(
368 'userusername' => get_string('username'),
369 'useridnumber' => get_string('idnumber'),
370 'userfirstname' => get_string('firstname'),
371 'userlastname' => get_string('lastname'),
372 'userfullname' => get_string('fullnameuser'),
373 'useremail' => get_string('email'),
374 'usericq' => get_string('icqnumber'),
375 'userphone1' => get_string('phone').' 1',
376 'userphone2' => get_string('phone2').' 2',
377 'userinstitution' => get_string('institution'),
378 'userdepartment' => get_string('department'),
379 'useraddress' => get_string('address'),
380 'usercity' => get_string('city'),
381 'usertimezone' => get_string('timezone'),
382 'userurl' => get_string('webpage'),
385 if ($config->rolesinparams) {
386 $roles = get_all_roles();
387 $roleoptions = array();
388 foreach ($roles as $role) {
389 $roleoptions['course'.$role->shortname] = get_string('yourwordforx', '', $role->name);
391 $options[get_string('roles')] = $roleoptions;
398 * Get the parameter values that may be appended to URL
399 * @param object $url module instance
401 * @param object $course
402 * @param object $config module config options
403 * @return array of parameter values
405 function url_get_variable_values($url, $cm, $course, $config) {
410 $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
413 'courseid' => $course->id,
414 'coursefullname' => format_string($course->fullname),
415 'courseshortname' => format_string($course->shortname, true, array('context' => $coursecontext)),
416 'courseidnumber' => $course->idnumber,
417 'coursesummary' => $course->summary,
418 'courseformat' => $course->format,
419 'lang' => current_language(),
420 'sitename' => format_string($site->fullname),
421 'serverurl' => $CFG->wwwroot,
422 'currenttime' => time(),
423 'urlinstance' => $url->id,
424 'urlcmid' => $cm->id,
425 'urlname' => format_string($url->name),
426 'urlidnumber' => $cm->idnumber,
430 $values['userid'] = $USER->id;
431 $values['userusername'] = $USER->username;
432 $values['useridnumber'] = $USER->idnumber;
433 $values['userfirstname'] = $USER->firstname;
434 $values['userlastname'] = $USER->lastname;
435 $values['userfullname'] = fullname($USER);
436 $values['useremail'] = $USER->email;
437 $values['usericq'] = $USER->icq;
438 $values['userphone1'] = $USER->phone1;
439 $values['userphone2'] = $USER->phone2;
440 $values['userinstitution'] = $USER->institution;
441 $values['userdepartment'] = $USER->department;
442 $values['useraddress'] = $USER->address;
443 $values['usercity'] = $USER->city;
444 $values['usertimezone'] = get_user_timezone_offset();
445 $values['userurl'] = $USER->url;
448 // weak imitation of Single-Sign-On, for backwards compatibility only
449 // NOTE: login hack is not included in 2.0 any more, new contrib auth plugin
450 // needs to be createed if somebody needs the old functionality!
451 if (!empty($config->secretphrase)) {
452 $values['encryptedcode'] = url_get_encrypted_parameter($url, $config);
455 //hmm, this is pretty fragile and slow, why do we need it here??
456 if ($config->rolesinparams) {
457 $roles = get_all_roles();
458 $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
459 $roles = role_fix_names($roles, $coursecontext, ROLENAME_ALIAS);
460 foreach ($roles as $role) {
461 $values['course'.$role->shortname] = $role->localname;
469 * BC internal function
471 * @param object $config
474 function url_get_encrypted_parameter($url, $config) {
477 if (file_exists("$CFG->dirroot/local/externserverfile.php")) {
478 require_once("$CFG->dirroot/local/externserverfile.php");
479 if (function_exists('extern_server_file')) {
480 return extern_server_file($url, $config);
483 return md5(getremoteaddr().$config->secretphrase);
487 * Optimised mimetype detection from general URL
489 * @return string mimetype
491 function url_guess_icon($fullurl) {
493 require_once("$CFG->libdir/filelib.php");
495 if (substr_count($fullurl, '/') < 3 or substr($fullurl, -1) === '/') {
496 // most probably default directory - index.php, index.html, etc.
500 $icon = mimeinfo('icon', $fullurl);
501 $icon = 'f/'.str_replace(array('.gif', '.png'), '', $icon);
503 if ($icon === 'f/html' or $icon === 'f/unknown') {