Commit af62237d authored by Sam Hemelryk's avatar Sam Hemelryk
Browse files

MDL-40931 useragent: separated user agent functionality into a lib

This commit moves user agent related functionality out of several
core libraries and combines it into a more manageable class.
All core uses are converted and functions deprecated in favor
of the new class.
parent 838d78a9
......@@ -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) {
......
......@@ -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');
}
......
......@@ -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
......
......@@ -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'));
}
/**
......
......@@ -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">&nbsp;</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));
}
......
<?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));
}
}
This diff is collapsed.
......@@ -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
......@@ -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;
}
......
......@@ -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...
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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;
}
......
......@@ -7403,448 +7403,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;
}
}