/** * Returns whether ajax is enabled/allowed or not. * @param array $browsers optional list of alowed browsers, empty means use default list * @return bool */ function ajaxenabled(array $browsers = null) { global $CFG, $USER; if (!empty($browsers)) { $valid = false; foreach ($browsers as $brand => $version) { if (check_browser_version($brand, $version)) { $valid = true; } } if (!$valid) { return false; } } $ie = check_browser_version('MSIE', 6.0); $ff = check_browser_version('Gecko', 20051106); $op = check_browser_version('Opera', 9.0); $sa = check_browser_version('Safari', 412); if (!$ie && !$ff && !$op && !$sa) { /** @see http://en.wikipedia.org/wiki/User_agent */ // Gecko build 20051107 is what is in Firefox 1.5. // We still have issues with AJAX in other browsers. return false; } if (!empty($CFG->enableajax) && (!empty($USER->ajax) || !isloggedin())) { return true; } else { return false; } }
protected function is_legacy_browser() { // IE8 and IE9 are the only supported browsers that do not have spellchecker. if (check_browser_version('MSIE', 5) and !check_browser_version('MSIE', 10)) { return true; } // The rest of browsers supports spellchecking or is horribly outdated and we do not care... return false; }
protected function can_use_drag_and_drop() { global $USER; $ie = check_browser_version('MSIE', 6.0); $ff = check_browser_version('Gecko', 20051106); $op = check_browser_version('Opera', 9.0); $sa = check_browser_version('Safari', 412); $ch = check_browser_version('Chrome', 6); if (!$ie && !$ff && !$op && !$sa && !$ch or !empty($USER->screenreader)) { return false; } return true; }
public function supported_by_browser() { if (check_browser_version('MSIE', 6)) { return true; } if (check_browser_version('Gecko', 20030516)) { return true; } if (check_browser_version('Safari', 412)) { return true; } if (check_browser_version('Chrome', 6)) { return true; } if (check_browser_version('Opera', 9)) { return true; } return false; }
public function supported_by_browser() { if (check_browser_version('MSIE', 5.5)) { return true; } else { if (check_browser_version('Gecko', 20030516)) { return true; } else { if (check_browser_version('Safari', 3)) { return true; } else { if (check_browser_version('Opera', 9)) { return true; } } } } return true; }
/** * Modifies $_SERVER['HTTP_USER_AGENT'] manually to check if check_browser_version * works as expected. */ function test_check_browser_version() { global $CFG; $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['2.0']['Mac OS X']; $this->assertTrue(check_browser_version('Safari', '312')); $this->assertFalse(check_browser_version('Safari', '500')); $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP']; $this->assertTrue(check_browser_version('Opera', '8.0')); $this->assertFalse(check_browser_version('Opera', '10.0')); $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['6.0']['Windows XP SP2']; $this->assertTrue(check_browser_version('MSIE', '5.0')); $this->assertFalse(check_browser_version('MSIE', '7.0')); $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP']; $this->assertTrue(check_browser_version('Firefox', '1.5')); $this->assertFalse(check_browser_version('Firefox', '3.0')); }
/** * Returns general link or file embedding html. * @param string $fullurl * @param string $title * @param string $clicktoopen * @return string html */ function resourcelib_embed_general($fullurl, $title, $clicktoopen, $mimetype) { global $CFG, $PAGE; if ($fullurl instanceof moodle_url) { $fullurl = $fullurl->out(); } $iframe = false; // IE can not embed stuff properly if stored on different server // that is why we use iframe instead, unfortunately this tag does not validate // in xhtml strict mode if ($mimetype === 'text/html' and check_browser_version('MSIE', 5)) { if (preg_match('(^https?://[^/]*)', $fullurl, $matches)) { if (strpos($CFG->wwwroot, $matches[0]) !== 0) { $iframe = true; } } } if ($iframe) { $code = <<<EOT <div class="resourcecontent resourcegeneral"> <iframe id="resourceobject" src="{$fullurl}"> {$clicktoopen} </iframe> </div> EOT; } else { $code = <<<EOT <div class="resourcecontent resourcegeneral"> <object id="resourceobject" data="{$fullurl}" type="{$mimetype}" width="800" height="600"> <param name="src" value="{$fullurl}" /> {$clicktoopen} </object> </div> EOT; } // the size is hardcoded in the boject obove intentionally because it is adjusted by the following function on-the-fly $PAGE->requires->js_init_call('M.util.init_maximised_embed', array('resourceobject'), true); return $code; }
$USER->editing = 1; $bodyclasses[] = 'krystle_persistent_edit'; } if (!empty($PAGE->theme->settings->footnote)) { $footnote = $PAGE->theme->settings->footnote; } else { $footnote = '<!-- There was no custom footnote set -->'; } // Tell IE to use the latest engine (no Compatibility mode), if the user is using IE. $ie = false; if (class_exists('core_useragent')) { if (core_useragent::check_ie_version()) { $ie = true; } } else { if (check_browser_version("MSIE", "0")) { $ie = true; } } if ($ie) { header('X-UA-Compatible: IE=edge'); } //Settings for responsive design taken from Zebra theme $userespond = $PAGE->theme->settings->userespond; //Check the theme settings to see if respond.js should be called $usecf = $PAGE->theme->settings->usecf; //Check the theme settings to see if Chrome Frame should be called $cfmaxversion = $PAGE->theme->settings->cfmaxversion; //Check the theme settings to see which versions of IE get prompted for Chrome Frame $ieversion = strpos($PAGE->bodyclasses, $cfmaxversion); $usingie = strpos($PAGE->bodyclasses, 'ie ie');
/** * Handles the sending of file data to the user's browser, including support for * byteranges etc. * * @global object * @global object * @global object * @param object $stored_file local file object * @param int $lifetime Number of seconds before the file should expire from caches (default 24 hours) * @param int $filter 0 (default)=no filtering, 1=all files, 2=html files only * @param bool $forcedownload If true (default false), forces download of file rather than view in browser/plugin * @param string $filename Override filename * @param bool $dontdie - return control to caller afterwards. this is not recommended and only used for cleanup tasks. * if this is passed as true, ignore_user_abort is called. if you don't want your processing to continue on cancel, * you must detect this case when control is returned using connection_aborted. Please not that session is closed * and should not be reopened. * @return void no return or void, script execution stopped unless $dontdie is true */ function send_stored_file($stored_file, $lifetime = 86400, $filter = 0, $forcedownload = false, $filename = null, $dontdie = false) { global $CFG, $COURSE, $SESSION; if (!$stored_file or $stored_file->is_directory()) { // nothing to serve if ($dontdie) { return; } die; } if ($dontdie) { ignore_user_abort(true); } session_get_instance()->write_close(); // unlock session during fileserving // Use given MIME type if specified, otherwise guess it using mimeinfo. // IE, Konqueror and Opera open html file directly in browser from web even when directed to save it to disk :-O // only Firefox saves all files locally before opening when content-disposition: attachment stated $filename = is_null($filename) ? $stored_file->get_filename() : $filename; $isFF = check_browser_version('Firefox', '1.5'); // only FF > 1.5 properly tested $mimetype = ($forcedownload and !$isFF) ? 'application/x-forcedownload' : ($stored_file->get_mimetype() ? $stored_file->get_mimetype() : mimeinfo('type', $filename)); $lastmodified = $stored_file->get_timemodified(); $filesize = $stored_file->get_filesize(); //try to disable automatic sid rewrite in cookieless mode @ini_set("session.use_trans_sid", "false"); if ($lifetime > 0 && !empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { // get unixtime of request header; clip extra junk off first $since = strtotime(preg_replace('/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"])); if ($since && $since >= $lastmodified) { header('HTTP/1.1 304 Not Modified'); header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $lifetime) . ' GMT'); header('Cache-Control: max-age=' . $lifetime); header('Content-Type: ' . $mimetype); if ($dontdie) { return; } die; } } //do not put '@' before the next header to detect incorrect moodle configurations, //error should be better than "weird" empty lines for admins/users //TODO: should we remove all those @ before the header()? Are all of the values supported on all servers? header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastmodified) . ' GMT'); // if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup if (check_browser_version('MSIE')) { $filename = rawurlencode($filename); } if ($forcedownload) { header('Content-Disposition: attachment; filename="' . $filename . '"'); } else { header('Content-Disposition: inline; filename="' . $filename . '"'); } if ($lifetime > 0) { header('Cache-Control: max-age=' . $lifetime); header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $lifetime) . ' GMT'); header('Pragma: '); if (empty($CFG->disablebyteserving) && $mimetype != 'text/plain' && $mimetype != 'text/html') { header('Accept-Ranges: bytes'); if (!empty($_SERVER['HTTP_RANGE']) && strpos($_SERVER['HTTP_RANGE'], 'bytes=') !== FALSE) { // byteserving stuff - for acrobat reader and download accelerators // see: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35 // inspired by: http://www.coneural.org/florian/papers/04_byteserving.php $ranges = false; if (preg_match_all('/(\\d*)-(\\d*)/', $_SERVER['HTTP_RANGE'], $ranges, PREG_SET_ORDER)) { foreach ($ranges as $key => $value) { if ($ranges[$key][1] == '') { //suffix case $ranges[$key][1] = $filesize - $ranges[$key][2]; $ranges[$key][2] = $filesize - 1; } else { if ($ranges[$key][2] == '' || $ranges[$key][2] > $filesize - 1) { //fix range length $ranges[$key][2] = $filesize - 1; } } if ($ranges[$key][2] != '' && $ranges[$key][2] < $ranges[$key][1]) { //invalid byte-range ==> ignore header $ranges = false; break; } //prepare multipart header $ranges[$key][0] = "\r\n--" . BYTESERVING_BOUNDARY . "\r\nContent-Type: {$mimetype}\r\n"; $ranges[$key][0] .= "Content-Range: bytes {$ranges[$key][1]}-{$ranges[$key][2]}/{$filesize}\r\n\r\n"; } } else { $ranges = false; } if ($ranges) { byteserving_send_file($stored_file->get_content_file_handle(), $mimetype, $ranges, $filesize); } } } else { /// Do not byteserve (disabled, strings, text and html files). header('Accept-Ranges: none'); } } else { // Do not cache files in proxies and browsers if (strpos($CFG->wwwroot, 'https://') === 0) { //https sites - watch out for IE! KB812935 and KB316431 header('Cache-Control: max-age=10'); header('Expires: ' . gmdate('D, d M Y H:i:s', 0) . ' GMT'); header('Pragma: '); } else { //normal http - prevent caching at all cost header('Cache-Control: private, must-revalidate, pre-check=0, post-check=0, max-age=0'); header('Expires: ' . gmdate('D, d M Y H:i:s', 0) . ' GMT'); header('Pragma: no-cache'); } header('Accept-Ranges: none'); // Do not allow byteserving when caching disabled } if (empty($filter)) { $filtered = false; if ($mimetype == 'text/html' && !empty($CFG->usesid)) { //cookieless mode - rewrite links header('Content-Type: text/html'); $text = $stored_file->get_content(); $text = sid_ob_rewrite($text); $filesize = strlen($text); $filtered = true; } else { if ($mimetype == 'text/plain') { header('Content-Type: Text/plain; charset=utf-8'); //add encoding } else { header('Content-Type: ' . $mimetype); } } header('Content-Length: ' . $filesize); //flush the buffers - save memory and disable sid rewrite //this also disables zlib compression prepare_file_content_sending(); // send the contents if ($filtered) { echo $text; } else { $stored_file->readfile(); } } else { // Try to put the file through filters if ($mimetype == 'text/html') { $options = new stdClass(); $options->noclean = true; $options->nocache = true; // temporary workaround for MDL-5136 $text = $stored_file->get_content(); $text = file_modify_html_header($text); $output = format_text($text, FORMAT_HTML, $options, $COURSE->id); if (!empty($CFG->usesid)) { //cookieless mode - rewrite links $output = sid_ob_rewrite($output); } header('Content-Length: ' . strlen($output)); header('Content-Type: text/html'); //flush the buffers - save memory and disable sid rewrite //this also disables zlib compression prepare_file_content_sending(); // send the contents echo $output; } else { if ($mimetype == 'text/plain' and $filter == 1) { // only filter text if filter all files is selected $options = new stdClass(); $options->newlines = false; $options->noclean = true; $text = $stored_file->get_content(); $output = '<pre>' . format_text($text, FORMAT_MOODLE, $options, $COURSE->id) . '</pre>'; if (!empty($CFG->usesid)) { //cookieless mode - rewrite links $output = sid_ob_rewrite($output); } header('Content-Length: ' . strlen($output)); header('Content-Type: text/html; charset=utf-8'); //add encoding //flush the buffers - save memory and disable sid rewrite //this also disables zlib compression prepare_file_content_sending(); // send the contents echo $output; } else { // Just send it out raw header('Content-Length: ' . $filesize); header('Content-Type: ' . $mimetype); //flush the buffers - save memory and disable sid rewrite //this also disables zlib compression prepare_file_content_sending(); // send the contents $stored_file->readfile(); } } } if ($dontdie) { return; } die; //no more chars to output!!! }
/** * Determines if the HTML editor is enabled. * * This depends on site and user * settings, as well as the current browser being used. * * @return string|false Returns false if editor is not being used, otherwise * returns 'MSIE' or 'Gecko'. */ function can_use_html_editor() { global $USER, $CFG; if (!empty($USER->htmleditor) and !empty($CFG->htmleditor)) { if (check_browser_version('MSIE', 5.5)) { return 'MSIE'; } else { if (check_browser_version('Gecko', 20030516)) { return 'Gecko'; } } } return false; }
/** * Handles the sending of file data to the user's browser, including support for * byteranges etc. * * The $options parameter supports the following keys: * (string|null) preview - send the preview of the file (e.g. "thumb" for a thumbnail) * (string|null) filename - overrides the implicit filename * (bool) dontdie - return control to caller afterwards. this is not recommended and only used for cleanup tasks. * if this is passed as true, ignore_user_abort is called. if you don't want your processing to continue on cancel, * you must detect this case when control is returned using connection_aborted. Please not that session is closed * and should not be reopened. * * @category files * @param stored_file $stored_file local file object * @param int $lifetime Number of seconds before the file should expire from caches (default 24 hours) * @param int $filter 0 (default)=no filtering, 1=all files, 2=html files only * @param bool $forcedownload If true (default false), forces download of file rather than view in browser/plugin * @param array $options additional options affecting the file serving * @return null script execution stopped unless $options['dontdie'] is true */ function send_stored_file($stored_file, $lifetime = 86400, $filter = 0, $forcedownload = false, array $options = array()) { global $CFG, $COURSE; if (empty($options['filename'])) { $filename = null; } else { $filename = $options['filename']; } if (empty($options['dontdie'])) { $dontdie = false; } else { $dontdie = true; } if (!empty($options['preview'])) { // replace the file with its preview $fs = get_file_storage(); $preview_file = $fs->get_file_preview($stored_file, $options['preview']); if (!$preview_file) { // unable to create a preview of the file, send its default mime icon instead if ($options['preview'] === 'tinyicon') { $size = 24; } else { if ($options['preview'] === 'thumb') { $size = 90; } else { $size = 256; } } $fileicon = file_file_icon($stored_file, $size); send_file($CFG->dirroot . '/pix/' . $fileicon . '.png', basename($fileicon) . '.png'); } else { // preview images have fixed cache lifetime and they ignore forced download // (they are generated by GD and therefore they are considered reasonably safe). $stored_file = $preview_file; $lifetime = DAYSECS; $filter = 0; $forcedownload = false; } } // handle external resource if ($stored_file && $stored_file->is_external_file() && !isset($options['sendcachedexternalfile'])) { $stored_file->send_file($lifetime, $filter, $forcedownload, $options); die; } if (!$stored_file or $stored_file->is_directory()) { // nothing to serve if ($dontdie) { return; } die; } if ($dontdie) { ignore_user_abort(true); } session_get_instance()->write_close(); // unlock session during fileserving // Use given MIME type if specified, otherwise guess it using mimeinfo. // IE, Konqueror and Opera open html file directly in browser from web even when directed to save it to disk :-O // only Firefox saves all files locally before opening when content-disposition: attachment stated $filename = is_null($filename) ? $stored_file->get_filename() : $filename; $isFF = check_browser_version('Firefox', '1.5'); // only FF > 1.5 properly tested $mimetype = ($forcedownload and !$isFF) ? 'application/x-forcedownload' : ($stored_file->get_mimetype() ? $stored_file->get_mimetype() : mimeinfo('type', $filename)); // if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup if (check_browser_version('MSIE')) { $filename = rawurlencode($filename); } if ($forcedownload) { header('Content-Disposition: attachment; filename="' . $filename . '"'); } else { header('Content-Disposition: inline; filename="' . $filename . '"'); } if ($lifetime > 0) { header('Cache-Control: max-age=' . $lifetime); header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $lifetime) . ' GMT'); header('Pragma: '); } else { // Do not cache files in proxies and browsers if (strpos($CFG->wwwroot, 'https://') === 0) { //https sites - watch out for IE! KB812935 and KB316431 header('Cache-Control: max-age=10'); header('Expires: ' . gmdate('D, d M Y H:i:s', 0) . ' GMT'); header('Pragma: '); } else { //normal http - prevent caching at all cost header('Cache-Control: private, must-revalidate, pre-check=0, post-check=0, max-age=0'); header('Expires: ' . gmdate('D, d M Y H:i:s', 0) . ' GMT'); header('Pragma: no-cache'); } } if (empty($filter)) { // send the contents readfile_accel($stored_file, $mimetype, !$dontdie); } else { // Try to put the file through filters if ($mimetype == 'text/html') { $options = new stdClass(); $options->noclean = true; $options->nocache = true; // temporary workaround for MDL-5136 $text = $stored_file->get_content(); $text = file_modify_html_header($text); $output = format_text($text, FORMAT_HTML, $options, $COURSE->id); readstring_accel($output, $mimetype, false); } else { if ($mimetype == 'text/plain' and $filter == 1) { // only filter text if filter all files is selected $options = new stdClass(); $options->newlines = false; $options->noclean = true; $text = $stored_file->get_content(); $output = '<pre>' . format_text($text, FORMAT_MOODLE, $options, $COURSE->id) . '</pre>'; readstring_accel($output, $mimetype, false); } else { // Just send it out raw readfile_accel($stored_file, $mimetype, !$dontdie); } } } if ($dontdie) { return; } die; //no more chars to output!!! }
/** * Returns general link or file embedding html. * * @param string $fullurl * @param string $clicktoopen * @param string $mimetype * @return string html */ function equella_embed_general($equella) { global $CFG, $PAGE; if ($CFG->equella_enable_lti) { $launchurl = new moodle_url('/mod/equella/ltilaunch.php', array('cmid' => $equella->cmid, 'action' => 'view')); $url = $launchurl->out(); } else { $url = equella_appendtoken($equella->url); } $link = html_writer::tag('a', $equella->name, array('href' => str_replace('&', '&', $url))); $clicktoopen = get_string('clicktoopen', 'equella', $link); $iframe = false; // IE can not embed stuff properly, that is why we use iframe instead. // Unfortunately this tag does not validate in xhtml strict mode, // but in any case it is undeprecated in HTML 5 - we will use it everywhere soon! $ie5 = false; $vendor = 'MSIE'; $version = 5; if (method_exists('core_useragent', 'check_browser_version')) { $ie5 = core_useragent::check_browser_version($vendor, $version); } else { $ie5 = check_browser_version($vendor, $version); } if ($ie5 || $CFG->equella_enable_lti) { $iframe = true; } if ($iframe) { $code = <<<EOT <div class="resourcecontent resourcegeneral"> <iframe id="resourceobject" src="{$url}"> {$clicktoopen} </iframe> </div> EOT; } else { $param = '<param name="src" value="' . $url . '" />'; $code = <<<EOT <div class="resourcecontent resourcegeneral"> <object id="resourceobject" data="{$url}" width="800" height="600"> {$param} {$clicktoopen} </object> </div> EOT; } // the size is hardcoded in the object above intentionally because it is adjusted by the following function on-the-fly $PAGE->requires->js_init_call('M.util.init_maximised_embed', array('resourceobject'), true); return $code; }
/** * Returns general link or file embedding html. * @param string $fullurl * @param string $title * @param string $clicktoopen * @param string $mimetype * @return string html */ function resourcelib_embed_general($fullurl, $title, $clicktoopen, $mimetype) { global $CFG, $PAGE; if ($fullurl instanceof moodle_url) { $fullurl = $fullurl->out(); } $iframe = false; $param = '<param name="src" value="' . $fullurl . '" />'; // IE can not embed stuff properly, that is why we use iframe instead. // Unfortunately this tag does not validate in xhtml strict mode, // but in any case it is undeprecated in HTML 5 - we will use it everywhere soon! if ($mimetype === 'text/html' and check_browser_version('MSIE', 5)) { $iframe = true; } if ($iframe) { $code = <<<EOT <div class="resourcecontent resourcegeneral"> <iframe id="resourceobject" src="{$fullurl}"> {$clicktoopen} </iframe> </div> EOT; } else { $code = <<<EOT <div class="resourcecontent resourcegeneral"> <object id="resourceobject" data="{$fullurl}" type="{$mimetype}" width="800" height="600"> {$param} {$clicktoopen} </object> </div> EOT; } // the size is hardcoded in the boject obove intentionally because it is adjusted by the following function on-the-fly $PAGE->requires->js_init_call('M.util.init_maximised_embed', array('resourceobject'), true); return $code; }
/** * Returns whether or not to display fixed students column. * Includes a browser check, because IE6 doesn't support the scrollbar. * * @return bool */ public function is_fixed_students() { global $USER, $CFG; return $CFG->grade_report_fixedstudents && (check_browser_version('MSIE', '7.0') || check_browser_version('Firefox', '2.0') || check_browser_version('Gecko', '2006010100') || check_browser_version('Camino', '1.0') || check_browser_version('Opera', '6.0') || check_browser_version('Chrome', '6') || check_browser_version('Safari', '300')); }
/** * Get the user dashboard report view. * * @uses $CFG, $CURMAN * @param none * @return string The HTML for the dashboard report. */ function get_dashboard() { global $CFG, $CURMAN; require_once CURMAN_DIRLOCATION . '/lib/curriculumstudent.class.php'; //needed for AJAX calls require_js(array('yui_yahoo', 'yui_dom', 'yui_event', 'yui_connection', "{$CFG->wwwroot}/curriculum/js/util.js", "{$CFG->wwwroot}/curriculum/js/dashboard.js"), true); if (optional_param('tab', '', PARAM_CLEAN) == 'archivedlp') { $tab = 'archivedlp'; $show_archived = 1; } else { $tab = 'currentlp'; $show_archived = 0; } $content = ''; $archive_var = '_elis_curriculum_archive'; $totalcourses = 0; $totalcurricula = 0; $completecourses = 0; $curriculas = array(); $classids = array(); $sql = 'SELECT curstu.id, curstu.curriculumid as curid, cur.name as name FROM ' . $CURMAN->db->prefix_table(CURASSTABLE) . ' curstu JOIN ' . $CURMAN->db->prefix_table(CURTABLE) . ' cur ON cur.id = curstu.curriculumid WHERE curstu.userid = \'' . $this->id . '\' ORDER BY cur.priority ASC, cur.name ASC'; if ($usercurs = get_records_sql($sql)) { foreach ($usercurs as $usercur) { // Check if this curricula is set as archived and whether we want to display it $crlm_context = get_context_instance(context_level_base::get_custom_context_level('curriculum', 'block_curr_admin'), $usercur->curid); $data_array = field_data::get_for_context_and_field($crlm_context, $archive_var); $crlm_archived = 0; if (is_array($data_array) && !empty($data_array)) { foreach ($data_array as $data_key => $data_obj) { $crlm_archived = !empty($data_obj->data) ? 1 : 0; } } if ($show_archived == $crlm_archived) { $totalcurricula++; $curriculas[$usercur->curid]['id'] = $usercur->curid; $curriculas[$usercur->curid]['name'] = $usercur->name; $data = array(); if ($courses = curriculumcourse_get_listing($usercur->curid, 'curcrs.position, crs.name', 'ASC')) { foreach ($courses as $course) { $totalcourses++; $course_obj = new course($course->courseid); $coursedesc = $course_obj->syllabus; if ($cdata = student_get_class_from_course($course->courseid, $this->id)) { foreach ($cdata as $classdata) { if (!in_array($classdata->id, $classids)) { $classids[] = $classdata->id; } if ($classdata->completestatusid == STUSTATUS_PASSED) { $completecourses++; } if ($mdlcrs = moodle_get_course($classdata->id)) { $coursename = '<a href="' . $CFG->wwwroot . '/course/view.php?id=' . $mdlcrs . '">' . $course->coursename . '</a>'; } else { $coursename = $course->coursename; } $data[] = array($coursename, $coursedesc, $classdata->grade, $classdata->completestatusid == STUSTATUS_PASSED ? get_string('yes') : get_string('no'), $classdata->completestatusid == STUSTATUS_PASSED && !empty($classdata->completetime) ? date('M j, Y', $classdata->completetime) : get_string('na', 'block_curr_admin')); } } else { $data[] = array($course->coursename, $coursedesc, 0, get_string('no'), get_string('na', 'block_curr_admin')); } } } $curriculas[$usercur->curid]['data'] = $data; } else { // Keep note of the classid's regardless if set archived or not for later use in determining non-curricula courses if ($courses = curriculumcourse_get_listing($usercur->curid, 'curcrs.position, crs.name', 'ASC')) { foreach ($courses as $course) { if ($cdata = student_get_class_from_course($course->courseid, $this->id)) { foreach ($cdata as $classdata) { if (!in_array($classdata->id, $classids)) { $classids[] = $classdata->id; } } } } } } } } // Show different css for IE below version 8 if (check_browser_version('MSIE', 7.0) && !check_browser_version('MSIE', 8.0)) { // IEs that are lower than version 8 do not get the float because it messes up the tabs at the top of the page for some reason $float_style = 'text-align:right;'; } else { // Sane browsers get the float tag $float_style = 'text-align:right; float:right;'; } // Tab header $field_exists = field::get_for_context_level_with_name('curriculum', $archive_var); if (!empty($field_exists)) { $tabrow = array(); $tabrow[] = new tabobject('currentlp', $CFG->wwwroot . '/curriculum/index.php?tab=currentlp', get_string('tab_current_learning_plans', 'block_curr_admin')); $tabrow[] = new tabobject('archivedlp', $CFG->wwwroot . '/curriculum/index.php?tab=archivedlp', get_string('tab_archived_learning_plans', 'block_curr_admin')); $tabrows = array($tabrow); print_tabs($tabrows, $tab); } $content .= print_heading_block(get_string('learningplanwelcome', 'block_curr_admin', fullname($this)), '', true); if ($totalcurricula === 0) { $blank_lang = $tab == 'archivedlp' ? 'noarchivedplan' : 'nolearningplan'; $content .= '<br /><center>' . get_string($blank_lang, 'block_curr_admin') . '</center>'; } // Load the user preferences for hide/show button states if ($collapsed = get_user_preferences('crlm_learningplan_collapsed_curricula')) { $collapsed_array = explode(',', $collapsed); } else { $collapsed = ''; $collapsed_array = array(); } $content .= '<input type="hidden" name="collapsed" id="collapsed" value="' . $collapsed . '">'; if (!empty($usercurs)) { foreach ($usercurs as $usercur) { if (!isset($curriculas[$usercur->curid])) { continue; } $curricula = $curriculas[$usercur->curid]; $table = new stdClass(); $table->head = array(get_string('class', 'block_curr_admin'), get_string('description', 'block_curr_admin'), get_string('score', 'block_curr_admin'), get_string('completed_label', 'block_curr_admin'), get_string('date', 'block_curr_admin')); $table->data = $curricula['data']; $curricula_name = empty($CURMAN->config->disablecoursecatalog) ? '<a href="index.php?s=crscat§ion=curr&showcurid=' . $curricula['id'] . '">' . $curricula['name'] . '</a>' : $curricula['name']; $header_curr_name = get_string('learningplanname', 'block_curr_admin', $curricula_name); if (in_array($curricula['id'], $collapsed_array)) { $button_label = get_string('showcourses', 'block_curr_admin'); $extra_class = ' hide'; } else { $button_label = get_string('hidecourses', 'block_curr_admin'); $extra_class = ''; } $heading = '<div class="clearfix"></div>' . '<div style="' . $float_style . '">' . '<script id="curriculum' . $curricula['id'] . 'script" type="text/javascript">toggleVisibleInitWithState("curriculum' . $curricula['id'] . 'script", "curriculum' . $curricula['id'] . 'button", "' . $button_label . '", "' . get_string('hidecourses', 'block_curr_admin') . '", "' . get_string('showcourses', 'block_curr_admin') . '", "curriculum-' . $curricula['id'] . '");</script></div>' . $header_curr_name; $content .= '<div class="dashboard_curricula_block">'; $content .= print_heading($heading, 'left', 2, 'main', true); $content .= '<div id="curriculum-' . $curricula['id'] . '" class="yui-skin-sam ' . $extra_class . '">'; if (empty($curricula['data'])) { $content .= get_string('nocourseassoc', 'block_curr_admin'); } else { $content .= print_table($table, true); } $content .= '</div>'; $content .= '</div>'; } } /// Completed non-curricula course data if ($tab != 'archivedlp') { if (!empty($classids)) { $sql = "SELECT stu.id, stu.classid, crs.name as coursename, stu.completetime, stu.grade, stu.completestatusid\n FROM " . $CURMAN->db->prefix_table(STUTABLE) . " stu\n INNER JOIN " . $CURMAN->db->prefix_table(CLSTABLE) . " cls ON cls.id = stu.classid\n INNER JOIN " . $CURMAN->db->prefix_table(CRSTABLE) . " crs ON crs.id = cls.courseid\n WHERE userid = {$this->id}\n AND classid " . (count($classids) == 1 ? "!= " . current($classids) : "NOT IN (" . implode(", ", $classids) . ")") . "\n ORDER BY crs.name ASC, stu.completetime ASC"; } else { $sql = "SELECT stu.id, stu.classid, crs.name as coursename, stu.completetime, stu.grade, stu.completestatusid\n FROM " . $CURMAN->db->prefix_table(STUTABLE) . " stu\n INNER JOIN " . $CURMAN->db->prefix_table(CLSTABLE) . " cls ON cls.id = stu.classid\n INNER JOIN " . $CURMAN->db->prefix_table(CRSTABLE) . " crs ON crs.id = cls.courseid\n WHERE userid = {$this->id}\n ORDER BY crs.name ASC, stu.completetime ASC"; } if ($classes = get_records_sql($sql)) { $table = new stdClass(); $table->head = array(get_string('class', 'block_curr_admin'), get_string('score', 'block_curr_admin'), get_string('completed_label', 'block_curr_admin'), get_string('date', 'block_curr_admin')); $table->data = array(); foreach ($classes as $class) { if ($mdlcrs = moodle_get_course($class->classid)) { $coursename = '<a href="' . $CFG->wwwroot . '/course/view.php?id=' . $mdlcrs . '">' . $class->coursename . '</a>'; } else { $coursename = $class->coursename; } $table->data[] = array($coursename, $class->grade, $class->completestatusid == STUSTATUS_PASSED ? get_string('yes') : get_string('no'), $class->completestatusid == STUSTATUS_PASSED && !empty($class->completetime) ? date('M j, Y', $class->completetime) : get_string('na', 'block_curr_admin')); } $header_curr_name = get_string('noncurriculacourses', 'block_curr_admin'); if (in_array('na', $collapsed_array)) { $button_label = get_string('showcourses', 'block_curr_admin'); $extra_class = ' hide'; } else { $button_label = get_string('hidecourses', 'block_curr_admin'); $extra_class = ''; } $heading = '<div class="clearfix"></div>' . '<div style="' . $float_style . '">' . '<script id="noncurriculascript" type="text/javascript">toggleVisibleInitWithState("noncurriculascript", "noncurriculabutton", "' . $button_label . '", "' . get_string('hidecourses', 'block_curr_admin') . '", "' . get_string('showcourses', 'block_curr_admin') . '", "curriculum-na");</script></div>' . $header_curr_name; $content .= '<div class="dashboard_curricula_block">'; $content .= print_heading($heading, 'left', 2, 'main', true); $content .= '<div id="curriculum-na" class="yui-skin-sam ' . $extra_class . '">'; $content .= print_table($table, true); $content .= '</div>'; $content .= '</div>'; } } return $content; }
/** * Sets up the editing lock * * @param object $lock * @param string $ouwiki */ function ouwiki_print_editlock($lock, $ouwiki) { global $DB, $PAGE; // Prepare the warning about lock without JS... $a = new StdClass(); $a->now = userdate(time(), get_string('strftimetime')); $a->minutes = (int) (OUWIKI_LOCK_NOJS / 60); $a->deadline = userdate(time() + $a->minutes * 60, get_string('strftimetime')); $nojswarning = get_string('nojswarning', 'ouwiki', $a); $nojsstart = '<p class="ouw_nojswarning">'; // Put in the AJAX for keeping the lock, if on a supported browser $ie = check_browser_version('MSIE', 6.0); $ff = check_browser_version('Gecko', 20051106); $op = check_browser_version('Opera', 9.0); $sa = check_browser_version('Safari', 412); $ch = check_browser_version('Chrome', 14); $js = $ie || $ff || $op || $sa || $ch; if ($js) { $nojsdisabled = get_string('nojsdisabled', 'ouwiki'); $nojs = $nojsstart . $nojsdisabled . ' ' . $nojswarning . '<img src="nojslock.php?lockid=' . $lock->id . '" alt=""/></p>'; $PAGE->requires->yui2_lib(array('yahoo', 'event', 'connection')); $strlockcancelled = ouwiki_javascript_escape(get_string('lockcancelled', 'ouwiki')); $intervalms = OUWIKI_LOCK_RECONFIRM * 1000; $timeoutscript = ''; if ($ouwiki->timeout) { $countdownurgent = ouwiki_javascript_escape(get_string('countdownurgent', 'ouwiki')); $timeoutscript = "var ouw_countdownto = (new Date()).getTime()+1000*{$ouwiki->timeout};\n var ouw_countdowninterval=setInterval(function() {\n var countdown=document.getElementById('ouw_countdown');\n var timeleft=ouw_countdownto-(new Date().getTime());\n if (timeleft < 0) {\n clearInterval(ouw_countdowninterval);\n document.forms['mform1'].elements['save'].click();\n return;\n }\n if(timeleft<2*60*1000) {\n var urgent=document.getElementById('ouw_countdownurgent');\n if(!urgent.firstChild) {\n urgent.appendChild(document.createTextNode(\"" . $countdownurgent . "\"));\n countdown.style.fontWeight='bold';\n countdown.style.color='red';\n }\n }\n var minutes=Math.floor(timeleft/(60*1000));\n var seconds=Math.floor(timeleft/1000) - minutes*60;\n var text=minutes+':';\n if(seconds<10) text+='0';\n text+=seconds;\n while(countdown.firstChild) {\n countdown.removeChild(countdown.firstChild);\n }\n countdown.appendChild(document.createTextNode(text));\n },500);\n "; } print "<script type='text/javascript'>\n var intervalID;\n function handleResponse(o) {\n if(o.responseText=='cancel') {\n document.forms['mform1'].elements['id_preview'].disabled=true;\n document.forms['mform1'].elements['id_save'].disabled=true;\n clearInterval(intervalID);\n alert(\"{$strlockcancelled}\");\n }\n }\n function handleFailure(o) {\n // Ignore for now\n }\n intervalID=setInterval(function() {\n YAHOO.util.Connect.asyncRequest('POST','confirmlock.php',\n {success:handleResponse,failure:handleFailure},'lockid={$lock->id}');\n },{$intervalms});\n {$timeoutscript}\n </script>\n <noscript>\n {$nojs}\n </noscript>\n "; } else { // If they have a non-supported browser, update the lock time right now without // going through the dodgy image method, to reserve their 15-minute slot. // (This means it will work for Lynx, for instance.) print $nojsstart . get_string('nojsbrowser', 'ouwiki') . ' ' . $nojswarning . '.</p>'; $lock->seenat = time() + OUWIKI_LOCK_NOJS; $DB->update_record('ouwiki_locks', $lock); } }
/** * Prepares the start of an AJAX output. */ public function header() { // MDL-39810: IE doesn't support JSON MIME type if version < 8 or when it runs in Compatibility View. $supportsjsoncontenttype = !check_browser_version('MSIE') || check_browser_version('MSIE', 8) && !(preg_match("/MSIE 7.0/", $_SERVER['HTTP_USER_AGENT']) && preg_match("/Trident\\/([0-9\\.]+)/", $_SERVER['HTTP_USER_AGENT'])); // unfortunately YUI iframe upload does not support application/json if (!empty($_FILES)) { @header('Content-type: text/plain; charset=utf-8'); if (!$supportsjsoncontenttype) { @header('X-Content-Type-Options: nosniff'); } } else { if (!$supportsjsoncontenttype) { @header('Content-type: text/plain; charset=utf-8'); @header('X-Content-Type-Options: nosniff'); } else { @header('Content-type: application/json; charset=utf-8'); } } // Headers to make it not cacheable and json @header('Cache-Control: no-store, no-cache, must-revalidate'); @header('Cache-Control: post-check=0, pre-check=0', false); @header('Pragma: no-cache'); @header('Expires: Mon, 20 Aug 1969 09:23:00 GMT'); @header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); @header('Accept-Ranges: none'); }
/** * Will get called before the login page is shownr. Ff NTLM SSO * is enabled, and the user is in the right network, we'll redirect * to the magic NTLM page for SSO... * */ function loginpage_hook() { global $CFG, $SESSION; // HTTPS is potentially required //httpsrequired(); - this must be used before setting the URL, it is already done on the login/index.php if (($_SERVER['REQUEST_METHOD'] === 'GET' // Only on initial GET of loginpage || ($_SERVER['REQUEST_METHOD'] === 'POST' && (get_referer() != strip_querystring(qualified_me())))) // Or when POSTed from another place // See MDL-14071 && !empty($this->config->ntlmsso_enabled) // SSO enabled && !empty($this->config->ntlmsso_subnet) // have a subnet to test for && empty($_GET['authldap_skipntlmsso']) // haven't failed it yet && (isguestuser() || !isloggedin()) // guestuser or not-logged-in users && address_in_subnet(getremoteaddr(), $this->config->ntlmsso_subnet)) { // First, let's remember where we were trying to get to before we got here if (empty($SESSION->wantsurl)) { $SESSION->wantsurl = (array_key_exists('HTTP_REFERER', $_SERVER) && $_SERVER['HTTP_REFERER'] != $CFG->wwwroot && $_SERVER['HTTP_REFERER'] != $CFG->wwwroot.'/' && $_SERVER['HTTP_REFERER'] != $CFG->httpswwwroot.'/login/' && $_SERVER['HTTP_REFERER'] != $CFG->httpswwwroot.'/login/index.php') ? $_SERVER['HTTP_REFERER'] : NULL; } // Now start the whole NTLM machinery. if(!empty($this->config->ntlmsso_ie_fastpath)) { // Shortcut for IE browsers: skip the attempt page if(check_browser_version('MSIE')) { $sesskey = sesskey(); redirect($CFG->wwwroot.'/auth/ldap/ntlmsso_magic.php?sesskey='.$sesskey); } else { redirect($CFG->httpswwwroot.'/login/index.php?authldap_skipntlmsso=1'); } } else { redirect($CFG->wwwroot.'/auth/ldap/ntlmsso_attempt.php'); } } // No NTLM SSO, Use the normal login page instead. // If $SESSION->wantsurl is empty and we have a 'Referer:' header, the login // page insists on redirecting us to that page after user validation. If // we clicked on the redirect link at the ntlmsso_finish.php page (instead // of waiting for the redirection to happen) then we have a 'Referer:' header // we don't want to use at all. As we can't get rid of it, just point // $SESSION->wantsurl to $CFG->wwwroot (after all, we came from there). if (empty($SESSION->wantsurl) && (get_referer() == $CFG->httpswwwroot.'/auth/ldap/ntlmsso_finish.php')) { $SESSION->wantsurl = $CFG->wwwroot; } }
/** * Can handle rotated text. Whether it is safe to use the trickery in textrotate.js. * * @return bool True for yes, false for no */ function can_use_rotated_text() { return check_browser_version('MSIE', 9) || check_browser_version('Firefox', 2) || check_browser_version('Chrome', 21) || check_browser_version('Safari', 536.25) || check_browser_version('Opera', 12) || check_browser_version('Safari iOS', 533); }
/** * Returns one or several CSS class names that match the user's browser. These can be put * in the body tag of the page to apply browser-specific rules without relying on CSS hacks * * @return array An array of browser version classes */ function get_browser_version_classes() { $classes = array(); if (check_browser_version("MSIE", "0")) { $classes[] = 'ie'; if (check_browser_version("MSIE", 9)) { $classes[] = 'ie9'; } else { if (check_browser_version("MSIE", 8)) { $classes[] = 'ie8'; } elseif (check_browser_version("MSIE", 7)) { $classes[] = 'ie7'; } elseif (check_browser_version("MSIE", 6)) { $classes[] = 'ie6'; } } } else { if (check_browser_version("Firefox") || check_browser_version("Gecko") || check_browser_version("Camino")) { $classes[] = 'gecko'; if (preg_match('/rv\\:([1-2])\\.([0-9])/', $_SERVER['HTTP_USER_AGENT'], $matches)) { $classes[] = "gecko{$matches[1]}{$matches[2]}"; } } else { if (check_browser_version("WebKit")) { $classes[] = 'safari'; if (check_browser_version("Safari iOS")) { $classes[] = 'ios'; } else { if (check_browser_version("WebKit Android")) { $classes[] = 'android'; } } } else { if (check_browser_version("Opera")) { $classes[] = 'opera'; } } } } return $classes; }
/** * Returns whether or not to display fixed students column. * Includes a browser check, because IE6 doesn't support the scrollbar. * * @return bool */ function is_fixed_students() { global $USER, $CFG; return empty($USER->screenreader) && $CFG->grade_report_fixedstudents && (check_browser_version('MSIE', '7.0') || check_browser_version('Firefox', '2.0') || check_browser_version('Gecko', '2006010100') || check_browser_version('Camino', '1.0') || check_browser_version('Opera', '6.0') || check_browser_version('Safari', '2.0')); }
/** * Return true if we should look for SVG images as well. * * @staticvar bool $svg * @return bool */ public function use_svg_icons() { global $CFG; if ($this->usesvg === null) { if (!isset($CFG->svgicons) || !is_bool($CFG->svgicons)) { // IE 5 - 8 don't support SVG at all. if (empty($_SERVER['HTTP_USER_AGENT'])) { // Can't be sure, just say no. $this->usesvg = false; } else { if (check_browser_version('MSIE', 0) and !check_browser_version('MSIE', 9)) { // IE < 9 doesn't support SVG. Say no. $this->usesvg = false; } else { if (preg_match('#Android +[0-2]\\.#', $_SERVER['HTTP_USER_AGENT'])) { // Android < 3 doesn't support SVG. Say no. $this->usesvg = false; } else { if (check_browser_version('Opera', 0)) { // Opera 12 still does not support SVG well enough. Say no. $this->usesvg = false; } else { // Presumed fine. $this->usesvg = true; } } } } } else { // Force them on/off depending upon the setting. $this->usesvg = $CFG->svgicons; } } return $this->usesvg; }
/** * Get the stylesheet URL of this theme * * @param moodle_page $page Not used... deprecated? * @return array of moodle_url */ public function css_urls(moodle_page $page) { global $CFG; $rev = theme_get_revision(); $urls = array(); if ($rev > -1) { if (check_browser_version('MSIE', 5)) { // We need to split the CSS files for IE $urls[] = new moodle_url($CFG->httpswwwroot . '/theme/styles.php', array('theme' => $this->name, 'rev' => $rev, 'type' => 'plugins')); $urls[] = new moodle_url($CFG->httpswwwroot . '/theme/styles.php', array('theme' => $this->name, 'rev' => $rev, 'type' => 'parents')); $urls[] = new moodle_url($CFG->httpswwwroot . '/theme/styles.php', array('theme' => $this->name, 'rev' => $rev, 'type' => 'theme')); } else { if (!empty($CFG->slasharguments)) { $url = new moodle_url("{$CFG->httpswwwroot}/theme/styles.php"); $url->set_slashargument('/' . $this->name . '/' . $rev . '/all', 'noparam', true); $urls[] = $url; } else { $urls[] = new moodle_url($CFG->httpswwwroot . '/theme/styles.php', array('theme' => $this->name, 'rev' => $rev, 'type' => 'all')); } } } else { // find out the current CSS and cache it now for 5 seconds // the point is to construct the CSS only once and pass it through the // dataroot to the script that actually serves the sheets if (!defined('THEME_DESIGNER_CACHE_LIFETIME')) { define('THEME_DESIGNER_CACHE_LIFETIME', 4); // this can be also set in config.php } $candidatesheet = "{$CFG->cachedir}/theme/{$this->name}/designer.ser"; if (!file_exists($candidatesheet)) { $css = $this->css_content(); check_dir_exists(dirname($candidatesheet)); file_put_contents($candidatesheet, serialize($css)); } else { if (filemtime($candidatesheet) > time() - THEME_DESIGNER_CACHE_LIFETIME) { if ($css = file_get_contents($candidatesheet)) { $css = unserialize($css); } else { unlink($candidatesheet); $css = $this->css_content(); } } else { unlink($candidatesheet); $css = $this->css_content(); file_put_contents($candidatesheet, serialize($css)); } } $baseurl = $CFG->httpswwwroot . '/theme/styles_debug.php'; if (check_browser_version('MSIE', 5)) { // lalala, IE does not allow more than 31 linked CSS files from main document $urls[] = new moodle_url($baseurl, array('theme' => $this->name, 'type' => 'ie', 'subtype' => 'plugins')); foreach ($css['parents'] as $parent => $sheets) { // We need to serve parents individually otherwise we may easily exceed the style limit IE imposes (4096) $urls[] = new moodle_url($baseurl, array('theme' => $this->name, 'type' => 'ie', 'subtype' => 'parents', 'sheet' => $parent)); } $urls[] = new moodle_url($baseurl, array('theme' => $this->name, 'type' => 'ie', 'subtype' => 'theme')); } else { foreach ($css['plugins'] as $plugin => $unused) { $urls[] = new moodle_url($baseurl, array('theme' => $this->name, 'type' => 'plugin', 'subtype' => $plugin)); } foreach ($css['parents'] as $parent => $sheets) { foreach ($sheets as $sheet => $unused2) { $urls[] = new moodle_url($baseurl, array('theme' => $this->name, 'type' => 'parent', 'subtype' => $parent, 'sheet' => $sheet)); } } foreach ($css['theme'] as $sheet => $unused) { $urls[] = new moodle_url($baseurl, array('sheet' => $sheet, 'theme' => $this->name, 'type' => 'theme')); // sheet first in order to make long urls easier to read } } } return $urls; }
/** * Can handle rotated text. Whether it is safe to use the trickery in textrotate.js. * * @return bool True for yes, false for no */ function can_use_rotated_text() { global $USER; return (check_browser_version('MSIE', 9) || check_browser_version('Firefox', 2) || check_browser_version('Chrome', 21) || check_browser_version('Safari', 536.25) || check_browser_version('Opera', 12) || check_browser_version('Safari iOS', 533)) && !$USER->screenreader; }
/** * Print a png image. * * @param string $url ? * @param int $sizex ? * @param int $sizey ? * @param boolean $return ? * @param string $parameters ? * @todo Finish documenting this function */ function print_png($url, $sizex, $sizey, $return, $parameters = 'alt=""') { global $CFG; static $recentIE; if (!isset($recentIE)) { $recentIE = check_browser_version('MSIE', '5.0'); } if ($recentIE) { // work around the HORRIBLE bug IE has with alpha transparencies $output .= '<img src="' . $CFG->pixpath . '/spacer.gif" width="' . $sizex . '" height="' . $sizey . '"' . ' class="png" style="width: ' . $sizex . 'px; height: ' . $sizey . 'px; ' . ' filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' . "'{$url}', sizingMethod='scale') " . ' ' . $parameters . ' />'; } else { $output .= '<img src="' . $url . '" style="width: ' . $sizex . 'px; height: ' . $sizey . 'px; ' . $parameters . ' />'; } if ($return) { return $output; } else { echo $output; } }
public function list_supported_urls(array $urls, array $options = array()) { $extensions = $this->get_supported_extensions(); $result = array(); foreach ($urls as $url) { $ext = core_media::get_extension($url); if (in_array($ext, $extensions)) { if ($ext === 'ogg' || $ext === 'oga') { // Formats .ogg and .oga are not supported in IE or Safari. if (check_browser_version('MSIE') || check_browser_version('Safari')) { continue; } } else { // Formats .aac, .mp3, and .m4a are not supported in Firefox or Opera. if (check_browser_version('Firefox') || check_browser_version('Opera')) { continue; } } // Old Android versions (pre 2.3.3) 'support' audio tag but no codecs. if (check_browser_version('WebKit Android') && !check_browser_version('WebKit Android', '533.1')) { continue; } $result[] = $url; } } return $result; }
} else { echo "<option value='{$session->id}'>{$sesstext}</option>"; } } echo '</select> <input type="submit" value="' . get_string('showsession', 'realtimequiz') . '" /></form></center>'; if ($CFG->version < 2013111800) { $tickimg = '<img src="' . $OUTPUT->pix_url('i/tick_green_big') . '" alt="' . get_string('tick', 'realtimequiz') . '" />'; $crossimg = '<img src="' . $OUTPUT->pix_url('i/cross_red_big') . '" alt="' . get_string('cross', 'realtimequiz') . '" />'; } else { $tickimg = '<img src="' . $OUTPUT->pix_url('i/grade_correct') . '" alt="' . get_string('tick', 'realtimequiz') . '" />'; $crossimg = '<img src="' . $OUTPUT->pix_url('i/grade_incorrect') . '" alt="' . get_string('cross', 'realtimequiz') . '" />'; } if ($questionid == 0) { // Show all of the questions if ($CFG->version < 2013111800) { $isff = check_browser_version('Gecko'); } else { $isff = core_useragent::check_browser_version('Gecko'); } if ($isff) { $blankcolspan = 'colspan="999" '; } else { $blankcolspan = ''; } $questions = $DB->get_records('realtimequiz_question', array('quizid' => $realtimequiz->id), 'questionnum'); $linkurl = new moodle_url('/mod/realtimequiz/responses.php', array('id' => $cm->id, 'showsession' => $showsession)); if ($showusers) { $linkurl->param('showusers', 1); if ($CFG->version < 2013111800) { $usernames = 'u.firstname, u.lastname'; } else {
/** * Handles the sending of file data to the user's browser, including support for * byteranges etc. * @param string $path Path of file on disk (including real filename), or actual content of file as string * @param string $filename Filename to send * @param int $lifetime Number of seconds before the file should expire from caches (default 24 hours) * @param int $filter 0 (default)=no filtering, 1=all files, 2=html files only * @param bool $pathisstring If true (default false), $path is the content to send and not the pathname * @param bool $forcedownload If true (default false), forces download of file rather than view in browser/plugin * @param string $mimetype Include to specify the MIME type; leave blank to have it guess the type from $filename */ function send_file($path, $filename, $lifetime = 'default', $filter = 0, $pathisstring = false, $forcedownload = false, $mimetype = '') { global $CFG, $COURSE, $SESSION; // MDL-11789, apply $CFG->filelifetime here if ($lifetime === 'default') { if (!empty($CFG->filelifetime)) { $lifetime = $CFG->filelifetime; } else { $lifetime = 86400; } } // Use given MIME type if specified, otherwise guess it using mimeinfo. // IE, Konqueror and Opera open html file directly in browser from web even when directed to save it to disk :-O // only Firefox saves all files locally before opening when content-disposition: attachment stated $isFF = check_browser_version('Firefox', '1.5'); // only FF > 1.5 properly tested $mimetype = ($forcedownload and !$isFF) ? 'application/x-forcedownload' : ($mimetype ? $mimetype : mimeinfo('type', $filename)); // If the file is a Flash file and that the user flash player is outdated return a flash upgrader MDL-20841 if (!empty($CFG->excludeoldflashclients) && $mimetype == 'application/x-shockwave-flash' && !empty($SESSION->flashversion)) { $userplayerversion = explode('.', $SESSION->flashversion); $requiredplayerversion = explode('.', $CFG->excludeoldflashclients); if ($userplayerversion[0] < $requiredplayerversion[0] || $userplayerversion[0] == $requiredplayerversion[0] && $userplayerversion[1] < $requiredplayerversion[1] || $userplayerversion[0] == $requiredplayerversion[0] && $userplayerversion[1] == $requiredplayerversion[1] && $userplayerversion[2] < $requiredplayerversion[2]) { $path = $CFG->dirroot . "/lib/flashdetect/flashupgrade.swf"; // Alternate content asking user to upgrade Flash $filename = "flashupgrade.swf"; $lifetime = 0; // Do not cache } } $lastmodified = $pathisstring ? time() : filemtime($path); $filesize = $pathisstring ? strlen($path) : filesize($path); /* - MDL-13949 //Adobe Acrobat Reader XSS prevention if ($mimetype=='application/pdf' or mimeinfo('type', $filename)=='application/pdf') { //please note that it prevents opening of pdfs in browser when http referer disabled //or file linked from another site; browser caching of pdfs is now disabled too if (!empty($_SERVER['HTTP_RANGE'])) { //already byteserving $lifetime = 1; // >0 needed for byteserving } else if (empty($_SERVER['HTTP_REFERER']) or strpos($_SERVER['HTTP_REFERER'], $CFG->wwwroot)!==0) { $mimetype = 'application/x-forcedownload'; $forcedownload = true; $lifetime = 0; } else { $lifetime = 1; // >0 needed for byteserving } } */ //IE compatibiltiy HACK! if (ini_get('zlib.output_compression')) { ini_set('zlib.output_compression', 'Off'); } //try to disable automatic sid rewrite in cookieless mode @ini_set("session.use_trans_sid", "false"); //do not put '@' before the next header to detect incorrect moodle configurations, //error should be better than "weird" empty lines for admins/users //TODO: should we remove all those @ before the header()? Are all of the values supported on all servers? header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastmodified) . ' GMT'); // if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup if (check_browser_version('MSIE')) { $filename = rawurlencode($filename); } if ($forcedownload) { @header('Content-Disposition: attachment; filename="' . $filename . '"'); } else { @header('Content-Disposition: inline; filename="' . $filename . '"'); } if ($lifetime > 0) { @header('Cache-Control: max-age=' . $lifetime); @header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $lifetime) . ' GMT'); @header('Pragma: '); if (empty($CFG->disablebyteserving) && !$pathisstring && $mimetype != 'text/plain' && $mimetype != 'text/html') { @header('Accept-Ranges: bytes'); if (!empty($_SERVER['HTTP_RANGE']) && strpos($_SERVER['HTTP_RANGE'], 'bytes=') !== FALSE) { // byteserving stuff - for acrobat reader and download accelerators // see: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35 // inspired by: http://www.coneural.org/florian/papers/04_byteserving.php $ranges = false; if (preg_match_all('/(\\d*)-(\\d*)/', $_SERVER['HTTP_RANGE'], $ranges, PREG_SET_ORDER)) { foreach ($ranges as $key => $value) { if ($ranges[$key][1] == '') { //suffix case $ranges[$key][1] = $filesize - $ranges[$key][2]; $ranges[$key][2] = $filesize - 1; } else { if ($ranges[$key][2] == '' || $ranges[$key][2] > $filesize - 1) { //fix range length $ranges[$key][2] = $filesize - 1; } } if ($ranges[$key][2] != '' && $ranges[$key][2] < $ranges[$key][1]) { //invalid byte-range ==> ignore header $ranges = false; break; } //prepare multipart header $ranges[$key][0] = "\r\n--" . BYTESERVING_BOUNDARY . "\r\nContent-Type: {$mimetype}\r\n"; $ranges[$key][0] .= "Content-Range: bytes {$ranges[$key][1]}-{$ranges[$key][2]}/{$filesize}\r\n\r\n"; } } else { $ranges = false; } if ($ranges) { byteserving_send_file($path, $mimetype, $ranges); } } } else { /// Do not byteserve (disabled, strings, text and html files). @header('Accept-Ranges: none'); } } else { // Do not cache files in proxies and browsers if (strpos($CFG->wwwroot, 'https://') === 0) { //https sites - watch out for IE! KB812935 and KB316431 @header('Cache-Control: max-age=10'); @header('Expires: ' . gmdate('D, d M Y H:i:s', 0) . ' GMT'); @header('Pragma: '); } else { //normal http - prevent caching at all cost @header('Cache-Control: private, must-revalidate, pre-check=0, post-check=0, max-age=0'); @header('Expires: ' . gmdate('D, d M Y H:i:s', 0) . ' GMT'); @header('Pragma: no-cache'); } @header('Accept-Ranges: none'); // Do not allow byteserving when caching disabled } if (empty($filter)) { if ($mimetype == 'text/html' && !empty($CFG->usesid) && empty($_COOKIE['MoodleSession' . $CFG->sessioncookie])) { //cookieless mode - rewrite links @header('Content-Type: text/html'); $path = $pathisstring ? $path : implode('', file($path)); $path = sid_ob_rewrite($path); $filesize = strlen($path); $pathisstring = true; } else { if ($mimetype == 'text/plain') { @header('Content-Type: Text/plain; charset=utf-8'); //add encoding } else { @header('Content-Type: ' . $mimetype); } } @header('Content-Length: ' . $filesize); while (@ob_end_flush()) { } //flush the buffers - save memory and disable sid rewrite if ($pathisstring) { echo $path; } else { readfile_chunked($path); } } else { // Try to put the file through filters if ($mimetype == 'text/html') { $options = new object(); $options->noclean = true; $options->nocache = true; // temporary workaround for MDL-5136 $text = $pathisstring ? $path : implode('', file($path)); $text = file_modify_html_header($text); $output = format_text($text, FORMAT_HTML, $options, $COURSE->id); if (!empty($CFG->usesid) && empty($_COOKIE['MoodleSession' . $CFG->sessioncookie])) { //cookieless mode - rewrite links $output = sid_ob_rewrite($output); } @header('Content-Length: ' . strlen($output)); @header('Content-Type: text/html'); while (@ob_end_flush()) { } //flush the buffers - save memory and disable sid rewrite echo $output; // only filter text if filter all files is selected } else { if ($mimetype == 'text/plain' and $filter == 1) { $options = new object(); $options->newlines = false; $options->noclean = true; $text = htmlentities($pathisstring ? $path : implode('', file($path))); $output = '<pre>' . format_text($text, FORMAT_MOODLE, $options, $COURSE->id) . '</pre>'; if (!empty($CFG->usesid) && empty($_COOKIE['MoodleSession' . $CFG->sessioncookie])) { //cookieless mode - rewrite links $output = sid_ob_rewrite($output); } @header('Content-Length: ' . strlen($output)); @header('Content-Type: text/html; charset=utf-8'); //add encoding while (@ob_end_flush()) { } //flush the buffers - save memory and disable sid rewrite echo $output; } else { // Just send it out raw @header('Content-Length: ' . $filesize); @header('Content-Type: ' . $mimetype); while (@ob_end_flush()) { } //flush the buffers - save memory and disable sid rewrite if ($pathisstring) { echo $path; } else { readfile_chunked($path); } } } } die; //no more chars to output!!! }
} } if ($gradereports = get_list_of_plugins('grade/report')) { foreach ($gradereports as $gradereport) { if (file_exists($CFG->dirroot . '/grade/report/' . $gradereport . '/lib.php')) { require_once $CFG->dirroot . '/grade/report/' . $gradereport . '/lib.php'; $cron_function = 'grade_report_' . $gradereport . '_cron'; if (function_exists($cron_function)) { mtrace("Processing gradebook report function {$cron_function} ...", ''); $cron_function; } } } } // run any customized cronjobs, if any // looking for functions in lib/local/cron.php if (file_exists($CFG->dirroot . '/local/cron.php')) { mtrace('Processing customized cron script ...', ''); include_once $CFG->dirroot . '/local/cron.php'; mtrace('done.'); } //Unset session variables and destroy it @session_unset(); @session_destroy(); mtrace("Cron script completed correctly"); $difftime = microtime_diff($starttime, microtime()); mtrace("Execution took " . $difftime . " seconds"); /// finish the IE hack if (check_browser_version('MSIE')) { echo "</xmp>"; }
/** * Modifies $_SERVER['HTTP_USER_AGENT'] manually to check if check_browser_version * works as expected. */ function test_check_browser_version() { global $CFG; $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['412']['Mac OS X']; $this->assertTrue(check_browser_version('Safari')); $this->assertTrue(check_browser_version('WebKit')); $this->assertTrue(check_browser_version('Safari', '312')); $this->assertFalse(check_browser_version('Safari', '500')); $this->assertFalse(check_browser_version('Chrome')); $this->assertFalse(check_browser_version('Safari iOS')); $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari iOS']['528']['iPhone']; $this->assertTrue(check_browser_version('Safari iOS')); $this->assertTrue(check_browser_version('WebKit')); $this->assertTrue(check_browser_version('Safari iOS', '527')); $this->assertFalse(check_browser_version('Safari iOS', 590)); $this->assertFalse(check_browser_version('Safari', '312')); $this->assertFalse(check_browser_version('Safari', '500')); $this->assertFalse(check_browser_version('Chrome')); $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['WebKit Android']['530']['Nexus']; $this->assertTrue(check_browser_version('WebKit')); $this->assertTrue(check_browser_version('WebKit Android', '527')); $this->assertFalse(check_browser_version('WebKit Android', 590)); $this->assertFalse(check_browser_version('Safari')); $this->assertFalse(check_browser_version('Chrome')); $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Chrome']['8']['Mac OS X']; $this->assertTrue(check_browser_version('Chrome')); $this->assertTrue(check_browser_version('WebKit')); $this->assertTrue(check_browser_version('Chrome', 8)); $this->assertFalse(check_browser_version('Chrome', 10)); $this->assertFalse(check_browser_version('Safari', '1')); $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP']; $this->assertTrue(check_browser_version('Opera')); $this->assertTrue(check_browser_version('Opera', '8.0')); $this->assertFalse(check_browser_version('Opera', '10.0')); $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['6.0']['Windows XP SP2']; $this->assertTrue(check_browser_version('MSIE')); $this->assertTrue(check_browser_version('MSIE', '5.0')); $this->assertFalse(check_browser_version('MSIE', '7.0')); $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['5.0']['Windows 98']; $this->assertFalse(check_browser_version('MSIE')); $this->assertTrue(check_browser_version('MSIE', 0)); $this->assertTrue(check_browser_version('MSIE', '5.0')); $this->assertFalse(check_browser_version('MSIE', '7.0')); $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['9.0']['Windows 7']; $this->assertTrue(check_browser_version('MSIE')); $this->assertTrue(check_browser_version('MSIE', 0)); $this->assertTrue(check_browser_version('MSIE', '5.0')); $this->assertTrue(check_browser_version('MSIE', '9.0')); $this->assertFalse(check_browser_version('MSIE', '10')); $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP']; $this->assertTrue(check_browser_version('Firefox')); $this->assertTrue(check_browser_version('Firefox', '1.5')); $this->assertFalse(check_browser_version('Firefox', '3.0')); }