MDL-51737 core: Add Edge UserAgent support
authorAndrew Nicols <andrew@nicols.co.uk>
Tue, 13 Oct 2015 06:51:29 +0000 (14:51 +0800)
committerAndrew Nicols <andrew@nicols.co.uk>
Thu, 22 Oct 2015 00:37:27 +0000 (08:37 +0800)
lib/classes/useragent.php
lib/tests/useragent_test.php

index fcc3c6d..5ed0c73 100644 (file)
@@ -481,6 +481,52 @@ class core_useragent {
         return false;
     }
 
+    /**
+     * Checks the user agent is Edge (of any version).
+     *
+     * @return bool true if Edge
+     */
+    public static function is_edge() {
+        return self::check_edge_version();
+    }
+
+    /**
+     * Check the User Agent for the version of Edge.
+     *
+     * @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_edge_version($version = null) {
+        $useragent = self::get_user_agent_string();
+
+        if ($useragent === false) {
+            // No User Agent found.
+            return false;
+        }
+
+        if (strpos($useragent, 'Edge/') === false) {
+            // Edge was not found in the UA - this is not Edge.
+            return false;
+        }
+
+        if (empty($version)) {
+            // No version to check.
+            return true;
+        }
+
+        // Find the version.
+        // Edge versions are always in the format:
+        //      Edge/<version>.<OS build number>
+        preg_match('%Edge/([\d]+)\.(.*)$%', $useragent, $matches);
+
+        // Just to be safe, round the version being tested.
+        // Edge only uses integer versions - the second component is the OS build number.
+        $version = round($version);
+
+        // Check whether the version specified is >= the version found.
+        return version_compare($matches[1], $version, '>=');
+    }
+
     /**
      * Checks the user agent is IE (of any version).
      *
@@ -516,6 +562,7 @@ class core_useragent {
         } else {
             return false;
         }
+
         $compatview = 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.
@@ -696,7 +743,9 @@ class core_useragent {
             // 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.
+        if (strpos($useragent, 'Chrome')) {
+            // Reject chrome browsers - it needs to be tested explicitly.
+            // This will also reject Edge, which pretends to be both Chrome, and Safari.
             return false;
         }
 
index f0dd54d..b81c59a 100644 (file)
@@ -42,6 +42,68 @@ class core_useragent_testcase extends basic_testcase {
         // Note: When adding new entries to this list, please ensure that any new browser versions are added to the corresponding list.
         // This ensures that regression tests are applied to all known user agents.
         return array(
+            'Microsoft Edge for Windows 10 Desktop' => array(
+                'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10136',
+                array(
+                    'is_edge'                       => true,
+                    'check_edge_version'            => array(
+                        '12'                        => true,
+                    ),
+
+                    // Edge pretends to be WebKit.
+                    'is_webkit'                     => true,
+
+                    // Edge pretends to be Chrome.
+                    // Note: Because Edge pretends to be Chrome, it will not be picked up as a Safari browser.
+                    'is_chrome'                     => true,
+                    'check_chrome_version'          => array(
+                        '7'                         => true,
+                        '8'                         => true,
+                        '10'                        => true,
+                        '39'                        => true,
+                    ),
+
+                    'versionclasses'                => array(
+                        'safari',
+                    ),
+                ),
+            ),
+            'Microsoft Edge for Windows 10 Mobile' => array(
+                'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; DEVICE INFO) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Mobile Safari/537.36 Edge/12.10136',
+                array(
+                    'is_edge'                       => true,
+                    'check_edge_version'              => array(
+                        '12'                        => true,
+                    ),
+
+                    // Edge pretends to be WebKit.
+                    'is_webkit'                     => true,
+
+                    // Mobile Edge pretends to be Android.
+                    'is_webkit_android'             => true,
+                    'check_webkit_android_version'  => array(
+                        '525'                       => true,
+                        '527'                       => true,
+                    ),
+
+                    // Edge pretends to be Chrome.
+                    // Note: Because Edge pretends to be Chrome, it will not be picked up as a Safari browser.
+                    'is_chrome'                     => true,
+                    'check_chrome_version'          => array(
+                        '7'                         => true,
+                        '8'                         => true,
+                        '10'                        => true,
+                        '39'                        => true,
+                    ),
+
+                    'versionclasses'                => array(
+                        'safari',
+                        'android',
+                    ),
+
+                    'devicetype'                    => 'mobile',
+                ),
+            ),
             // Windows 98; Internet Explorer 5.0.
             array(
                 'Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)',
@@ -1338,6 +1400,37 @@ class core_useragent_testcase extends basic_testcase {
         $this->assertInstanceOf('core_useragent', core_useragent::instance(true));
     }
 
+    /**
+     * @dataProvider user_agents_providers
+     */
+    public function test_useragent_edge($useragent, $tests) {
+        // Setup the core_useragent instance.
+        core_useragent::instance(true, $useragent);
+
+        // Edge Tests.
+        if (isset($tests['is_edge']) && $tests['is_edge']) {
+            $this->assertTrue(core_useragent::is_edge());
+        } else {
+            $this->assertFalse(core_useragent::is_edge());
+        }
+
+        $versions = array(
+            // New versions of should be added here.
+            '12'   => false,
+        );
+
+        if (isset($tests['check_edge_version'])) {
+            // The test provider has overwritten some of the above checks.
+            // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
+            $versions = $tests['check_edge_version'] + $versions;
+        }
+
+        foreach ($versions as $version => $result) {
+            $this->assertEquals($result, core_useragent::check_edge_version($version),
+                "Version incorrectly determined for Edge version '{$version}'");
+        }
+    }
+
     /**
      * @dataProvider user_agents_providers
      */