diff --git a/auth/ldap/auth.php b/auth/ldap/auth.php index a1a96451475..866a83884a8 100644 --- a/auth/ldap/auth.php +++ b/auth/ldap/auth.php @@ -1646,8 +1646,7 @@ class auth_plugin_ldap extends auth_plugin_base { // Now start the whole NTLM machinery. if($this->config->ntlmsso_ie_fastpath == AUTH_NTLM_FASTPATH_YESATTEMPT || $this->config->ntlmsso_ie_fastpath == AUTH_NTLM_FASTPATH_YESFORM) { - - if(check_browser_version('MSIE')) { + if (core_useragent::check_ie_version()) { $sesskey = sesskey(); redirect($CFG->wwwroot.'/auth/ldap/ntlmsso_magic.php?sesskey='.$sesskey); } else if ($this->config->ntlmsso_ie_fastpath == AUTH_NTLM_FASTPATH_YESFORM) { diff --git a/auth/ldap/ntlmsso_magic.php b/auth/ldap/ntlmsso_magic.php index 0d349c5eef9..2ac49a3022b 100644 --- a/auth/ldap/ntlmsso_magic.php +++ b/auth/ldap/ntlmsso_magic.php @@ -28,7 +28,7 @@ $file = $CFG->dirroot.'/pix/spacer.gif'; if ($authplugin->ntlmsso_magic($sesskey) && file_exists($file)) { if (!empty($authplugin->config->ntlmsso_ie_fastpath)) { - if (check_browser_version('MSIE')) { + if (core_useragent::check_ie_version()) { // $PAGE->https_required() up above takes care of what $CFG->httpswwwroot should be. redirect($CFG->httpswwwroot.'/auth/ldap/ntlmsso_finish.php'); } diff --git a/course/view.php b/course/view.php index cf3748a4c0d..5430b6c1f3e 100644 --- a/course/view.php +++ b/course/view.php @@ -219,8 +219,10 @@ redirect($CFG->wwwroot .'/'); } + $ajaxenabled = ajaxenabled(); + $completion = new completion_info($course); - if ($completion->is_enabled() && ajaxenabled()) { + if ($completion->is_enabled() && $ajaxenabled) { $PAGE->requires->string_for_js('completion-title-manual-y', 'completion'); $PAGE->requires->string_for_js('completion-title-manual-n', 'completion'); $PAGE->requires->string_for_js('completion-alt-manual-y', 'completion'); @@ -241,7 +243,7 @@ $PAGE->set_heading($course->fullname); echo $OUTPUT->header(); - if ($completion->is_enabled() && ajaxenabled()) { + if ($completion->is_enabled() && $ajaxenabled) { // This value tracks whether there has been a dynamic change to the page. // It is used so that if a user does this - (a) set some tickmarks, (b) // go to another page, (c) clicks Back button - the page will diff --git a/grade/report/grader/lib.php b/grade/report/grader/lib.php index 1c6fd33913a..2e18c8cadd8 100644 --- a/grade/report/grader/lib.php +++ b/grade/report/grader/lib.php @@ -1582,15 +1582,15 @@ class grade_report_grader extends grade_report { * @return bool */ public function is_fixed_students() { - global $USER, $CFG; + global $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')); + (core_useragent::check_ie_version('7.0') || + core_useragent::check_firefox_version('2.0') || + core_useragent::check_gecko_version('2006010100') || + core_useragent::check_camino_version('1.0') || + core_useragent::check_opera_version('6.0') || + core_useragent::check_chrome_version('6') || + core_useragent::check_safari_version('300')); } /** diff --git a/group/index.php b/group/index.php index ffd8f742f12..15116190e2c 100644 --- a/group/index.php +++ b/group/index.php @@ -152,7 +152,8 @@ $currenttab = 'groups'; require('tabs.php'); $disabled = 'disabled="disabled"'; -if (ajaxenabled()) { +$ajaxenabled = ajaxenabled(); +if ($ajaxenabled) { // Some buttons are enabled if single group selected $showaddmembersform_disabled = $singlegroup ? '' : $disabled; $showeditgroupsettingsform_disabled = $singlegroup ? '' : $disabled; @@ -178,7 +179,7 @@ echo '<tr>'."\n"; echo "<td>\n"; echo '<p><label for="groups"><span id="groupslabel">'.get_string('groups').':</span><span id="thegrouping"> </span></label></p>'."\n"; -if (ajaxenabled()) { // TODO: move this to JS init! +if ($ajaxenabled) { // TODO: move this to JS init! $onchange = 'M.core_group.membersCombo.refreshMembers();'; } else { $onchange = ''; @@ -275,7 +276,7 @@ echo '</table>'."\n"; echo '</div>'."\n"; echo '</form>'."\n"; -if (ajaxenabled()) { +if ($ajaxenabled) { $PAGE->requires->js_init_call('M.core_group.init_index', array($CFG->wwwroot, $courseid)); $PAGE->requires->js_init_call('M.core_group.groupslist', array($preventgroupremoval)); } diff --git a/lib/ajax/tests/ajaxlib_test.php b/lib/ajax/tests/ajaxlib_test.php deleted file mode 100644 index f8096f0f95e..00000000000 --- a/lib/ajax/tests/ajaxlib_test.php +++ /dev/null @@ -1,130 +0,0 @@ -<?php -// This file is part of Moodle - http://moodle.org/ -// -// Moodle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Moodle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Moodle. If not, see <http://www.gnu.org/licenses/>. - -/** - * Unit tests for (some of) ../ajaxlib.php. - * - * @package core - * @category phpunit - * @copyright 2009 Tim Hunt - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -global $CFG; -require_once($CFG->libdir . '/ajax/ajaxlib.php'); - - -/** - * Unit tests for ../ajaxlib.php functions. - * - * @copyright 2008 Tim Hunt - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class core_ajaxlib_testcase extends advanced_testcase { - - var $user_agents = array( - 'MSIE' => array( - '5.5' => array('Windows 2000' => 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)'), - '6.0' => array('Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)'), - '7.0' => array('Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; YPC 3.0.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)') - ), - 'Firefox' => array( - '1.0.6' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6'), - '1.5' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; nl; rv:1.8) Gecko/20051107 Firefox/1.5'), - '1.5.0.1' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1'), - '2.0' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1', - 'Ubuntu Linux AMD64' => 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1) Gecko/20060601 Firefox/2.0 (Ubuntu-edgy)') - ), - 'Safari' => array( - '312' => array('Mac OS X' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/312.1 (KHTML, like Gecko) Safari/312'), - '2.0' => array('Mac OS X' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412 (KHTML, like Gecko) Safari/412') - ), - 'Opera' => array( - '8.51' => array('Windows XP' => 'Opera/8.51 (Windows NT 5.1; U; en)'), - '9.0' => array('Windows XP' => 'Opera/9.0 (Windows NT 5.1; U; en)', - 'Debian Linux' => 'Opera/9.01 (X11; Linux i686; U; en)') - ) - ); - - /** - * Uses the array of user agents to test ajax_lib::ajaxenabled - */ - function test_ajaxenabled() { - global $CFG; - - $this->resetAfterTest(true); - - $CFG->enableajax = 1; - - // Should be true - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP']; - $this->assertTrue(ajaxenabled()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['1.5']['Windows XP']; - $this->assertTrue(ajaxenabled()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['2.0']['Mac OS X']; - $this->assertTrue(ajaxenabled()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP']; - $this->assertTrue(ajaxenabled()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['6.0']['Windows XP SP2']; - $this->assertTrue(ajaxenabled()); - - // Should be false - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['1.0.6']['Windows XP']; - $this->assertFalse(ajaxenabled()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['312']['Mac OS X']; - $this->assertFalse(ajaxenabled()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['8.51']['Windows XP']; - $this->assertFalse(ajaxenabled()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['5.5']['Windows 2000']; - $this->assertFalse(ajaxenabled()); - - // Test array of tested browsers - $tested_browsers = array('MSIE' => 6.0, 'Gecko' => 20061111); - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP']; - $this->assertTrue(ajaxenabled($tested_browsers)); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['7.0']['Windows XP SP2']; - $this->assertTrue(ajaxenabled($tested_browsers)); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['2.0']['Mac OS X']; - $this->assertFalse(ajaxenabled($tested_browsers)); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP']; - $this->assertFalse(ajaxenabled($tested_browsers)); - - $tested_browsers = array('Safari' => 412, 'Opera' => 9.0); - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP']; - $this->assertFalse(ajaxenabled($tested_browsers)); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['7.0']['Windows XP SP2']; - $this->assertFalse(ajaxenabled($tested_browsers)); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['2.0']['Mac OS X']; - $this->assertTrue(ajaxenabled($tested_browsers)); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP']; - $this->assertTrue(ajaxenabled($tested_browsers)); - } -} diff --git a/lib/classes/useragent.php b/lib/classes/useragent.php new file mode 100644 index 00000000000..95a6958cb31 --- /dev/null +++ b/lib/classes/useragent.php @@ -0,0 +1,760 @@ +<?php +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. + +/** + * Environment class to aid with the detection and establishment of the working environment. + * + * @package core + * @copyright 2013 Sam Hemelryk + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * The user agent class. + * + * It's important to note that we do not like browser sniffing and its use in core code is highly discouraged. + * No new uses of this API will be integrated unless there is absolutely no alternative. + * + * This API supports the few browser checks we do have in core, all of which one day will hopefully be removed. + * The API will remain to support any third party use out there, however at some point like all code it will be deprecated. + * + * Use sparingly and only with good cause! + * + * @package core + * @copyright 2013 Sam Hemelryk + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class core_useragent { + + /** + * The default for devices, think of as a computer. + */ + const DEVICETYPE_DEFAULT = 'default'; + /** + * Legacy devices, or at least legacy browsers. These are older devices/browsers + * that don't support standards. + */ + const DEVICETYPE_LEGACY = 'legacy'; + /** + * Mobile devices like your cell phone or hand held gaming device. + */ + const DEVICETYPE_MOBILE = 'mobile'; + /** + * Tables, larger than hand held, but still easily portable and smaller than a laptop. + */ + const DEVICETYPE_TABLET = 'tablet'; + + /** + * An instance of this class. + * @var core_useragent + */ + protected static $instance = null; + + /** + * The device types we track. + * @var array + */ + public static $devicetypes = array( + self::DEVICETYPE_DEFAULT, + self::DEVICETYPE_LEGACY, + self::DEVICETYPE_MOBILE, + self::DEVICETYPE_TABLET + ); + + /** + * The current requests user agent string if there was one. + * @var string|bool|null Null until initialised, false if none available, or string when available. + */ + protected $useragent = null; + + /** + * The users device type, one of self::DEVICETYPE_*. + * @var string null until initialised + */ + protected $devicetype = null; + + /** + * Custom device types entered into the admin interface. + * @var array + */ + protected $devicetypecustoms = array(); + + /** + * True if the user agent supports ajax. False if not. + * @var bool|null Null until initialised, then true or false. + */ + protected $supportsajax = null; + + /** + * True if the user agent supports the display of svg images. False if not. + * @var bool|null Null until initialised, then true or false. + */ + protected $supportssvg = null; + + /** + * Get an instance of the user agent object. + * + * @param bool $reload If set to true the user agent will be reset and all ascertations remade. + * @param string $forceuseragent The string to force as the user agent, don't use unless absolutely unavoidable. + * @return core_useragent + */ + public static function instance($reload = false, $forceuseragent = null) { + if (!self::$instance || $reload) { + self::$instance = new core_useragent($forceuseragent); + } + return self::$instance; + } + + /** + * Constructs a new user agent object. Publically you must use the instance method above. + * + * @param string|null $forceuseragent Optional a user agent to force. + */ + protected function __construct($forceuseragent = null) { + global $CFG; + if (!empty($CFG->devicedetectregex)) { + $this->devicetypecustoms = json_decode($CFG->devicedetectregex); + } + if ($forceuseragent !== null) { + $this->useragent = $forceuseragent; + } else if (!empty($_SERVER['HTTP_USER_AGENT'])) { + $this->useragent = $_SERVER['HTTP_USER_AGENT']; + } else { + $this->useragent = false; + $this->devicetype = self::DEVICETYPE_DEFAULT; + } + if (empty($CFG->enableajax)) { + $this->supportsajax = false; + } + } + + /** + * Returns the user agent string. + * @return bool|string The user agent string or false if one isn't available. + */ + public static function get_user_agent_string() { + $instance = self::instance(); + return $instance->useragent; + } + + /** + * Returns the device type we believe is being used. + * @return string + */ + public static function get_device_type() { + $instance = self::instance(); + if ($instance->devicetype === null) { + return $instance->guess_device_type(); + } + return $instance->devicetype; + } + + /** + * Guesses the device type the user agent is running on. + * + * @return string + */ + protected function guess_device_type() { + global $CFG; + if (empty($CFG->enabledevicedetection)) { + $this->devicetype = self::DEVICETYPE_DEFAULT; + return $this->devicetype; + } + foreach ($this->devicetypecustoms as $value => $regex) { + if (preg_match($regex, $this->useragent)) { + $this->devicetype = $value; + return $this->devicetype; + } + } + if ($this->is_useragent_mobile()) { + $this->devicetype = 'mobile'; + } else if ($this->is_useragent_tablet()) { + $this->devicetype = 'tablet'; + } else if (substr($this->useragent, 0, 34) === 'Mozilla/4.0 (compatible; MSIE 6.0;') { + // Safe way to check for IE6 and not get false positives for some IE 7/8 users. + $this->devicetype = 'legacy'; + } else { + $this->devicetype = self::DEVICETYPE_DEFAULT; + } + return $this->devicetype; + } + + /** + * Returns true if the user appears to be on a mobile device. + * @return bool + */ + protected function is_useragent_mobile() { + // Mobile detection PHP direct copy from open source detectmobilebrowser.com. + $phonesregex = '/android .+ mobile|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i'; + $modelsregex = '/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-/i'; + return (preg_match($phonesregex, $this->useragent) || preg_match($modelsregex, substr($this->useragent, 0, 4))); + } + + /** + * Returns true if the user appears to be on a tablet. + * @return int + */ + protected function is_useragent_tablet() { + $tabletregex = '/Tablet browser|android|iPad|iProd|GT-P1000|GT-I9000|SHW-M180S|SGH-T849|SCH-I800|Build\/ERE27|sholest/i'; + return (preg_match($tabletregex, $this->useragent)); + } + + /** + * Gets a list of known device types. + * + * @param bool $includecustomtypes If set to true we'll include types that have been added by the admin. + * @return array + */ + public static function get_device_type_list($includecustomtypes = true) { + $types = self::$devicetypes; + if ($includecustomtypes) { + $instance = self::instance(); + $types = array_merge($types, array_keys($instance->devicetypecustoms)); + } + return $types; + } + + /** + * Returns the theme to use for the given device type. + * + * This used to be get_selected_theme_for_device_type. + * @param null|string $devicetype The device type to find out for. Defaults to the device the user is using, + * @return bool + */ + public static function get_device_type_theme($devicetype = null) { + global $CFG; + if ($devicetype === null) { + $devicetype = self::get_device_type(); + } + $themevarname = self::get_device_type_cfg_var_name($devicetype); + if (empty($CFG->$themevarname)) { + return false; + } + return $CFG->$themevarname; + } + + /** + * Returns the CFG var used to find the theme to use for the given device. + * + * Used to be get_device_cfg_var_name. + * + * @param null|string $devicetype The device type to find out for. Defaults to the device the user is using, + * @return string + */ + public static function get_device_type_cfg_var_name($devicetype = null) { + if ($devicetype == self::DEVICETYPE_DEFAULT || empty($devicetype)) { + return 'theme'; + } + return 'theme' . $devicetype; + } + + /** + * Gets the device type the user is currently using. + * @return string + */ + public static function get_user_device_type() { + $device = self::get_device_type(); + $switched = get_user_preferences('switchdevice'.$device, false); + if ($switched != false) { + return $switched; + } + return $device; + } + + /** + * Switches the device type we think the user is using to what ever was given. + * @param string $newdevice + * @return bool + * @throws coding_exception + */ + public static function set_user_device_type($newdevice) { + $devicetype = self::get_device_type(); + if ($newdevice == $devicetype) { + unset_user_preference('switchdevice'.$devicetype); + return true; + } else { + $devicetypes = self::get_device_type_list(); + if (in_array($newdevice, $devicetypes)) { + set_user_preference('switchdevice'.$devicetype, $newdevice); + return true; + } + } + throw new coding_exception('Invalid device type provided to set_user_device_type'); + } + + /** + * Returns true if the user agent matches the given brand and the version is equal to or greater than that specified. + * + * @param string $brand The branch to check for. + * @param scalar $version The version if we need to find out if it is equal to or greater than that specified. + * @return bool + */ + public static function check_browser_version($brand, $version = null) { + switch ($brand) { + + case 'MSIE': + // Internet Explorer. + return self::check_ie_version($version); + + case 'Firefox': + // Mozilla Firefox browsers. + return self::check_firefox_version($version); + + case 'Chrome': + return self::check_chrome_version($version); + + case 'Opera': + // Opera. + return self::check_opera_version($version); + + case 'Safari': + // Desktop version of Apple Safari browser - no mobile or touch devices. + return self::check_safari_version($version); + + case 'Safari iOS': + // Safari on iPhone, iPad and iPod touch. + return self::check_safari_ios_version($version); + + case 'WebKit': + // WebKit based browser - everything derived from it (Safari, Chrome, iOS, Android and other mobiles). + return self::check_webkit_version($version); + + case 'Gecko': + // Gecko based browsers. + return self::check_gecko_version($version); + + case 'WebKit Android': + // WebKit browser on Android. + return self::check_webkit_android_version($version); + + case 'Camino': + // OSX browser using Gecke engine. + return self::check_camino_version($version); + } + // Who knows?! doesn't pass anyway. + return false; + } + + /** + * Checks the user agent is camino based and that the version is equal to or greater than that specified. + * + * Camino browser is at the end of its life, its no longer being developed or supported, just don't worry about it. + * + * @param string|int $version A version to check for, returns true if its equal to or greater than that specified. + * @return bool + */ + protected static function check_camino_version($version = null) { + // OSX browser using Gecko engine. + $useragent = self::get_user_agent_string(); + if ($useragent === false) { + return false; + } + if (strpos($useragent, 'Camino') === false) { + return false; + } + if (empty($version)) { + return true; // No version specified. + } + if (preg_match("/Camino\/([0-9\.]+)/i", $useragent, $match)) { + if (version_compare($match[1], $version) >= 0) { + return true; + } + } + return false; + } + + /** + * Checks the user agent is Firefox based and that the version is equal to or greater than that specified. + * + * @param string|int $version A version to check for, returns true if its equal to or greater than that specified. + * @return bool + */ + public static function check_firefox_version($version = null) { + // Mozilla Firefox browsers. + $useragent = self::get_user_agent_string(); + if ($useragent === false) { + return false; + } + if (strpos($useragent, 'Firefox') === false && strpos($useragent, 'Iceweasel') === false) { + return false; + } + if (empty($version)) { + return true; // No version specified.. + } + if (preg_match("/(Iceweasel|Firefox)\/([0-9\.]+)/i", $useragent, $match)) { + if (version_compare($match[2], $version) >= 0) { + return true; + } + } + return false; + } + + /** + * Checks the user agent is Gecko based and that the version is equal to or greater than that specified. + * + * @param string|int $version A version to check for, returns true if its equal to or greater than that specified. + * @return bool + */ + public static function check_gecko_version($version = null) { + // Gecko based browsers. + // Do not look for dates any more, we expect real Firefox version here. + $useragent = self::get_user_agent_string(); + if ($useragent === false) { + return false; + } + if (empty($version)) { + $version = 1; + } else if ($version > 20000000) { + // This is just a guess, it is not supposed to be 100% accurate! + if (preg_match('/^201/', $version)) { + $version = 3.6; + } else if (preg_match('/^200[7-9]/', $version)) { + $version = 3; + } else if (preg_match('/^2006/', $version)) { + $version = 2; + } else { + $version = 1.5; + } + } + if (preg_match("/(Iceweasel|Firefox)\/([0-9\.]+)/i", $useragent, $match)) { + // Use real Firefox version if specified in user agent string. + if (version_compare($match[2], $version) >= 0) { + return true; + } + } else if (preg_match("/Gecko\/([0-9\.]+)/i", $useragent, $match)) { + // Gecko might contain date or Firefox revision, let's just guess the Firefox version from the date. + $browserver = $match[1]; + if ($browserver > 20000000) { + // This is just a guess, it is not supposed to be 100% accurate! + if (preg_match('/^201/', $browserver)) { + $browserver = 3.6; + } else if (preg_match('/^200[7-9]/', $browserver)) { + $browserver = 3; + } else if (preg_match('/^2006/', $version)) { + $browserver = 2; + } else { + $browserver = 1.5; + } + } + if (version_compare($browserver, $version) >= 0) { + return true; + } + } + return false; + } + + /** + * Checks the user agent is IE and that the version is equal to or greater than that specified. + * + * @param string|int $version A version to check for, returns true if its equal to or greater than that specified. + * @return bool + */ + public static function check_ie_version($version = null) { + // Internet Explorer. + $useragent = self::get_user_agent_string(); + if ($useragent === false) { + return false; + } + if (strpos($useragent, 'Opera') !== false) { + // Reject Opera. + return false; + } + // In case of IE we have to deal with BC of the version parameter. + if (is_null($version)) { + $version = 5.5; // Anything older is not considered a browser at all! + } + // IE uses simple versions, let's cast it to float to simplify the logic here. + $version = round($version, 1); + // See: http://www.useragentstring.com/pages/Internet%20Explorer/. + if (preg_match("/MSIE ([0-9\.]+)/", $useragent, $match)) { + $browser = $match[1]; + } else { + return false; + } + // IE8 and later versions may pretend to be IE7 for intranet sites, use Trident version instead, + // the Trident should always describe the capabilities of IE in any emulation mode. + if ($browser === '7.0' and preg_match("/Trident\/([0-9\.]+)/", $useragent, $match)) { + $browser = $match[1] + 4; // NOTE: Hopefully this will work also for future IE versions. + } + $browser = round($browser, 1); + return ($browser >= $version); + } + + /** + * Checks the user agent is Opera and that the version is equal to or greater than that specified. + * + * @param string|int $version A version to check for, returns true if its equal to or greater than that specified. + * @return bool + */ + public static function check_opera_version($version = null) { + // Opera. + $useragent = self::get_user_agent_string(); + if ($useragent === false) { + return false; + } + if (strpos($useragent, 'Opera') === false) { + return false; + } + if (empty($version)) { + return true; // No version specified. + } + // Recent Opera useragents have Version/ with the actual version, e.g.: + // Opera/9.80 (Windows NT 6.1; WOW64; U; en) Presto/2.10.289 Version/12.01 + // That's Opera 12.01, not 9.8. + if (preg_match("/Version\/([0-9\.]+)/i", $useragent, $match)) { + if (version_compare($match[1], $version) >= 0) { + return true; + } + } else if (preg_match("/Opera\/([0-9\.]+)/i", $useragent, $match)) { + if (version_compare($match[1], $version) >= 0) { + return true; + } + } + return false; + } + + /** + * Checks the user agent is Webkit based and that the version is equal to or greater than that specified. + * + * @param string|int $version A version to check for, returns true if its equal to or greater than that specified. + * @return bool + */ + public static function check_webkit_version($version = null) { + // WebKit based browser - everything derived from it (Safari, Chrome, iOS, Android and other mobiles). + $useragent = self::get_user_agent_string(); + if ($useragent === false) { + return false; + } + if (strpos($useragent, 'AppleWebKit') === false) { + return false; + } + if (empty($version)) { + return true; // No version specified. + } + if (preg_match("/AppleWebKit\/([0-9.]+)/i", $useragent, $match)) { + if (version_compare($match[1], $version) >= 0) { + return true; + } + } + return false; + } + + /** + * Checks the user agent is Safari based and that the version is equal to or greater than that specified. + * + * @param string|int $version A version to check for, returns true if its equal to or greater than that specified. + * @return bool + */ + public static function check_safari_version($version = null) { + // Desktop version of Apple Safari browser - no mobile or touch devices. + $useragent = self::get_user_agent_string(); + if ($useragent === false) { + return false; + } + if (strpos($useragent, 'AppleWebKit') === false) { + return false; + } + // Look for AppleWebKit, excluding strings with OmniWeb, Shiira and SymbianOS and any other mobile devices. + if (strpos($useragent, 'OmniWeb')) { + // Reject OmniWeb. + return false; + } + if (strpos($useragent, 'Shiira')) { + // Reject Shiira. + return false; + } + if (strpos($useragent, 'SymbianOS')) { + // Reject SymbianOS. + return false; + } + if (strpos($useragent, 'Android')) { + // Reject Androids too. + return false; + } + if (strpos($useragent, 'iPhone') or strpos($useragent, 'iPad') or strpos($useragent, 'iPod')) { + // No Apple mobile devices here - editor does not work, course ajax is not touch compatible, etc. + return false; + } + if (strpos($useragent, 'Chrome')) { // Reject chrome browsers - it needs to be tested explicitly. + return false; + } + + if (empty($version)) { + return true; // No version specified. + } + if (preg_match("/AppleWebKit\/([0-9.]+)/i", $useragent, $match)) { + if (version_compare($match[1], $version) >= 0) { + return true; + } + } + return false; + } + + /** + * Checks the user agent is Chrome based and that the version is equal to or greater than that specified. + * + * @param string|int $version A version to check for, returns true if its equal to or greater than that specified. + * @return bool + */ + public static function check_chrome_version($version = null) { + // Chrome. + $useragent = self::get_user_agent_string(); + if ($useragent === false) { + return false; + } + if (strpos($useragent, 'Chrome') === false) { + return false; + } + if (empty($version)) { + return true; // No version specified. + } + if (preg_match("/Chrome\/(.*)[ ]+/i", $useragent, $match)) { + if (version_compare($match[1], $version) >= 0) { + return true; + } + } + return false; + } + + /** + * Checks the user agent is Webkit based and on Android and that the version is equal to or greater than that specified. + * + * @param string|int $version A version to check for, returns true if its equal to or greater than that specified. + * @return bool + */ + public static function check_webkit_android_version($version = null) { + // WebKit browser on Android. + $useragent = self::get_user_agent_string(); + if ($useragent === false) { + return false; + } + if (strpos($useragent, 'Linux; U; Android') === false) { + return false; + } + if (empty($version)) { + return true; // No version specified. + } + if (preg_match("/AppleWebKit\/([0-9]+)/i", $useragent, $match)) { + if (version_compare($match[1], $version) >= 0) { + return true; + } + } + return false; + } + + /** + * Checks the user agent is Safari on iOS and that the version is equal to or greater than that specified. + * + * @param string|int $version A version to check for, returns true if its equal to or greater than that specified. + * @return bool + */ + public static function check_safari_ios_version($version = null) { + // Safari on iPhone, iPad and iPod touch. + $useragent = self::get_user_agent_string(); + if ($useragent === false) { + return false; + } + if (strpos($useragent, 'AppleWebKit') === false or strpos($useragent, 'Safari') === false) { + return false; + } + if (!strpos($useragent, 'iPhone') and !strpos($useragent, 'iPad') and !strpos($useragent, 'iPod')) { + return false; + } + if (empty($version)) { + return true; // No version specified. + } + if (preg_match("/AppleWebKit\/([0-9]+)/i", $useragent, $match)) { + if (version_compare($match[1], $version) >= 0) { + return true; + } + } + return false; + } + + /** + * Check if the user agent matches a given brand. + * + * Known brand: 'Windows','Linux','Macintosh','SGI','SunOS','HP-UX' + * + * @param string $brand + * @return bool + */ + public static function check_browser_operating_system($brand) { + $useragent = self::get_user_agent_string(); + return ($useragent !== false && preg_match("/$brand/i", $useragent)); + } + + /** + * Gets an array of CSS classes to represent the user agent. + * @return array + */ + public static function get_browser_version_classes() { + $classes = array(); + if (self::check_ie_version('0')) { + $classes[] = 'ie'; + for ($i = 12; $i >= 6; $i--) { + if (self::check_ie_version($i)) { + $classes[] = 'ie'.$i; + break; + } + } + } else if (self::check_firefox_version() || self::check_gecko_version() || self::check_camino_version()) { + $classes[] = 'gecko'; + if (preg_match('/rv\:([1-2])\.([0-9])/', self::get_user_agent_string(), $matches)) { + $classes[] = "gecko{$matches[1]}{$matches[2]}"; + } + } else if (self::check_webkit_version()) { + $classes[] = 'safari'; + if (self::check_safari_ios_version()) { + $classes[] = 'ios'; + } else if (self::check_webkit_android_version()) { + $classes[] = 'android'; + } + } else if (self::check_opera_version()) { + $classes[] = 'opera'; + } + return $classes; + } + + /** + * Returns true if the user agent supports the display of SVG images. + * + * @return bool + */ + public static function supports_svg() { + // IE 5 - 8 don't support SVG at all. + $instance = self::instance(); + if ($instance->supportssvg === null) { + if ($instance->useragent === false) { + // Can't be sure, just say no. + $instance->supportssvg = false; + } else if (self::check_ie_version() and !self::check_ie_version('9')) { + // IE < 9 doesn't support SVG. Say no. + $instance->supportssvg = false; + } else if (preg_match('#Android +[0-2]\.#', $instance->useragent)) { + // Android < 3 doesn't support SVG. Say no. + $instance->supportssvg = false; + } else if (self::check_opera_version()) { + // Opera 12 still does not support SVG well enough. Say no. + $instance->supportssvg = false; + } else { + // Presumed fine. + $instance->supportssvg = true; + } + } + return $instance->supportssvg; + } +} \ No newline at end of file diff --git a/lib/deprecatedlib.php b/lib/deprecatedlib.php index 863480a6d1b..c5b65015ab9 100644 --- a/lib/deprecatedlib.php +++ b/lib/deprecatedlib.php @@ -4419,3 +4419,117 @@ function get_plugin_list_with_file($plugintype, $file, $include = false) { DEBUG_DEVELOPER); return core_component::get_plugin_list_with_file($plugintype, $file, $include); } + +/** + * Checks to see if is the browser operating system matches the specified brand. + * + * Known brand: 'Windows','Linux','Macintosh','SGI','SunOS','HP-UX' + * + * @deprecated since 2.6 + * @param string $brand The operating system identifier being tested + * @return bool true if the given brand below to the detected operating system + */ +function check_browser_operating_system($brand) { + debugging('check_browser_operating_system has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER); + return core_useragent::check_browser_operating_system($brand); +} + +/** + * Checks to see if is a browser matches the specified + * brand and is equal or better version. + * + * @deprecated since 2.6 + * @param string $brand The browser identifier being tested + * @param int $version The version of the browser, if not specified any version (except 5.5 for IE for BC reasons) + * @return bool true if the given version is below that of the detected browser + */ +function check_browser_version($brand, $version = null) { + debugging('check_browser_version has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER); + return core_useragent::check_browser_version($brand, $version); +} + +/** + * Returns whether a device/browser combination is mobile, tablet, legacy, default or the result of + * an optional admin specified regular expression. If enabledevicedetection is set to no or not set + * it returns default + * + * @deprecated since 2.6 + * @return string device type + */ +function get_device_type() { + debugging('get_device_type has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER); + return core_useragent::get_device_type(); +} + +/** + * Returns a list of the device types supporting by Moodle + * + * @deprecated since 2.6 + * @param boolean $incusertypes includes types specified using the devicedetectregex admin setting + * @return array $types + */ +function get_device_type_list($incusertypes = true) { + debugging('get_device_type_list has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER); + return core_useragent::get_device_type_list($incusertypes); +} + +/** + * Returns the theme selected for a particular device or false if none selected. + * + * @deprecated since 2.6 + * @param string $devicetype + * @return string|false The name of the theme to use for the device or the false if not set + */ +function get_selected_theme_for_device_type($devicetype = null) { + debugging('get_selected_theme_for_device_type has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER); + return core_useragent::get_device_type_theme($devicetype); +} + +/** + * Returns the name of the device type theme var in $CFG because there is not a convention to allow backwards compatibility. + * + * @deprecated since 2.6 + * @param string $devicetype + * @return string The config variable to use to determine the theme + */ +function get_device_cfg_var_name($devicetype = null) { + debugging('get_device_cfg_var_name has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER); + return core_useragent::get_device_type_cfg_var_name($devicetype); +} + +/** + * Allows the user to switch the device they are seeing the theme for. + * This allows mobile users to switch back to the default theme, or theme for any other device. + * + * @deprecated since 2.6 + * @param string $newdevice The device the user is currently using. + * @return string The device the user has switched to + */ +function set_user_device_type($newdevice) { + debugging('set_user_device_type has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER); + return core_useragent::set_user_device_type($newdevice); +} + +/** + * Returns the device the user is currently using, or if the user has chosen to switch devices + * for the current device type the type they have switched to. + * + * @deprecated since 2.6 + * @return string The device the user is currently using or wishes to use + */ +function get_user_device_type() { + debugging('get_user_device_type has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER); + return core_useragent::get_user_device_type(); +} + +/** + * 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 + * + * @deprecated since 2.6 + * @return array An array of browser version classes + */ +function get_browser_version_classes() { + debugging('get_browser_version_classes has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER); + return core_useragent::get_browser_version_classes(); +} \ No newline at end of file diff --git a/lib/editor/tinymce/lib.php b/lib/editor/tinymce/lib.php index 838f845dcdd..a231f4165db 100644 --- a/lib/editor/tinymce/lib.php +++ b/lib/editor/tinymce/lib.php @@ -34,25 +34,25 @@ class tinymce_texteditor extends texteditor { * @return bool */ public function supported_by_browser() { - if (check_browser_version('MSIE', 6)) { + if (core_useragent::check_ie_version(6)) { return true; } - if (check_browser_version('Gecko', 20030516)) { + if (core_useragent::check_firefox_version(20030516)) { return true; } - if (check_browser_version('Safari', 412)) { + if (core_useragent::check_safari_version(412)) { return true; } - if (check_browser_version('Chrome', 6)) { + if (core_useragent::check_chrome_version(6)) { return true; } - if (check_browser_version('Opera', 9)) { + if (core_useragent::check_opera_version(9)) { return true; } - if (check_browser_version('Safari iOS', 534)) { + if (core_useragent::check_safari_ios_version(534)) { return true; } - if (check_browser_version('WebKit', 534)) { + if (core_useragent::check_webkit_version(534)) { return true; } diff --git a/lib/editor/tinymce/plugins/spellchecker/lib.php b/lib/editor/tinymce/plugins/spellchecker/lib.php index 72d63236c95..a3c8540c1e1 100644 --- a/lib/editor/tinymce/plugins/spellchecker/lib.php +++ b/lib/editor/tinymce/plugins/spellchecker/lib.php @@ -63,7 +63,7 @@ class tinymce_spellchecker extends editor_tinymce_plugin { 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)) { + if (core_useragent::check_ie_version() and !core_useragent::check_ie_version(10)) { return true; } // The rest of browsers supports spellchecking or is horribly outdated and we do not care... diff --git a/lib/excellib.class.php b/lib/excellib.class.php index 1e1355db0c2..77341cc21c3 100644 --- a/lib/excellib.class.php +++ b/lib/excellib.class.php @@ -120,7 +120,7 @@ class MoodleExcelWorkbook { header('Pragma: no-cache'); } - if (check_browser_version('MSIE')) { + if (core_useragent::check_ie_version()) { $filename = rawurlencode($filename); } else { $filename = s($filename); diff --git a/lib/filelib.php b/lib/filelib.php index 79464ca400f..efe335a060a 100644 --- a/lib/filelib.php +++ b/lib/filelib.php @@ -2101,7 +2101,7 @@ function readstring_accel($string, $mimetype, $accelerate) { function send_temp_file($path, $filename, $pathisstring=false) { global $CFG; - if (check_browser_version('Firefox', '1.5')) { + if (core_useragent::check_firefox_version('1.5')) { // only FF is known to correctly save to disk before opening... $mimetype = mimeinfo('type', $filename); } else { @@ -2121,7 +2121,7 @@ function send_temp_file($path, $filename, $pathisstring=false) { } // if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup - if (check_browser_version('MSIE')) { + if (core_useragent::check_ie_version()) { $filename = urlencode($filename); } @@ -2197,12 +2197,12 @@ function send_file($path, $filename, $lifetime = 'default' , $filter=0, $pathiss // 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 + $isFF = core_useragent::check_firefox_version('1.5'); // only FF > 1.5 properly tested $mimetype = ($forcedownload and !$isFF) ? 'application/x-forcedownload' : ($mimetype ? $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')) { + if (core_useragent::check_ie_version()) { $filename = rawurlencode($filename); } @@ -2361,12 +2361,12 @@ function send_stored_file($stored_file, $lifetime=86400 , $filter=0, $forcedownl // 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 + $isFF = core_useragent::check_firefox_version('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')) { + if (core_useragent::check_ie_version()) { $filename = rawurlencode($filename); } diff --git a/lib/medialib.php b/lib/medialib.php index 2dff8f29763..2de7fc633ec 100644 --- a/lib/medialib.php +++ b/lib/medialib.php @@ -983,8 +983,8 @@ class core_media_player_html5video extends core_media_player { public function embed($urls, $name, $width, $height, $options) { // Special handling to make videos play on Android devices pre 2.3. // Note: I tested and 2.3.3 (in emulator) works without, is 533.1 webkit. - $oldandroid = check_browser_version('WebKit Android') && - !check_browser_version('WebKit Android', '533.1'); + $oldandroid = core_useragent::check_webkit_android_version() && + !core_useragent::check_webkit_android_version('533.1'); // Build array of source tags. $sources = array(); @@ -1067,12 +1067,12 @@ OET; // versions or manual plugins. if ($ext === 'ogv' || $ext === 'webm') { // Formats .ogv and .webm are not supported in IE or Safari. - if (check_browser_version('MSIE') || check_browser_version('Safari')) { + if (core_useragent::check_ie_version() || core_useragent::check_safari_version()) { continue; } } else { // Formats .m4v and .mp4 are not supported in Firefox or Opera. - if (check_browser_version('Firefox') || check_browser_version('Opera')) { + if (core_useragent::check_firefox_version() || core_useragent::check_opera_version()) { continue; } } @@ -1136,18 +1136,18 @@ OET; 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')) { + if (core_useragent::check_ie_version() || core_useragent::check_safari_version()) { continue; } } else { // Formats .aac, .mp3, and .m4a are not supported in Firefox or Opera. - if (check_browser_version('Firefox') || check_browser_version('Opera')) { + if (core_useragent::check_firefox_version() || core_useragent::check_opera_version()) { 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')) { + if (core_useragent::check_webkit_android_version() && + !core_useragent::check_webkit_android_version('533.1')) { continue; } diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 3a42fddbccc..ad04ace16d1 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -7415,448 +7415,6 @@ function check_php_version($version='5.2.4') { return (version_compare(phpversion(), $version) >= 0); } -/** - * Checks to see if is the browser operating system matches the specified brand. - * - * Known brand: 'Windows','Linux','Macintosh','SGI','SunOS','HP-UX' - * - * @uses $_SERVER - * @param string $brand The operating system identifier being tested - * @return bool true if the given brand below to the detected operating system - */ -function check_browser_operating_system($brand) { - if (empty($_SERVER['HTTP_USER_AGENT'])) { - return false; - } - - if (preg_match("/$brand/i", $_SERVER['HTTP_USER_AGENT'])) { - return true; - } - - return false; -} - -/** - * Checks to see if is a browser matches the specified - * brand and is equal or better version. - * - * @uses $_SERVER - * @param string $brand The browser identifier being tested - * @param int $version The version of the browser, if not specified any version (except 5.5 for IE for BC reasons) - * @return bool true if the given version is below that of the detected browser - */ -function check_browser_version($brand, $version = null) { - if (empty($_SERVER['HTTP_USER_AGENT'])) { - return false; - } - - $agent = $_SERVER['HTTP_USER_AGENT']; - - switch ($brand) { - - case 'Camino': - // OSX browser using Gecke engine. - if (strpos($agent, 'Camino') === false) { - return false; - } - if (empty($version)) { - return true; // No version specified. - } - if (preg_match("/Camino\/([0-9\.]+)/i", $agent, $match)) { - if (version_compare($match[1], $version) >= 0) { - return true; - } - } - break; - - case 'Firefox': - // Mozilla Firefox browsers. - if (strpos($agent, 'Iceweasel') === false and strpos($agent, 'Firefox') === false) { - return false; - } - if (empty($version)) { - return true; // No version specified.. - } - if (preg_match("/(Iceweasel|Firefox)\/([0-9\.]+)/i", $agent, $match)) { - if (version_compare($match[2], $version) >= 0) { - return true; - } - } - break; - - case 'Gecko': - // Gecko based browsers. - // Do not look for dates any more, we expect real Firefox version here. - if (empty($version)) { - $version = 1; - } else if ($version > 20000000) { - // This is just a guess, it is not supposed to be 100% accurate! - if (preg_match('/^201/', $version)) { - $version = 3.6; - } else if (preg_match('/^200[7-9]/', $version)) { - $version = 3; - } else if (preg_match('/^2006/', $version)) { - $version = 2; - } else { - $version = 1.5; - } - } - if (preg_match("/(Iceweasel|Firefox)\/([0-9\.]+)/i", $agent, $match)) { - // Use real Firefox version if specified in user agent string. - if (version_compare($match[2], $version) >= 0) { - return true; - } - } else if (preg_match("/Gecko\/([0-9\.]+)/i", $agent, $match)) { - // Gecko might contain date or Firefox revision, let's just guess the Firefox version from the date. - $browserver = $match[1]; - if ($browserver > 20000000) { - // This is just a guess, it is not supposed to be 100% accurate! - if (preg_match('/^201/', $browserver)) { - $browserver = 3.6; - } else if (preg_match('/^200[7-9]/', $browserver)) { - $browserver = 3; - } else if (preg_match('/^2006/', $version)) { - $browserver = 2; - } else { - $browserver = 1.5; - } - } - if (version_compare($browserver, $version) >= 0) { - return true; - } - } - break; - - case 'MSIE': - // Internet Explorer. - if (strpos($agent, 'Opera') !== false) { - // Reject Opera. - return false; - } - // In case of IE we have to deal with BC of the version parameter. - if (is_null($version)) { - $version = 5.5; // Anything older is not considered a browser at all! - } - // IE uses simple versions, let's cast it to float to simplify the logic here. - $version = round($version, 1); - // See: http://www.useragentstring.com/pages/Internet%20Explorer/. - if (preg_match("/MSIE ([0-9\.]+)/", $agent, $match)) { - $browser = $match[1]; - } else { - return false; - } - // IE8 and later versions may pretend to be IE7 for intranet sites, use Trident version instead, - // the Trident should always describe the capabilities of IE in any emulation mode. - if ($browser === '7.0' and preg_match("/Trident\/([0-9\.]+)/", $agent, $match)) { - $browser = $match[1] + 4; // NOTE: Hopefully this will work also for future IE versions. - } - $browser = round($browser, 1); - return ($browser >= $version); - break; - - case 'Opera': - // Opera. - if (strpos($agent, 'Opera') === false) { - return false; - } - if (empty($version)) { - return true; // No version specified. - } - // Recent Opera useragents have Version/ with the actual version, e.g.: - // Opera/9.80 (Windows NT 6.1; WOW64; U; en) Presto/2.10.289 Version/12.01 - // That's Opera 12.01, not 9.8. - if (preg_match("/Version\/([0-9\.]+)/i", $agent, $match)) { - if (version_compare($match[1], $version) >= 0) { - return true; - } - } else if (preg_match("/Opera\/([0-9\.]+)/i", $agent, $match)) { - if (version_compare($match[1], $version) >= 0) { - return true; - } - } - break; - - case 'WebKit': - // WebKit based browser - everything derived from it (Safari, Chrome, iOS, Android and other mobiles). - if (strpos($agent, 'AppleWebKit') === false) { - return false; - } - if (empty($version)) { - return true; // No version specified. - } - if (preg_match("/AppleWebKit\/([0-9.]+)/i", $agent, $match)) { - if (version_compare($match[1], $version) >= 0) { - return true; - } - } - break; - - case 'Safari': - // Desktop version of Apple Safari browser - no mobile or touch devices. - if (strpos($agent, 'AppleWebKit') === false) { - return false; - } - // Look for AppleWebKit, excluding strings with OmniWeb, Shiira and SymbianOS and any other mobile devices - if (strpos($agent, 'OmniWeb')) { // Reject OmniWeb. - return false; - } - if (strpos($agent, 'Shiira')) { // Reject Shiira. - return false; - } - if (strpos($agent, 'SymbianOS')) { // Reject SymbianOS. - return false; - } - if (strpos($agent, 'Android')) { // Reject Androids too. - return false; - } - if (strpos($agent, 'iPhone') or strpos($agent, 'iPad') or strpos($agent, 'iPod')) { - // No Apple mobile devices here - editor does not work, course ajax is not touch compatible, etc. - return false; - } - if (strpos($agent, 'Chrome')) { // Reject chrome browsers - it needs to be tested explicitly. - return false; - } - - if (empty($version)) { - return true; // No version specified. - } - if (preg_match("/AppleWebKit\/([0-9.]+)/i", $agent, $match)) { - if (version_compare($match[1], $version) >= 0) { - return true; - } - } - break; - - case 'Chrome': - if (strpos($agent, 'Chrome') === false) { - return false; - } - if (empty($version)) { - return true; // No version specified. - } - if (preg_match("/Chrome\/(.*)[ ]+/i", $agent, $match)) { - if (version_compare($match[1], $version) >= 0) { - return true; - } - } - break; - - case 'Safari iOS': - // Safari on iPhone, iPad and iPod touch. - if (strpos($agent, 'AppleWebKit') === false or strpos($agent, 'Safari') === false) { - return false; - } - if (!strpos($agent, 'iPhone') and !strpos($agent, 'iPad') and !strpos($agent, 'iPod')) { - return false; - } - if (empty($version)) { - return true; // No version specified. - } - if (preg_match("/AppleWebKit\/([0-9]+)/i", $agent, $match)) { - if (version_compare($match[1], $version) >= 0) { - return true; - } - } - break; - - case 'WebKit Android': - // WebKit browser on Android. - if (strpos($agent, 'Linux; U; Android') === false) { - return false; - } - if (empty($version)) { - return true; // No version specified. - } - if (preg_match("/AppleWebKit\/([0-9]+)/i", $agent, $match)) { - if (version_compare($match[1], $version) >= 0) { - return true; - } - } - break; - } - - return false; -} - -/** - * Returns whether a device/browser combination is mobile, tablet, legacy, default or the result of - * an optional admin specified regular expression. If enabledevicedetection is set to no or not set - * it returns default - * - * @return string device type - */ -function get_device_type() { - global $CFG; - - if (empty($CFG->enabledevicedetection) || empty($_SERVER['HTTP_USER_AGENT'])) { - return 'default'; - } - - $useragent = $_SERVER['HTTP_USER_AGENT']; - - if (!empty($CFG->devicedetectregex)) { - $regexes = json_decode($CFG->devicedetectregex); - - foreach ($regexes as $value => $regex) { - if (preg_match($regex, $useragent)) { - return $value; - } - } - } - - // Mobile detection PHP direct copy from open source detectmobilebrowser.com. - $phonesregex = '/android .+ mobile|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i'; - $modelsregex = '/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-/i'; - if (preg_match($phonesregex, $useragent) || preg_match($modelsregex, substr($useragent, 0, 4))) { - return 'mobile'; - } - - $tabletregex = '/Tablet browser|android|iPad|iProd|GT-P1000|GT-I9000|SHW-M180S|SGH-T849|SCH-I800|Build\/ERE27|sholest/i'; - if (preg_match($tabletregex, $useragent)) { - return 'tablet'; - } - - // Safe way to check for IE6 and not get false positives for some IE 7/8 users. - if (substr($_SERVER['HTTP_USER_AGENT'], 0, 34) === 'Mozilla/4.0 (compatible; MSIE 6.0;') { - return 'legacy'; - } - - return 'default'; -} - -/** - * Returns a list of the device types supporting by Moodle - * - * @param boolean $incusertypes includes types specified using the devicedetectregex admin setting - * @return array $types - */ -function get_device_type_list($incusertypes = true) { - global $CFG; - - $types = array('default', 'legacy', 'mobile', 'tablet'); - - if ($incusertypes && !empty($CFG->devicedetectregex)) { - $regexes = json_decode($CFG->devicedetectregex); - - foreach ($regexes as $value => $regex) { - $types[] = $value; - } - } - - return $types; -} - -/** - * Returns the theme selected for a particular device or false if none selected. - * - * @param string $devicetype - * @return string|false The name of the theme to use for the device or the false if not set - */ -function get_selected_theme_for_device_type($devicetype = null) { - global $CFG; - - if (empty($devicetype)) { - $devicetype = get_user_device_type(); - } - - $themevarname = get_device_cfg_var_name($devicetype); - if (empty($CFG->$themevarname)) { - return false; - } - - return $CFG->$themevarname; -} - -/** - * Returns the name of the device type theme var in $CFG because there is not a convention to allow backwards compatibility. - * - * @param string $devicetype - * @return string The config variable to use to determine the theme - */ -function get_device_cfg_var_name($devicetype = null) { - if ($devicetype == 'default' || empty($devicetype)) { - return 'theme'; - } - - return 'theme' . $devicetype; -} - -/** - * Allows the user to switch the device they are seeing the theme for. - * This allows mobile users to switch back to the default theme, or theme for any other device. - * - * @param string $newdevice The device the user is currently using. - * @return string The device the user has switched to - */ -function set_user_device_type($newdevice) { - global $USER; - - $devicetype = get_device_type(); - $devicetypes = get_device_type_list(); - - if ($newdevice == $devicetype) { - unset_user_preference('switchdevice'.$devicetype); - } else if (in_array($newdevice, $devicetypes)) { - set_user_preference('switchdevice'.$devicetype, $newdevice); - } -} - -/** - * Returns the device the user is currently using, or if the user has chosen to switch devices - * for the current device type the type they have switched to. - * - * @return string The device the user is currently using or wishes to use - */ -function get_user_device_type() { - $device = get_device_type(); - $switched = get_user_preferences('switchdevice'.$device, false); - if ($switched != false) { - return $switched; - } - return $device; -} - -/** - * 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'; - for ($i=12; $i>=6; $i--) { - if (check_browser_version("MSIE", $i)) { - $classes[] = 'ie'.$i; - break; - } - } - - } 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; -} - /** * Determine if moodle installation requires update. * diff --git a/lib/outputlib.php b/lib/outputlib.php index be02e35db1e..e1051dd1cc1 100644 --- a/lib/outputlib.php +++ b/lib/outputlib.php @@ -656,7 +656,7 @@ class theme_config { if ($rev > -1) { $url = new moodle_url("$CFG->httpswwwroot/theme/styles.php"); - $separate = (check_browser_version('MSIE', 5) && !check_browser_version('MSIE', 10)); + $separate = (core_useragent::check_ie_version('5') && !core_useragent::check_ie_version('10')); if (!empty($CFG->slasharguments)) { $slashargs = ''; if (!$svg) { @@ -734,7 +734,7 @@ class theme_config { // We do this because all modern browsers support SVG and this param will one day be removed. $baseurl->param('svg', '0'); } - if (check_browser_version('MSIE', 5)) { + if (core_useragent::check_ie_version('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) { @@ -1359,24 +1359,9 @@ class theme_config { 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; - } + $this->usesvg = core_useragent::supports_svg(); } else { // Force them on/off depending upon the setting. $this->usesvg = $CFG->svgicons; diff --git a/lib/outputrenderers.php b/lib/outputrenderers.php index d61279a473b..e13340324b0 100644 --- a/lib/outputrenderers.php +++ b/lib/outputrenderers.php @@ -3037,7 +3037,7 @@ EOD; */ protected function theme_switch_links() { - $actualdevice = get_device_type(); + $actualdevice = core_useragent::get_device_type(); $currentdevice = $this->page->devicetypeinuse; $switched = ($actualdevice != $currentdevice); diff --git a/lib/pagelib.php b/lib/pagelib.php index 7e733ee6a55..9c7db77892a 100644 --- a/lib/pagelib.php +++ b/lib/pagelib.php @@ -659,7 +659,7 @@ class moodle_page { */ protected function magic_get_devicetypeinuse() { if (empty($this->_devicetypeinuse)) { - $this->_devicetypeinuse = get_user_device_type(); + $this->_devicetypeinuse = core_useragent::get_user_device_type(); } return $this->_devicetypeinuse; } @@ -1549,12 +1549,12 @@ class moodle_page { return $mnetpeertheme; } // First try for the device the user is using. - $devicetheme = get_selected_theme_for_device_type($this->devicetypeinuse); + $devicetheme = core_useragent::get_device_type_theme($this->devicetypeinuse); if (!empty($devicetheme)) { return $devicetheme; } // Next try for the default device (as a fallback). - $devicetheme = get_selected_theme_for_device_type('default'); + $devicetheme = core_useragent::get_device_type_theme('default'); if (!empty($devicetheme)) { return $devicetheme; } @@ -1636,7 +1636,7 @@ class moodle_page { $this->add_body_class('path-' . join('-', array_slice($pathbits, 0, $i))); } - $this->add_body_classes(get_browser_version_classes()); + $this->add_body_classes(core_useragent::get_browser_version_classes()); $this->add_body_class('dir-' . get_string('thisdirection', 'langconfig')); $this->add_body_class('lang-' . current_language()); $this->add_body_class('yui-skin-sam'); // Make YUI happy, if it is used. diff --git a/lib/setuplib.php b/lib/setuplib.php index 1b43764f449..9f8653f5696 100644 --- a/lib/setuplib.php +++ b/lib/setuplib.php @@ -1174,7 +1174,7 @@ function disable_output_buffering() { */ function redirect_if_major_upgrade_required() { global $CFG; - $lastmajordbchanges = 2013081400.00; + $lastmajordbchanges = 2013081600.00; if (empty($CFG->version) or (float)$CFG->version < $lastmajordbchanges or during_initial_install() or !empty($CFG->adminsetuppending)) { try { diff --git a/lib/tests/medialib_test.php b/lib/tests/medialib_test.php index 782ca196275..eea80f40183 100644 --- a/lib/tests/medialib_test.php +++ b/lib/tests/medialib_test.php @@ -67,8 +67,8 @@ class core_medialib_testcase extends advanced_testcase { */ private function pretend_to_be_safari() { // Pretend to be using Safari browser (must support mp4 for tests to work). - $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) ' . - 'AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1'; + core_useragent::instance(true, 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) ' . + 'AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1'); } /** @@ -76,7 +76,7 @@ class core_medialib_testcase extends advanced_testcase { */ private function pretend_to_be_firefox() { // Pretend to be using Firefox browser (must support ogg for tests to work). - $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0'; + core_useragent::instance(true, 'Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0'); } /** diff --git a/lib/tests/moodlelib_test.php b/lib/tests/moodlelib_test.php index 60c3ed8d879..1c9fe7e80d9 100644 --- a/lib/tests/moodlelib_test.php +++ b/lib/tests/moodlelib_test.php @@ -30,57 +30,6 @@ class core_moodlelib_testcase extends advanced_testcase { public static $includecoverage = array('lib/moodlelib.php'); - protected $user_agents = array( - 'MSIE' => array( - '5.0' => array('Windows 98' => 'Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)'), - '5.5' => array('Windows 2000' => 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)'), - '6.0' => array('Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)'), - '7.0' => array('Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; YPC 3.0.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)'), - '8.0' => array('Windows Vista' => 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648)'), - '9.0' => array('Windows 7' => 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)'), - '9.0i' => array('Windows 7' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)'), - '10.0' => array('Windows 8' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0; Touch)'), - '10.0i' => array('Windows 8' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; Trident/6.0; Touch; .NET4.0E; .NET4.0C; Tablet PC 2.0)'), - ), - 'Firefox' => array( - '1.0.6' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6'), - '1.5' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; nl; rv:1.8) Gecko/20051107 Firefox/1.5'), - '1.5.0.1' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1'), - '2.0' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1', - 'Ubuntu Linux AMD64' => 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1) Gecko/20060601 Firefox/2.0 (Ubuntu-edgy)'), - '3.0.6' => array('SUSE' => 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.6) Gecko/2009012700 SUSE/3.0.6-1.4 Firefox/3.0.6'), - '3.6' => array('Linux' => 'Mozilla/5.0 (X11; Linux i686; rv:2.0) Gecko/20100101 Firefox/3.6'), - '11.0' => array('Windows' => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko Firefox/11.0'), - '15.0a2' => array('Windows' => 'Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20120716 Firefox/15.0a2'), - '18.0' => array('Mac OS X' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:18.0) Gecko/18.0 Firefox/18.0'), - ), - 'SeaMonkey' => array( - '2.0' => array('Windows' => 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1b3pre) Gecko/20081208 SeaMonkey/2.0'), - '2.1' => array('Linux' => 'Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20110609 Firefox/4.0.1 SeaMonkey/2.1'), - '2.3' => array('FreeBSD' => 'Mozilla/5.0 (X11; FreeBSD amd64; rv:6.0) Gecko/20110818 Firefox/6.0 SeaMonkey/2.3'), - ), - 'Safari' => array( - '312' => array('Mac OS X' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/312.1 (KHTML, like Gecko) Safari/312'), - '412' => array('Mac OS X' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412 (KHTML, like Gecko) Safari/412') - ), - 'Safari iOS' => array( - '528' => array('iPhone' => 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_2 like Mac OS X; cs-cz) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7D11 Safari/528.16'), - '533' => array('iPad' => 'Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5'), - ), - 'WebKit Android' => array( - '525' => array('G1 Phone' => 'Mozilla/5.0 (Linux; U; Android 1.1; en-gb; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2 – G1 Phone'), - '530' => array('Nexus' => 'Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17 –Nexus'), - ), - 'Chrome' => array( - '8' => array('Mac OS X' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.215 Safari/534.10'), - ), - 'Opera' => array( - '8.51' => array('Windows XP' => 'Opera/8.51 (Windows NT 5.1; U; en)'), - '9.0' => array('Windows XP' => 'Opera/9.0 (Windows NT 5.1; U; en)', - 'Debian Linux' => 'Opera/9.01 (X11; Linux i686; U; en)') - ) - ); - /** * Define a local decimal separator. * @@ -205,257 +154,6 @@ class core_moodlelib_testcase extends advanced_testcase { $this->assertFalse(address_in_subnet('123.123.123.123', '')); } - /** - * Modifies $_SERVER['HTTP_USER_AGENT'] manually to check if check_browser_version - * works as expected. - */ - public function test_check_browser_version() { - $_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['MSIE']['9.0i']['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['MSIE']['10.0']['Windows 8']; - $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->assertTrue(check_browser_version('MSIE', '10')); - $this->assertFalse(check_browser_version('MSIE', '11')); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['10.0i']['Windows 8']; - $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->assertTrue(check_browser_version('MSIE', '10')); - $this->assertFalse(check_browser_version('MSIE', '11')); - - $_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')); - $this->assertTrue(check_browser_version('Gecko', '2')); - $this->assertTrue(check_browser_version('Gecko', 20030516)); - $this->assertTrue(check_browser_version('Gecko', 20051106)); - $this->assertTrue(check_browser_version('Gecko', 2006010100)); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['1.0.6']['Windows XP']; - $this->assertTrue(check_browser_version('Firefox')); - $this->assertTrue(check_browser_version('Gecko', '1')); - $this->assertFalse(check_browser_version('Gecko', 20030516)); - $this->assertFalse(check_browser_version('Gecko', 20051106)); - $this->assertFalse(check_browser_version('Gecko', 2006010100)); - $this->assertFalse(check_browser_version('Firefox', '1.5')); - $this->assertFalse(check_browser_version('Firefox', '3.0')); - $this->assertFalse(check_browser_version('Gecko', '2')); - - $_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->assertTrue(check_browser_version('Gecko', '1')); - $this->assertTrue(check_browser_version('Gecko', '2')); - $this->assertTrue(check_browser_version('Gecko', 20030516)); - $this->assertTrue(check_browser_version('Gecko', 20051106)); - $this->assertTrue(check_browser_version('Gecko', 2006010100)); - $this->assertFalse(check_browser_version('Firefox', '3.0')); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['3.6']['Linux']; - $this->assertTrue(check_browser_version('Firefox')); - $this->assertTrue(check_browser_version('Firefox', '1.5')); - $this->assertTrue(check_browser_version('Firefox', '3.0')); - $this->assertTrue(check_browser_version('Gecko', '2')); - $this->assertTrue(check_browser_version('Gecko', '3.6')); - $this->assertTrue(check_browser_version('Gecko', 20030516)); - $this->assertTrue(check_browser_version('Gecko', 20051106)); - $this->assertTrue(check_browser_version('Gecko', 2006010100)); - $this->assertFalse(check_browser_version('Firefox', '4')); - $this->assertFalse(check_browser_version('Firefox', '10')); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['3.6']['Linux']; - $this->assertTrue(check_browser_version('Firefox')); - $this->assertTrue(check_browser_version('Firefox', '1.5')); - $this->assertTrue(check_browser_version('Firefox', '3.0')); - $this->assertTrue(check_browser_version('Gecko', '2')); - $this->assertTrue(check_browser_version('Gecko', '3.6')); - $this->assertTrue(check_browser_version('Gecko', 20030516)); - $this->assertTrue(check_browser_version('Gecko', 20051106)); - $this->assertTrue(check_browser_version('Gecko', 2006010100)); - $this->assertFalse(check_browser_version('Firefox', '4')); - $this->assertFalse(check_browser_version('Firefox', '10')); - $this->assertFalse(check_browser_version('Firefox', '18')); - $this->assertFalse(check_browser_version('Gecko', '4')); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['15.0a2']['Windows']; - $this->assertTrue(check_browser_version('Firefox')); - $this->assertTrue(check_browser_version('Firefox', '1.5')); - $this->assertTrue(check_browser_version('Firefox', '3.0')); - $this->assertTrue(check_browser_version('Gecko', '2')); - $this->assertTrue(check_browser_version('Gecko', '3.6')); - $this->assertTrue(check_browser_version('Gecko', '15.0')); - $this->assertTrue(check_browser_version('Gecko', 20030516)); - $this->assertTrue(check_browser_version('Gecko', 20051106)); - $this->assertTrue(check_browser_version('Gecko', 2006010100)); - $this->assertTrue(check_browser_version('Firefox', '4')); - $this->assertTrue(check_browser_version('Firefox', '10')); - $this->assertTrue(check_browser_version('Firefox', '15')); - $this->assertFalse(check_browser_version('Firefox', '18')); - $this->assertFalse(check_browser_version('Gecko', '18')); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['18.0']['Mac OS X']; - $this->assertTrue(check_browser_version('Firefox')); - $this->assertTrue(check_browser_version('Firefox', '1.5')); - $this->assertTrue(check_browser_version('Firefox', '3.0')); - $this->assertTrue(check_browser_version('Gecko', '2')); - $this->assertTrue(check_browser_version('Gecko', '3.6')); - $this->assertTrue(check_browser_version('Gecko', '15.0')); - $this->assertTrue(check_browser_version('Gecko', '18.0')); - $this->assertTrue(check_browser_version('Gecko', 20030516)); - $this->assertTrue(check_browser_version('Gecko', 20051106)); - $this->assertTrue(check_browser_version('Gecko', 2006010100)); - $this->assertTrue(check_browser_version('Firefox', '4')); - $this->assertTrue(check_browser_version('Firefox', '10')); - $this->assertTrue(check_browser_version('Firefox', '15')); - $this->assertTrue(check_browser_version('Firefox', '18')); - $this->assertFalse(check_browser_version('Firefox', '19')); - $this->assertFalse(check_browser_version('Gecko', '19')); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['SeaMonkey']['2.0']['Windows']; - - $this->assertTrue(check_browser_version('Gecko', '2')); - $this->assertTrue(check_browser_version('Gecko', 20030516)); - $this->assertTrue(check_browser_version('Gecko', 20051106)); - $this->assertTrue(check_browser_version('Gecko', 2006010100)); - $this->assertFalse(check_browser_version('Gecko', '3.6')); - $this->assertFalse(check_browser_version('Gecko', '4.0')); - $this->assertFalse(check_browser_version('Firefox')); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['SeaMonkey']['2.1']['Linux']; - $this->assertTrue(check_browser_version('Gecko', '2')); - $this->assertTrue(check_browser_version('Gecko', '3.6')); - $this->assertTrue(check_browser_version('Gecko', '4.0')); - $this->assertTrue(check_browser_version('Gecko', 20030516)); - $this->assertTrue(check_browser_version('Gecko', 20051106)); - $this->assertTrue(check_browser_version('Gecko', 2006010100)); - $this->assertTrue(check_browser_version('Firefox')); - $this->assertTrue(check_browser_version('Firefox', 4.0)); - $this->assertFalse(check_browser_version('Firefox', 5)); - $this->assertFalse(check_browser_version('Gecko', '18.0')); - - } - - public function test_get_browser_version_classes() { - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['412']['Mac OS X']; - $this->assertEquals(array('safari'), get_browser_version_classes()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Chrome']['8']['Mac OS X']; - $this->assertEquals(array('safari'), get_browser_version_classes()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari iOS']['528']['iPhone']; - $this->assertEquals(array('safari', 'ios'), get_browser_version_classes()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['WebKit Android']['530']['Nexus']; - $this->assertEquals(array('safari', 'android'), get_browser_version_classes()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Chrome']['8']['Mac OS X']; - $this->assertEquals(array('safari'), get_browser_version_classes()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP']; - $this->assertEquals(array('opera'), get_browser_version_classes()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['6.0']['Windows XP SP2']; - $this->assertEquals(array('ie', 'ie6'), get_browser_version_classes()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['7.0']['Windows XP SP2']; - $this->assertEquals(array('ie', 'ie7'), get_browser_version_classes()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['8.0']['Windows Vista']; - $this->assertEquals(array('ie', 'ie8'), get_browser_version_classes()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['9.0']['Windows 7']; - $this->assertEquals(array('ie', 'ie9'), get_browser_version_classes()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['9.0i']['Windows 7']; - $this->assertEquals(array('ie', 'ie9'), get_browser_version_classes()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['10.0']['Windows 8']; - $this->assertEquals(array('ie', 'ie10'), get_browser_version_classes()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['10.0i']['Windows 8']; - $this->assertEquals(array('ie', 'ie10'), get_browser_version_classes()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP']; - $this->assertEquals(array('gecko', 'gecko18'), get_browser_version_classes()); - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['3.0.6']['SUSE']; - $this->assertEquals(array('gecko', 'gecko19'), get_browser_version_classes()); - } - - public function test_get_device_type() { - // IE8 (common pattern ~1.5% of IE7/8 users have embedded IE6 agent). - $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; BT Openworld BB; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; Hotbar 10.2.197.0; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727)'; - $this->assertEquals('default', get_device_type()); - // Genuine IE6. - $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/4.0 (compatible; MSIE 6.0; AOL 9.0; Windows NT 5.1; SV1; FunWebProducts; .NET CLR 1.0.3705; Media Center PC 2.8)'; - $this->assertEquals('legacy', get_device_type()); - } - public function test_fix_utf8() { // Make sure valid data including other types is not changed. $this->assertSame(null, fix_utf8(null)); diff --git a/lib/tests/theme_config_test.php b/lib/tests/theme_config_test.php index 14b22618ace..64be4cc3e12 100644 --- a/lib/tests/theme_config_test.php +++ b/lib/tests/theme_config_test.php @@ -105,7 +105,7 @@ class core_theme_config_testcase extends advanced_testcase { 'Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13' => true ); foreach ($useragents as $agent => $expected) { - $_SERVER['HTTP_USER_AGENT'] = $agent; + core_useragent::instance(true, $agent); // We need to clone the theme as usesvg property is calculated only once. $testtheme = clone $theme; $imagefile = $testtheme->resolve_image_location('i/test', 'moodle', null); diff --git a/lib/tests/useragent_test.php b/lib/tests/useragent_test.php new file mode 100644 index 00000000000..21e0ef7b04a --- /dev/null +++ b/lib/tests/useragent_test.php @@ -0,0 +1,419 @@ +<?php +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see <http://www.gnu.org/licenses/>. + +/** + * Tests the user agent class. + * + * @package core + * @copyright 2013 Sam Hemelryk + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * User agent test suite. + * + * @package core + * @copyright 2013 Sam Hemelryk + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class core_useragent_testcase extends basic_testcase { + + /** + * User agents we'll be using to test. + * @var array + */ + protected $user_agents = array( + 'MSIE' => array( + '5.0' => array( + 'Windows 98' => 'Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)' + ), + '5.5' => array( + 'Windows 2000' => 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)' + ), + '6.0' => array( + 'Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)' + ), + '7.0' => array( + 'Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; YPC 3.0.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)' + ), + '8.0' => array( + 'Windows Vista' => 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648)' + ), + '9.0' => array( + 'Windows 7' => 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)' + ), + '9.0i' => array( + 'Windows 7' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)' + ), + '10.0' => array( + 'Windows 8' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0; Touch)' + ), + '10.0i' => array( + 'Windows 8' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; Trident/6.0; Touch; .NET4.0E; .NET4.0C; Tablet PC 2.0)' + ), + ), + 'Firefox' => array( + '1.0.6' => array( + 'Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6' + ), + '1.5' => array( + 'Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; nl; rv:1.8) Gecko/20051107 Firefox/1.5' + ), + '1.5.0.1' => array( + 'Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1' + ), + '2.0' => array( + 'Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1', + 'Ubuntu Linux AMD64' => 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1) Gecko/20060601 Firefox/2.0 (Ubuntu-edgy)' + ), + '3.0.6' => array( + 'SUSE' => 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.6) Gecko/2009012700 SUSE/3.0.6-1.4 Firefox/3.0.6' + ), + '3.6' => array( + 'Linux' => 'Mozilla/5.0 (X11; Linux i686; rv:2.0) Gecko/20100101 Firefox/3.6' + ), + '11.0' => array( + 'Windows' => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko Firefox/11.0' + ), + '15.0a2' => array( + 'Windows' => 'Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20120716 Firefox/15.0a2' + ), + '18.0' => array( + 'Mac OS X' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:18.0) Gecko/18.0 Firefox/18.0' + ), + ), + 'SeaMonkey' => array( + '2.0' => array( + 'Windows' => 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1b3pre) Gecko/20081208 SeaMonkey/2.0' + ), + '2.1' => array( + 'Linux' => 'Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20110609 Firefox/4.0.1 SeaMonkey/2.1' + ), + '2.3' => array( + 'FreeBSD' => 'Mozilla/5.0 (X11; FreeBSD amd64; rv:6.0) Gecko/20110818 Firefox/6.0 SeaMonkey/2.3' + ), + ), + 'Safari' => array( + '312' => array( + 'Mac OS X' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/312.1 (KHTML, like Gecko) Safari/312' + ), + '412' => array( + 'Mac OS X' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412 (KHTML, like Gecko) Safari/412' + ), + '2.0' => array( + 'Mac OS X' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412 (KHTML, like Gecko) Safari/412' + ) + ), + 'Safari iOS' => array( + '528' => array( + 'iPhone' => 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_2 like Mac OS X; cs-cz) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7D11 Safari/528.16' + ), + '533' => array( + 'iPad' => 'Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5' + ), + ), + 'WebKit Android' => array( + '525' => array( + 'G1 Phone' => 'Mozilla/5.0 (Linux; U; Android 1.1; en-gb; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2 – G1 Phone' + ), + '530' => array( + 'Nexus' => 'Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17 –Nexus' + ), + ), + 'Chrome' => array( + '8' => array( + 'Mac OS X' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.215 Safari/534.10' + ), + ), + 'Opera' => array( + '8.51' => array( + 'Windows XP' => 'Opera/8.51 (Windows NT 5.1; U; en)' + ), + '9.0' => array( + 'Windows XP' => 'Opera/9.0 (Windows NT 5.1; U; en)', + 'Debian Linux' => 'Opera/9.01 (X11; Linux i686; U; en)' + ) + ) + ); + + /** + * Test instance generation. + */ + public function test_instance() { + $this->assertInstanceOf('core_useragent', core_useragent::instance()); + $this->assertInstanceOf('core_useragent', core_useragent::instance(true)); + } + + /** + * Modifies $_SERVER['HTTP_USER_AGENT'] manually to check if check_browser_version + * works as expected. + */ + public function test_check_browser_version() { + core_useragent::instance(true, $this->user_agents['Safari']['412']['Mac OS X']); + $this->assertTrue(core_useragent::check_safari_version()); + $this->assertTrue(core_useragent::check_webkit_version()); + $this->assertTrue(core_useragent::check_safari_version('312')); + $this->assertFalse(core_useragent::check_safari_version('500')); + $this->assertFalse(core_useragent::check_chrome_version()); + $this->assertFalse(core_useragent::check_safari_ios_version()); + + core_useragent::instance(true, $this->user_agents['Safari iOS']['528']['iPhone']); + $this->assertTrue(core_useragent::check_safari_ios_version()); + $this->assertTrue(core_useragent::check_webkit_version()); + $this->assertTrue(core_useragent::check_safari_ios_version('527')); + $this->assertFalse(core_useragent::check_safari_ios_version(590)); + $this->assertFalse(core_useragent::check_safari_version('312')); + $this->assertFalse(core_useragent::check_safari_version('500')); + $this->assertFalse(core_useragent::check_chrome_version()); + + core_useragent::instance(true, $this->user_agents['WebKit Android']['530']['Nexus']); + $this->assertTrue(core_useragent::check_webkit_version()); + $this->assertTrue(core_useragent::check_webkit_android_version('527')); + $this->assertFalse(core_useragent::check_webkit_android_version(590)); + $this->assertFalse(core_useragent::check_safari_version()); + $this->assertFalse(core_useragent::check_chrome_version()); + + core_useragent::instance(true, $this->user_agents['Chrome']['8']['Mac OS X']); + $this->assertTrue(core_useragent::check_chrome_version()); + $this->assertTrue(core_useragent::check_webkit_version()); + $this->assertTrue(core_useragent::check_chrome_version(8)); + $this->assertFalse(core_useragent::check_chrome_version(10)); + $this->assertFalse(core_useragent::check_safari_version('1')); + + core_useragent::instance(true, $this->user_agents['Opera']['9.0']['Windows XP']); + $this->assertTrue(core_useragent::check_opera_version()); + $this->assertTrue(core_useragent::check_opera_version('8.0')); + $this->assertFalse(core_useragent::check_opera_version('10.0')); + + core_useragent::instance(true, $this->user_agents['MSIE']['6.0']['Windows XP SP2']); + $this->assertTrue(core_useragent::check_ie_version()); + $this->assertTrue(core_useragent::check_ie_version('5.0')); + $this->assertFalse(core_useragent::check_ie_version('7.0')); + + core_useragent::instance(true, $this->user_agents['MSIE']['5.0']['Windows 98']); + $this->assertFalse(core_useragent::check_ie_version()); + $this->assertTrue(core_useragent::check_ie_version(0)); + $this->assertTrue(core_useragent::check_ie_version('5.0')); + $this->assertFalse(core_useragent::check_ie_version('7.0')); + + core_useragent::instance(true, $this->user_agents['MSIE']['9.0']['Windows 7']); + $this->assertTrue(core_useragent::check_ie_version()); + $this->assertTrue(core_useragent::check_ie_version(0)); + $this->assertTrue(core_useragent::check_ie_version('5.0')); + $this->assertTrue(core_useragent::check_ie_version('9.0')); + $this->assertFalse(core_useragent::check_ie_version('10')); + + core_useragent::instance(true, $this->user_agents['MSIE']['9.0i']['Windows 7']); + $this->assertTrue(core_useragent::check_ie_version()); + $this->assertTrue(core_useragent::check_ie_version(0)); + $this->assertTrue(core_useragent::check_ie_version('5.0')); + $this->assertTrue(core_useragent::check_ie_version('9.0')); + $this->assertFalse(core_useragent::check_ie_version('10')); + + core_useragent::instance(true, $this->user_agents['MSIE']['10.0']['Windows 8']); + $this->assertTrue(core_useragent::check_ie_version()); + $this->assertTrue(core_useragent::check_ie_version(0)); + $this->assertTrue(core_useragent::check_ie_version('5.0')); + $this->assertTrue(core_useragent::check_ie_version('9.0')); + $this->assertTrue(core_useragent::check_ie_version('10')); + $this->assertFalse(core_useragent::check_ie_version('11')); + + core_useragent::instance(true, $this->user_agents['MSIE']['10.0i']['Windows 8']); + $this->assertTrue(core_useragent::check_ie_version()); + $this->assertTrue(core_useragent::check_ie_version(0)); + $this->assertTrue(core_useragent::check_ie_version('5.0')); + $this->assertTrue(core_useragent::check_ie_version('9.0')); + $this->assertTrue(core_useragent::check_ie_version('10')); + $this->assertFalse(core_useragent::check_ie_version('11')); + + core_useragent::instance(true, $this->user_agents['Firefox']['2.0']['Windows XP']); + $this->assertTrue(core_useragent::check_firefox_version()); + $this->assertTrue(core_useragent::check_firefox_version('1.5')); + $this->assertFalse(core_useragent::check_firefox_version('3.0')); + $this->assertTrue(core_useragent::check_gecko_version('2')); + $this->assertTrue(core_useragent::check_gecko_version(20030516)); + $this->assertTrue(core_useragent::check_gecko_version(20051106)); + $this->assertTrue(core_useragent::check_gecko_version(2006010100)); + + core_useragent::instance(true, $this->user_agents['Firefox']['1.0.6']['Windows XP']); + $this->assertTrue(core_useragent::check_firefox_version()); + $this->assertTrue(core_useragent::check_gecko_version('1')); + $this->assertFalse(core_useragent::check_gecko_version(20030516)); + $this->assertFalse(core_useragent::check_gecko_version(20051106)); + $this->assertFalse(core_useragent::check_gecko_version(2006010100)); + $this->assertFalse(core_useragent::check_firefox_version('1.5')); + $this->assertFalse(core_useragent::check_firefox_version('3.0')); + $this->assertFalse(core_useragent::check_gecko_version('2')); + + core_useragent::instance(true, $this->user_agents['Firefox']['2.0']['Windows XP']); + $this->assertTrue(core_useragent::check_firefox_version()); + $this->assertTrue(core_useragent::check_firefox_version('1.5')); + $this->assertTrue(core_useragent::check_gecko_version('1')); + $this->assertTrue(core_useragent::check_gecko_version('2')); + $this->assertTrue(core_useragent::check_gecko_version(20030516)); + $this->assertTrue(core_useragent::check_gecko_version(20051106)); + $this->assertTrue(core_useragent::check_gecko_version(2006010100)); + $this->assertFalse(core_useragent::check_firefox_version('3.0')); + + core_useragent::instance(true, $this->user_agents['Firefox']['3.6']['Linux']); + $this->assertTrue(core_useragent::check_firefox_version()); + $this->assertTrue(core_useragent::check_firefox_version('1.5')); + $this->assertTrue(core_useragent::check_firefox_version('3.0')); + $this->assertTrue(core_useragent::check_gecko_version('2')); + $this->assertTrue(core_useragent::check_gecko_version('3.6')); + $this->assertTrue(core_useragent::check_gecko_version(20030516)); + $this->assertTrue(core_useragent::check_gecko_version(20051106)); + $this->assertTrue(core_useragent::check_gecko_version(2006010100)); + $this->assertFalse(core_useragent::check_firefox_version('4')); + $this->assertFalse(core_useragent::check_firefox_version('10')); + + core_useragent::instance(true, $this->user_agents['Firefox']['3.6']['Linux']); + $this->assertTrue(core_useragent::check_firefox_version()); + $this->assertTrue(core_useragent::check_firefox_version('1.5')); + $this->assertTrue(core_useragent::check_firefox_version('3.0')); + $this->assertTrue(core_useragent::check_gecko_version('2')); + $this->assertTrue(core_useragent::check_gecko_version('3.6')); + $this->assertTrue(core_useragent::check_gecko_version(20030516)); + $this->assertTrue(core_useragent::check_gecko_version(20051106)); + $this->assertTrue(core_useragent::check_gecko_version(2006010100)); + $this->assertFalse(core_useragent::check_firefox_version('4')); + $this->assertFalse(core_useragent::check_firefox_version('10')); + $this->assertFalse(core_useragent::check_firefox_version('18')); + $this->assertFalse(core_useragent::check_gecko_version('4')); + + core_useragent::instance(true, $this->user_agents['Firefox']['15.0a2']['Windows']); + $this->assertTrue(core_useragent::check_firefox_version()); + $this->assertTrue(core_useragent::check_firefox_version('1.5')); + $this->assertTrue(core_useragent::check_firefox_version('3.0')); + $this->assertTrue(core_useragent::check_gecko_version('2')); + $this->assertTrue(core_useragent::check_gecko_version('3.6')); + $this->assertTrue(core_useragent::check_gecko_version('15.0')); + $this->assertTrue(core_useragent::check_gecko_version(20030516)); + $this->assertTrue(core_useragent::check_gecko_version(20051106)); + $this->assertTrue(core_useragent::check_gecko_version(2006010100)); + $this->assertTrue(core_useragent::check_firefox_version('4')); + $this->assertTrue(core_useragent::check_firefox_version('10')); + $this->assertTrue(core_useragent::check_firefox_version('15')); + $this->assertFalse(core_useragent::check_firefox_version('18')); + $this->assertFalse(core_useragent::check_gecko_version('18')); + + core_useragent::instance(true, $this->user_agents['Firefox']['18.0']['Mac OS X']); + $this->assertTrue(core_useragent::check_firefox_version()); + $this->assertTrue(core_useragent::check_firefox_version('1.5')); + $this->assertTrue(core_useragent::check_firefox_version('3.0')); + $this->assertTrue(core_useragent::check_gecko_version('2')); + $this->assertTrue(core_useragent::check_gecko_version('3.6')); + $this->assertTrue(core_useragent::check_gecko_version('15.0')); + $this->assertTrue(core_useragent::check_gecko_version('18.0')); + $this->assertTrue(core_useragent::check_gecko_version(20030516)); + $this->assertTrue(core_useragent::check_gecko_version(20051106)); + $this->assertTrue(core_useragent::check_gecko_version(2006010100)); + $this->assertTrue(core_useragent::check_firefox_version('4')); + $this->assertTrue(core_useragent::check_firefox_version('10')); + $this->assertTrue(core_useragent::check_firefox_version('15')); + $this->assertTrue(core_useragent::check_firefox_version('18')); + $this->assertFalse(core_useragent::check_firefox_version('19')); + $this->assertFalse(core_useragent::check_gecko_version('19')); + + core_useragent::instance(true, $this->user_agents['SeaMonkey']['2.0']['Windows']); + $this->assertTrue(core_useragent::check_gecko_version('2')); + $this->assertTrue(core_useragent::check_gecko_version(20030516)); + $this->assertTrue(core_useragent::check_gecko_version(20051106)); + $this->assertTrue(core_useragent::check_gecko_version(2006010100)); + $this->assertFalse(core_useragent::check_gecko_version('3.6')); + $this->assertFalse(core_useragent::check_gecko_version('4.0')); + $this->assertFalse(core_useragent::check_firefox_version()); + + core_useragent::instance(true, $this->user_agents['SeaMonkey']['2.1']['Linux']); + $this->assertTrue(core_useragent::check_gecko_version('2')); + $this->assertTrue(core_useragent::check_gecko_version('3.6')); + $this->assertTrue(core_useragent::check_gecko_version('4.0')); + $this->assertTrue(core_useragent::check_gecko_version(20030516)); + $this->assertTrue(core_useragent::check_gecko_version(20051106)); + $this->assertTrue(core_useragent::check_gecko_version(2006010100)); + $this->assertTrue(core_useragent::check_firefox_version()); + $this->assertTrue(core_useragent::check_firefox_version(4.0)); + $this->assertFalse(core_useragent::check_firefox_version(5)); + $this->assertFalse(core_useragent::check_gecko_version('18.0')); + + } + + /** + * Test browser version classes functionality. + */ + public function test_get_browser_version_classes() { + core_useragent::instance(true, $this->user_agents['Safari']['412']['Mac OS X']); + $this->assertEquals(array('safari'), core_useragent::get_browser_version_classes()); + + core_useragent::instance(true, $this->user_agents['Chrome']['8']['Mac OS X']); + $this->assertEquals(array('safari'), core_useragent::get_browser_version_classes()); + + core_useragent::instance(true, $this->user_agents['Safari iOS']['528']['iPhone']); + $this->assertEquals(array('safari', 'ios'), core_useragent::get_browser_version_classes()); + + core_useragent::instance(true, $this->user_agents['WebKit Android']['530']['Nexus']); + $this->assertEquals(array('safari', 'android'), core_useragent::get_browser_version_classes()); + + core_useragent::instance(true, $this->user_agents['Chrome']['8']['Mac OS X']); + $this->assertEquals(array('safari'), core_useragent::get_browser_version_classes()); + + core_useragent::instance(true, $this->user_agents['Opera']['9.0']['Windows XP']); + $this->assertEquals(array('opera'), core_useragent::get_browser_version_classes()); + + core_useragent::instance(true, $this->user_agents['MSIE']['6.0']['Windows XP SP2']); + $this->assertEquals(array('ie', 'ie6'), core_useragent::get_browser_version_classes()); + + core_useragent::instance(true, $this->user_agents['MSIE']['7.0']['Windows XP SP2']); + $this->assertEquals(array('ie', 'ie7'), core_useragent::get_browser_version_classes()); + + core_useragent::instance(true, $this->user_agents['MSIE']['8.0']['Windows Vista']); + $this->assertEquals(array('ie', 'ie8'), core_useragent::get_browser_version_classes()); + + core_useragent::instance(true, $this->user_agents['MSIE']['9.0']['Windows 7']); + $this->assertEquals(array('ie', 'ie9'), core_useragent::get_browser_version_classes()); + + core_useragent::instance(true, $this->user_agents['MSIE']['9.0i']['Windows 7']); + $this->assertEquals(array('ie', 'ie9'), core_useragent::get_browser_version_classes()); + + core_useragent::instance(true, $this->user_agents['MSIE']['10.0']['Windows 8']); + $this->assertEquals(array('ie', 'ie10'), core_useragent::get_browser_version_classes()); + + core_useragent::instance(true, $this->user_agents['MSIE']['10.0i']['Windows 8']); + $this->assertEquals(array('ie', 'ie10'), core_useragent::get_browser_version_classes()); + + core_useragent::instance(true, $this->user_agents['Firefox']['2.0']['Windows XP']); + $this->assertEquals(array('gecko', 'gecko18'), core_useragent::get_browser_version_classes()); + + core_useragent::instance(true, $this->user_agents['Firefox']['3.0.6']['SUSE']); + $this->assertEquals(array('gecko', 'gecko19'), core_useragent::get_browser_version_classes()); + } + + /** + * Test device type detection. + */ + public function test_get_device_type() { + // IE8 (common pattern ~1.5% of IE7/8 users have embedded IE6 agent). + $ie8 = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; BT Openworld BB; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; Hotbar 10.2.197.0; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727)'; + core_useragent::instance(true, $ie8); + $this->assertEquals('default', core_useragent::get_device_type()); + // Genuine IE6. + $ie6 = 'Mozilla/4.0 (compatible; MSIE 6.0; AOL 9.0; Windows NT 5.1; SV1; FunWebProducts; .NET CLR 1.0.3705; Media Center PC 2.8)'; + core_useragent::instance(true, $ie6); + $this->assertEquals('legacy', core_useragent::get_device_type()); + + core_useragent::instance(true); + } +} \ No newline at end of file diff --git a/lib/upgrade.txt b/lib/upgrade.txt index 29a297f941f..35c524df093 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -24,71 +24,82 @@ Various previously deprecated functions have now been altered to throw DEBUG_DEV and will be removed in a future release (target: 2.8), a summary follows: Accesslib: - * get_context_instance() -> context_xxxx::instance() - * get_context_instance_by_id() -> context::instance_by_id($id) - * get_system_context() -> context_system::instance() - * context_moved() -> context::update_moved() - * preload_course_contexts() -> context_helper::preload_course() - * context_instance_preload() -> context_helper::preload_from_record() - * context_instance_preload_sql()-> context_helper::get_preload_record_columns_sql() - * get_contextlevel_name() -> context_helper::get_level_name() - * create_contexts() -> context_helper::create_instances() - * cleanup_contexts() -> context_helper::cleanup_instances() - * build_context_path() -> context_helper::build_all_paths() - * print_context_name() -> $context->get_context_name() - * mark_context_dirty() -> $context->mark_dirty() - * delete_context() -> $context->delete_content() or context_helper::delete_instance() - * get_context_url() -> $context->get_url() - * get_course_context() -> $context->get_course_context() - * get_parent_contexts() -> $context->get_parent_context_ids() - * get_parent_contextid() -> $context->get_parent_context() - * get_child_contexts() -> $context->get_child_contexts() - * rebuild_contexts() -> $context->reset_paths() - * get_user_courses_bycap() -> enrol_get_users_courses() - * get_courseid_from_context() -> $context->get_course_context(false) - * get_role_context_caps() -> (no replacement) - * load_temp_role() -> (no replacement) - * remove_temp_roles() -> (no replacement) - * get_related_contexts_string() -> $context->get_parent_context_ids(true) - * get_recent_enrolments() -> (no replacement) + * get_context_instance() -> context_xxxx::instance() + * get_context_instance_by_id() -> context::instance_by_id($id) + * get_system_context() -> context_system::instance() + * context_moved() -> context::update_moved() + * preload_course_contexts() -> context_helper::preload_course() + * context_instance_preload() -> context_helper::preload_from_record() + * context_instance_preload_sql() -> context_helper::get_preload_record_columns_sql() + * get_contextlevel_name() -> context_helper::get_level_name() + * create_contexts() -> context_helper::create_instances() + * cleanup_contexts() -> context_helper::cleanup_instances() + * build_context_path() -> context_helper::build_all_paths() + * print_context_name() -> $context->get_context_name() + * mark_context_dirty() -> $context->mark_dirty() + * delete_context() -> $context->delete_content() or context_helper::delete_instance() + * get_context_url() -> $context->get_url() + * get_course_context() -> $context->get_course_context() + * get_parent_contexts() -> $context->get_parent_context_ids() + * get_parent_contextid() -> $context->get_parent_context() + * get_child_contexts() -> $context->get_child_contexts() + * rebuild_contexts() -> $context->reset_paths() + * get_user_courses_bycap() -> enrol_get_users_courses() + * get_courseid_from_context() -> $context->get_course_context(false) + * get_role_context_caps() -> (no replacement) + * load_temp_role() -> (no replacement) + * remove_temp_roles() -> (no replacement) + * get_related_contexts_string() -> $context->get_parent_context_ids(true) + * get_recent_enrolments() -> (no replacement) Enrollment: - * get_course_participants() -> get_enrolled_users() - * is_course_participant() -> is_enrolled() + * get_course_participants() -> get_enrolled_users() + * is_course_participant() -> is_enrolled() Output: - * current_theme() -> $PAGE->theme->name - * skip_main_destination() -> $OUTPUT->skip_link_target() - * print_container() -> $OUTPUT->container() - * print_container_start() -> $OUTPUT->container_start() - * print_container_end() -> $OUTPUT->container_end() - * print_continue() -> $OUTPUT->continue_button() - * print_header() -> $PAGE methods - * print_header_simple() -> $PAGE methods - * print_side_block() -> $OUTPUT->block() - * print_arrow() -> $OUTPUT->arrow() - * print_scale_menu_helpbutton() -> $OUTPUT->help_icon_scale($courseid, $scale) - * print_checkbox() -> html_writer::checkbox() + * current_theme() -> $PAGE->theme->name + * skip_main_destination() -> $OUTPUT->skip_link_target() + * print_container() -> $OUTPUT->container() + * print_container_start() -> $OUTPUT->container_start() + * print_container_end() -> $OUTPUT->container_end() + * print_continue() -> $OUTPUT->continue_button() + * print_header() -> $PAGE methods + * print_header_simple() -> $PAGE methods + * print_side_block() -> $OUTPUT->block() + * print_arrow() -> $OUTPUT->arrow() + * print_scale_menu_helpbutton() -> $OUTPUT->help_icon_scale($courseid, $scale) + * print_checkbox() -> html_writer::checkbox() Navigation: - * print_navigation() -> $OUTPUT->navbar() - * build_navigation() -> $PAGE->navbar methods - * navmenu() -> (no replacement) + * print_navigation() -> $OUTPUT->navbar() + * build_navigation() -> $PAGE->navbar methods + * navmenu() -> (no replacement) Calendar: - * add_event() -> calendar_event::create() - * update_event() -> calendar_event->update() - * delete_event() -> calendar_event->delete() - * hide_event() -> calendar_event->toggle_visibility(false) - * show_event() -> calendar_event->toggle_visibility(true) + * add_event() -> calendar_event::create() + * update_event() -> calendar_event->update() + * delete_event() -> calendar_event->delete() + * hide_event() -> calendar_event->toggle_visibility(false) + * show_event() -> calendar_event->toggle_visibility(true) Misc: - * filter_text() -> format_text(), format_string()... - * httpsrequired() -> $PAGE->https_required() - * detect_munged_arguments() -> clean_param([...], PARAM_FILE) - * mygroupid() -> groups_get_all_groups() - * js_minify() -> core_minify::js_files() - * css_minify_css() -> core_minify::css_files() + * filter_text() -> format_text(), format_string()... + * httpsrequired() -> $PAGE->https_required() + * detect_munged_arguments() -> clean_param([...], PARAM_FILE) + * mygroupid() -> groups_get_all_groups() + * js_minify() -> core_minify::js_files() + * css_minify_css() -> core_minify::css_files() + +User-agent related functions: + * check_browser_operating_system() -> core_useragent::check_browser_operating_system() + * check_browser_version() -> core_useragent::check_browser_version() + * get_device_type() -> core_useragent::get_device_type() + * get_device_type_list() -> core_useragent::get_device_type_list() + * get_selected_theme_for_device_type() -> core_useragent::get_device_type_theme() + * get_device_cfg_var_name() -> core_useragent::get_device_type_cfg_var_name() + * set_user_device_type() -> core_useragent::set_user_device_type() + * get_user_device_type() -> core_useragent::get_user_device_type() + * get_browser_version_classes() -> core_useragent::get_browser_version_classes() YUI: * moodle-core-notification has been deprecated with a recommendation of diff --git a/mod/lti/locallib.php b/mod/lti/locallib.php index dd1d9788d23..3f32ec16b25 100644 --- a/mod/lti/locallib.php +++ b/mod/lti/locallib.php @@ -1145,12 +1145,12 @@ function lti_get_launch_container($lti, $toolconfig) { $launchcontainer = LTI_LAUNCH_CONTAINER_EMBED_NO_BLOCKS; } - $devicetype = get_device_type(); + $devicetype = core_useragent::get_device_type(); //Scrolling within the object element doesn't work on iOS or Android //Opening the popup window also had some issues in testing //For mobile devices, always take up the entire screen to ensure the best experience - if ($devicetype === 'mobile' || $devicetype === 'tablet' ) { + if ($devicetype === core_useragent::DEVICETYPE_MOBILE || $devicetype === core_useragent::DEVICETYPE_TABLET ) { $launchcontainer = LTI_LAUNCH_CONTAINER_REPLACE_MOODLE_WINDOW; } diff --git a/theme/bootstrapbase/config.php b/theme/bootstrapbase/config.php index 8ddf89567a6..37685cd731f 100644 --- a/theme/bootstrapbase/config.php +++ b/theme/bootstrapbase/config.php @@ -73,7 +73,7 @@ $THEME->layouts = array( 'regions' => array('side-pre', 'side-post'), 'defaultregion' => 'side-pre', ), - // part of course, typical for modules - default page layout if $cm specified in require_login() + // part of course, typical for modules - default page layout if $cm specified in require_login(). 'incourse' => array( 'file' => 'columns3.php', 'regions' => array('side-pre', 'side-post'), @@ -123,7 +123,7 @@ $THEME->layouts = array( 'regions' => array(), 'options' => array('nofooter'=>true, 'nocoursefooter'=>true), ), - // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible + // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible. 'embedded' => array( 'file' => 'embedded.php', 'regions' => array() @@ -167,7 +167,7 @@ $THEME->javascripts_footer = array( 'moodlebootstrap', ); -if (check_browser_version('MSIE') && !check_browser_version('MSIE', '9.0')) { +if (core_useragent::check_ie_version() && core_useragent::check_ie_version('9.0')) { $THEME->javascripts[] = 'html5shiv'; } diff --git a/theme/index.php b/theme/index.php index c51665f63a8..1dbeded965a 100644 --- a/theme/index.php +++ b/theme/index.php @@ -32,10 +32,10 @@ $unsettheme = optional_param('unsettheme', 0, PARAM_BOOL); admin_externalpage_setup('themeselector'); if (!empty($device)) { - // Make sure the device requested is valid - $devices = get_device_type_list(); + // Make sure the device requested is valid. + $devices = core_useragent::get_device_type_list(); if (!in_array($device, $devices)) { - // The provided device isn't a valid device throw an error + // The provided device isn't a valid device throw an error. print_error('invaliddevicetype'); } } @@ -49,7 +49,7 @@ if ($reset and confirm_sesskey()) { // Load the theme to make sure it is valid. $theme = theme_config::load($choose); // Get the config argument for the chosen device. - $themename = get_device_cfg_var_name($device); + $themename = core_useragent::get_device_type_cfg_var_name($device); set_config($themename, $theme->name); // Create a new page for the display of the themes readme. @@ -74,8 +74,8 @@ if ($reset and confirm_sesskey()) { echo $output->footer(); exit; } else if ($device && $unsettheme && confirm_sesskey() && ($device != 'default')) { - //Unset the theme and continue. - unset_config(get_device_cfg_var_name($device)); + // Unset the theme and continue. + unset_config(core_useragent::get_device_type_cfg_var_name($device)); $device = ''; } @@ -92,15 +92,15 @@ if (!empty($CFG->enabledevicedetection) && empty($device)) { $strthemenotselected = get_string('themenoselected', 'admin'); $strthemeselect = get_string('themeselect', 'admin'); - // Display the device selection screen + // Display the device selection screen. $table->id = 'admindeviceselector'; $table->head = array(get_string('devicetype', 'admin'), get_string('currenttheme', 'admin'), get_string('info')); - $devices = get_device_type_list(); + $devices = core_useragent::get_device_type_list(); foreach ($devices as $thedevice) { - $headingthemename = ''; // To output the picked theme name when needed - $themename = get_selected_theme_for_device_type($thedevice); + $headingthemename = ''; // To output the picked theme name when needed. + $themename = core_useragent::get_device_type_theme($thedevice); if (!$themename && $thedevice == 'default') { $themename = theme_config::DEFAULT_THEME; } @@ -108,24 +108,27 @@ if (!empty($CFG->enabledevicedetection) && empty($device)) { $screenshotcell = $strthemenotselected; $unsetthemebutton = ''; if ($themename) { - // Check the theme exists + // Check the theme exists. $themename = clean_param($themename, PARAM_THEME); if (empty($themename)) { - // Likely the theme has been deleted - unset_config(get_device_cfg_var_name($thedevice)); + // Likely the theme has been deleted. + unset_config(core_useragent::get_device_type_cfg_var_name($thedevice)); } else { $strthemename = get_string('pluginname', 'theme_'.$themename); - // link to the screenshot, now mandatory - the image path is hardcoded because we need image from other themes, not the current one - $screenshoturl = new moodle_url('/theme/image.php', array('theme' => $themename, 'image' => 'screenshot', 'component' => 'theme')); + // Link to the screenshot, now mandatory - the image path is hardcoded because we need image from other themes, + // not the current one. + $screenshoturl = new moodle_url('/theme/image.php', + array('theme' => $themename, 'image' => 'screenshot', 'component' => 'theme')); // Contents of the screenshot/preview cell. $screenshotcell = html_writer::empty_tag('img', array('src' => $screenshoturl, 'alt' => $strthemename)); - // Show the name of the picked theme + // Show the name of the picked theme. $headingthemename = $OUTPUT->heading($strthemename, 3); } // If not default device then show option to unset theme. if ($thedevice != 'default') { $unsetthemestr = get_string('unsettheme', 'admin'); - $unsetthemeurl = new moodle_url('/theme/index.php', array('device' => $thedevice, 'sesskey' => sesskey(), 'unsettheme' => true)); + $unsetthemeurl = new moodle_url('/theme/index.php', + array('device' => $thedevice, 'sesskey' => sesskey(), 'unsettheme' => true)); $unsetthemebutton = new single_button($unsetthemeurl, $unsetthemestr, 'get'); $unsetthemebutton = $OUTPUT->render($unsetthemebutton); } @@ -145,8 +148,8 @@ if (!empty($CFG->enabledevicedetection) && empty($device)) { // of themes to select. $heading = get_string('selecttheme', 'admin', $device); if (empty($device)) { - // if $CFG->enabledevicedetection is off this will return 'default' - $device = get_device_type(); + // If $CFG->enabledevicedetection is off this will return 'default'. + $device = core_useragent::get_device_type(); } $table->id = 'adminthemeselector'; @@ -164,7 +167,7 @@ if (!empty($CFG->enabledevicedetection) && empty($device)) { continue; } if ($themename !== $theme->name) { - //obsoleted or broken theme, just skip for now + // Obsoleted or broken theme, just skip for now. continue; } if (empty($CFG->themedesignermode) && $theme->hidefromselector) { @@ -179,31 +182,34 @@ if (!empty($CFG->enabledevicedetection) && empty($device)) { $infoitems = array(); $rowclasses = array(); - // Set up bools whether this theme is chosen either main or legacy - $ischosentheme = ($themename == get_selected_theme_for_device_type($device)); + // Set up bools whether this theme is chosen either main or legacy. + $ischosentheme = ($themename == core_useragent::get_device_type_theme($device)); if ($ischosentheme) { - // Is the chosen main theme + // Is the chosen main theme. $rowclasses[] = 'selectedtheme'; } - // link to the screenshot, now mandatory - the image path is hardcoded because we need image from other themes, not the current one - $screenshotpath = new moodle_url('/theme/image.php', array('theme'=>$themename, 'image'=>'screenshot', 'component'=>'theme')); + // Link to the screenshot, now mandatory - the image path is hardcoded because we need image from other themes, + // not the current one. + $screenshotpath = new moodle_url('/theme/image.php', + array('theme'=>$themename, 'image'=>'screenshot', 'component'=>'theme')); // Contents of the first screenshot/preview cell. $row[] = html_writer::empty_tag('img', array('src'=>$screenshotpath, 'alt'=>$strthemename)); // Contents of the second cell. $infocell = $OUTPUT->heading($strthemename, 3); - // Button to choose this as the main theme or unset this theme for - // devices other then default + // Button to choose this as the main theme or unset this theme for devices other then default. if (($ischosentheme) && ($device != 'default')) { $unsetthemestr = get_string('unsettheme', 'admin'); - $unsetthemeurl = new moodle_url('/theme/index.php', array('device' => $device, 'unsettheme' => true, 'sesskey' => sesskey())); + $unsetthemeurl = new moodle_url('/theme/index.php', + array('device' => $device, 'unsettheme' => true, 'sesskey' => sesskey())); $unsetbutton = new single_button($unsetthemeurl, $unsetthemestr, 'get'); $infocell .= $OUTPUT->render($unsetbutton); } else if ((!$ischosentheme)) { $setthemestr = get_string('usetheme'); - $setthemeurl = new moodle_url('/theme/index.php', array('device' => $device, 'choose' => $themename, 'sesskey' => sesskey())); + $setthemeurl = new moodle_url('/theme/index.php', + array('device' => $device, 'choose' => $themename, 'sesskey' => sesskey())); $setthemebutton = new single_button($setthemeurl, $setthemestr, 'get'); $infocell .= $OUTPUT->render($setthemebutton); } diff --git a/theme/mymobile/config.php b/theme/mymobile/config.php index c2b9cd2b81d..c162766fac8 100644 --- a/theme/mymobile/config.php +++ b/theme/mymobile/config.php @@ -142,10 +142,11 @@ $THEME->layouts = array( ); // Get whether to show blocks and use appropriate pagelayout -// this is necessary for block JS errors and other block problems -$thisdevice = get_device_type(); -if ($thisdevice == "default" || $thisdevice == "tablet" || optional_param('mymobile_blocks', false, PARAM_BOOL)) { - // These are layouts with blocks +// this is necessary for block JS errors and other block problems. +$thisdevice = core_useragent::get_device_type(); +if ($thisdevice === core_useragent::DEVICETYPE_DEFAULT || $thisdevice === core_useragent::DEVICETYPE_TABLET || + optional_param('mymobile_blocks', false, PARAM_BOOL)) { + // These are layouts with blocks. $blocklayouts = array('course', 'incourse', 'frontpage', 'mydashboard', 'mypublic'); foreach ($blocklayouts as $layout) { $THEME->layouts[$layout]['regions'] = array('myblocks'); diff --git a/theme/switchdevice.php b/theme/switchdevice.php index 084a1adaf82..213f0f3f4b0 100644 --- a/theme/switchdevice.php +++ b/theme/switchdevice.php @@ -31,6 +31,6 @@ $newdevice = required_param('device', PARAM_TEXT); require_sesskey(); -set_user_device_type($newdevice); +core_useragent::set_user_device_type($newdevice); redirect($url); diff --git a/version.php b/version.php index c42ca0496cc..17a4b0d838d 100644 --- a/version.php +++ b/version.php @@ -29,11 +29,11 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2013081500.00; // YYYYMMDD = weekly release date of this DEV branch - // RR = release increments - 00 in DEV branches - // .XX = incremental changes +$version = 2013081600.00; // YYYYMMDD = weekly release date of this DEV branch. + // RR = release increments - 00 in DEV branches. + // .XX = incremental changes. -$release = '2.6dev (Build: 20130815)'; // Human-friendly version name +$release = '2.6dev (Build: 20130808)'; // Human-friendly version name. -$branch = '26'; // this version's branch -$maturity = MATURITY_ALPHA; // this version's maturity level +$branch = '26'; // This version's branch. +$maturity = MATURITY_ALPHA; // This version's maturity level.