Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Tests the user agent class.
  19   *
  20   * @package    core
  21   * @copyright  2013 Sam Hemelryk
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  /**
  26   * User agent test suite.
  27   *
  28   * @package    core
  29   * @copyright  2013 Sam Hemelryk
  30   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  31   */
  32  class core_useragent_testcase extends advanced_testcase {
  33  
  34      /**
  35       * Restores the user agent to the default one.
  36       */
  37      public function tearDown(): void {
  38          core_useragent::instance(true);
  39      }
  40  
  41      public function user_agents_providers() {
  42          // Note: When adding new entries to this list, please ensure that any new browser versions are added to the corresponding list.
  43          // This ensures that regression tests are applied to all known user agents.
  44          return array(
  45              'Microsoft Edge for Windows 10 Desktop' => array(
  46                  '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',
  47                  array(
  48                      'is_edge'                       => true,
  49                      'check_edge_version'            => array(
  50                          '12'                        => true,
  51                      ),
  52  
  53                      // Edge pretends to be WebKit.
  54                      'is_webkit'                     => true,
  55  
  56                      // Edge pretends to be Chrome.
  57                      // Note: Because Edge pretends to be Chrome, it will not be picked up as a Safari browser.
  58                      'is_chrome'                     => true,
  59                      'check_chrome_version'          => array(
  60                          '7'                         => true,
  61                          '8'                         => true,
  62                          '10'                        => true,
  63                          '39'                        => true,
  64                      ),
  65  
  66                      'versionclasses'                => array(
  67                          'edge',
  68                      ),
  69                  ),
  70              ),
  71              'Microsoft Edge for Windows 10 Mobile' => array(
  72                  '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',
  73                  array(
  74                      'is_edge'                       => true,
  75                      'check_edge_version'              => array(
  76                          '12'                        => true,
  77                      ),
  78  
  79                      // Edge pretends to be WebKit.
  80                      'is_webkit'                     => true,
  81  
  82                      // Mobile Edge pretends to be Android.
  83                      'is_webkit_android'             => true,
  84                      'check_webkit_android_version'  => array(
  85                          '525'                       => true,
  86                          '527'                       => true,
  87                      ),
  88  
  89                      // Edge pretends to be Chrome.
  90                      // Note: Because Edge pretends to be Chrome, it will not be picked up as a Safari browser.
  91                      'is_chrome'                     => true,
  92                      'check_chrome_version'          => array(
  93                          '7'                         => true,
  94                          '8'                         => true,
  95                          '10'                        => true,
  96                          '39'                        => true,
  97                      ),
  98  
  99                      'versionclasses'                => array(
 100                          'edge'
 101                      ),
 102  
 103                      'devicetype'                    => 'mobile',
 104                  ),
 105              ),
 106              // Windows 98; Internet Explorer 5.0.
 107              array(
 108                  'Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)',
 109                  array(
 110                      // MSIE 5.0 is not considered a browser at all: known false results.
 111                      'is_ie'                         => false,
 112                      'check_ie_version'              => array(
 113                          '0'                         => true,
 114                          '5.0'                       => true,
 115                      ),
 116                      'versionclasses'                => array(
 117                          // IE 5.0 is not considered a browser.
 118                      ),
 119  
 120                      // IE 5.0 is a legacy browser.
 121                      'devicetype'                    => 'legacy',
 122  
 123                      'supports_svg'                  => false,
 124                      'supports_json_contenttype'     => false,
 125                  ),
 126              ),
 127  
 128              // Windows 2000; Internet Explorer 5.5.
 129              array(
 130                  'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)',
 131                  array(
 132                      'is_ie'                         => true,
 133                      'check_ie_version'              => array(
 134                          '0'                         => true,
 135                          '5.0'                       => true,
 136                          '5.5'                       => true,
 137                      ),
 138                      'versionclasses'                => array(
 139                          'ie',
 140                      ),
 141  
 142                      // IE 6.0 is a legacy browser.
 143                      'devicetype'                    => 'legacy',
 144  
 145                      'supports_svg'                  => false,
 146                      'supports_json_contenttype'     => false,
 147                  ),
 148              ),
 149  
 150              // Windows XP SP2; Internet Explorer 6.0.
 151              array(
 152                  'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)',
 153                  array(
 154                      'is_ie'                         => true,
 155                      'check_ie_version'              => array(
 156                          '0'                         => true,
 157                          '5.0'                       => true,
 158                          '5.5'                       => true,
 159                          '6.0'                       => true,
 160                      ),
 161                      'versionclasses'                => array(
 162                          'ie',
 163                          'ie6',
 164                      ),
 165  
 166                      // IE 7.0 is a legacy browser.
 167                      'devicetype'                    => 'legacy',
 168  
 169                      'supports_svg'                  => false,
 170                      'supports_json_contenttype'     => false,
 171                  ),
 172              ),
 173  
 174              // Windows XP SP2; Internet Explorer 7.0.
 175              array(
 176                  '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)',
 177                  array(
 178                      'is_ie'                         => true,
 179                      'check_ie_version'              => array(
 180                          '0'                         => true,
 181                          '5.0'                       => true,
 182                          '5.5'                       => true,
 183                          '6.0'                       => true,
 184                          '7.0'                       => true,
 185                      ),
 186                      'versionclasses'                => array(
 187                          'ie',
 188                          'ie7',
 189                      ),
 190  
 191                      'supports_svg'                  => false,
 192                      'supports_json_contenttype'     => false,
 193                  ),
 194              ),
 195  
 196              // Windows XP SP2; Internet Explorer 7.0; Meridio extension.
 197              array(
 198                  'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Meridio for Excel 5.0.251; Meridio for PowerPoint 5.0.251; Meridio for Word 5.0.251; Meridio Protocol; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)',
 199                  array(
 200                      'is_ie'                         => true,
 201                      'check_ie_version'              => array(
 202                          '0'                         => true,
 203                          '5.0'                       => true,
 204                          '5.5'                       => true,
 205                          '6.0'                       => true,
 206                          '7.0'                       => true,
 207                      ),
 208                      'versionclasses'                => array(
 209                          'ie',
 210                          'ie7',
 211                      ),
 212  
 213                      'supports_svg'                  => false,
 214                      'supports_json_contenttype'     => false,
 215                  ),
 216              ),
 217  
 218              // Windows Vista; Internet Explorer 8.0.
 219              array(
 220                  '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)',
 221                  array(
 222                      'is_ie'                         => true,
 223                      'check_ie_version'              => array(
 224                          '0'                         => true,
 225                          '5.0'                       => true,
 226                          '5.5'                       => true,
 227                          '6.0'                       => true,
 228                          '7.0'                       => true,
 229                          '8.0'                       => true,
 230                      ),
 231                      'versionclasses'                => array(
 232                          'ie',
 233                          'ie8',
 234                      ),
 235  
 236                      'supports_svg'                  => false,
 237                  ),
 238              ),
 239  
 240              // Windows 7; Internet Explorer 9.0.
 241              array(
 242                  'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)',
 243                  array(
 244                      'is_ie'                         => true,
 245                      'check_ie_version'              => array(
 246                          '0'                         => true,
 247                          '5.0'                       => true,
 248                          '5.5'                       => true,
 249                          '6.0'                       => true,
 250                          '7.0'                       => true,
 251                          '8.0'                       => true,
 252                          '9.0'                       => true,
 253                      ),
 254                      'versionclasses'                => array(
 255                          'ie',
 256                          'ie9',
 257                      ),
 258                  ),
 259              ),
 260  
 261              // Windows 7; Internet Explorer 9.0i.
 262              array(
 263                  '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)',
 264                  array(
 265                      'is_ie'                         => true,
 266                      'check_ie_version'              => array(
 267                          '0'                         => true,
 268                          '5.0'                       => true,
 269                          '5.5'                       => true,
 270                          '6.0'                       => true,
 271                          '7.0'                       => true,
 272                          '8.0'                       => true,
 273                          '9.0'                       => true,
 274                      ),
 275                      'versionclasses'                => array(
 276                          'ie',
 277                          'ie9',
 278                      ),
 279                      'iecompatibility'               => true,
 280  
 281                      // IE 9 in Compatiblity mode does not support SVG.
 282                      'supports_svg'                  => false,
 283  
 284                      // IE in Compatiblity mode does not support JSON ContentType.
 285                      'supports_json_contenttype'     => false,
 286                  ),
 287              ),
 288  
 289              // Windows 8; Internet Explorer 10.0.
 290              array(
 291                  'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0; Touch)',
 292                  array(
 293                      'is_ie'                         => true,
 294                      'check_ie_version'              => array(
 295                          '0'                         => true,
 296                          '5.0'                       => true,
 297                          '5.5'                       => true,
 298                          '6.0'                       => true,
 299                          '7.0'                       => true,
 300                          '8.0'                       => true,
 301                          '9.0'                       => true,
 302                          '10'                        => true,
 303                      ),
 304                      'versionclasses'                => array(
 305                          'ie',
 306                          'ie10',
 307                      ),
 308                  ),
 309              ),
 310  
 311              // Windows 8; Internet Explorer 10.0i.
 312              array(
 313                  'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; Trident/6.0; Touch; .NET4.0E; .NET4.0C; Tablet PC 2.0)',
 314                  array(
 315                      'is_ie'                         => true,
 316                      'check_ie_version'              => array(
 317                          '0'                         => true,
 318                          '5.0'                       => true,
 319                          '5.5'                       => true,
 320                          '6.0'                       => true,
 321                          '7.0'                       => true,
 322                          '8.0'                       => true,
 323                          '9.0'                       => true,
 324                          '10'                        => true,
 325                      ),
 326                      'iecompatibility'               => true,
 327                      'versionclasses'                => array(
 328                          'ie',
 329                          'ie10',
 330                      ),
 331  
 332                      // IE in Compatiblity mode does not support JSON ContentType.
 333                      'supports_json_contenttype'     => false,
 334                  ),
 335              ),
 336  
 337              // Windows 8.1; Internet Explorer 11.0.
 338              array(
 339                  'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0)',
 340                  array(
 341                      'is_ie'                         => true,
 342                      'check_ie_version'              => array(
 343                          '0'                         => true,
 344                          '5.0'                       => true,
 345                          '5.5'                       => true,
 346                          '6.0'                       => true,
 347                          '7.0'                       => true,
 348                          '8.0'                       => true,
 349                          '9.0'                       => true,
 350                          '10'                        => true,
 351                          '11'                        => true,
 352                      ),
 353                      'versionclasses'                => array(
 354                          'ie',
 355                          'ie11',
 356                      ),
 357                  ),
 358              ),
 359  
 360              // Windows 8.1; Internet Explorer 11.0i.
 361              array(
 362                  ' Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; Trident/7.0; .NET4.0E; .NET4.0C)',
 363                  array(
 364                      'is_ie'                         => true,
 365                      'check_ie_version'              => array(
 366                          '0'                         => true,
 367                          '5.0'                       => true,
 368                          '5.5'                       => true,
 369                          '6.0'                       => true,
 370                          '7.0'                       => true,
 371                          '8.0'                       => true,
 372                          '9.0'                       => true,
 373                          '10'                        => true,
 374                          '11'                        => true,
 375                      ),
 376                      'iecompatibility'               => true,
 377                      'versionclasses'                => array(
 378                          'ie',
 379                          'ie11',
 380                      ),
 381  
 382                      // IE in Compatiblity mode does not support JSON ContentType.
 383                      'supports_json_contenttype'     => false,
 384                  ),
 385              ),
 386  
 387              // Windows XP; Firefox 1.0.6.
 388              array(
 389                  'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6',
 390                  array(
 391                      'is_firefox'                    => true,
 392  
 393                      'is_gecko'                      => true,
 394                      'check_gecko_version'           => array(
 395                          '1'                         => true,
 396                      ),
 397  
 398                      'versionclasses'                => array(
 399                          'gecko',
 400                          'gecko17',
 401                      ),
 402                  ),
 403              ),
 404  
 405              // Windows XP; Firefox 1.0.6.
 406              array(
 407                  'Mozilla/5.0 (Windows; U; Windows NT 5.1; nl; rv:1.8) Gecko/20051107 Firefox/1.5',
 408                  array(
 409                      'is_firefox'                    => true,
 410                      'check_firefox_version'         => array(
 411                          '1.5'                       => true,
 412                      ),
 413  
 414                      'is_gecko'                      => true,
 415                      'check_gecko_version'           => array(
 416                          '1'                         => true,
 417                          '20030516'                  => true,
 418                          '20051116'                  => true,
 419                      ),
 420  
 421                      'versionclasses'                => array(
 422                          'gecko',
 423                          'gecko18',
 424                      ),
 425                  ),
 426              ),
 427  
 428              // Windows XP; Firefox 1.5.0.1.
 429              array(
 430                  'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1',
 431                  array(
 432                      'is_firefox'                    => true,
 433                      'check_firefox_version'         => array(
 434                          '1.5'                       => true,
 435                      ),
 436  
 437                      'is_gecko'                      => true,
 438                      'check_gecko_version'           => array(
 439                          '1'                         => true,
 440                          '20030516'                  => true,
 441                          '20051116'                  => true,
 442                      ),
 443  
 444                      'versionclasses'                => array(
 445                          'gecko',
 446                          'gecko18',
 447                      ),
 448                  ),
 449              ),
 450  
 451              // Windows XP; Firefox 2.0.
 452              array(
 453                  'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1',
 454                  array(
 455                      'is_firefox'                    => true,
 456                      'check_firefox_version'         => array(
 457                          '1.5'                       => true,
 458                      ),
 459  
 460                      'is_gecko'                      => true,
 461                      'check_gecko_version'           => array(
 462                          '1'                         => true,
 463                          '2'                         => true,
 464                          '20030516'                  => true,
 465                          '20051116'                  => true,
 466                          '2006010100'                => true,
 467                      ),
 468  
 469                      'versionclasses'                => array(
 470                          'gecko',
 471                          'gecko18',
 472                      ),
 473                  ),
 474              ),
 475  
 476              // Ubuntu Linux amd64; Firefox 2.0.
 477              array(
 478                  'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1) Gecko/20060601 Firefox/2.0 (Ubuntu-edgy)',
 479                  array(
 480                      'is_firefox'                    => true,
 481                      'check_firefox_version'         => array(
 482                          '1.5'                       => true,
 483                      ),
 484  
 485                      'is_gecko'                      => true,
 486                      'check_gecko_version'           => array(
 487                          '1'                         => true,
 488                          '2'                         => true,
 489                          '20030516'                  => true,
 490                          '20051116'                  => true,
 491                          '2006010100'                => true,
 492                      ),
 493  
 494                      'versionclasses'                => array(
 495                          'gecko',
 496                          'gecko18',
 497                      ),
 498                  ),
 499              ),
 500  
 501              // SUSE; Firefox 3.0.6.
 502              array(
 503                  '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',
 504                  array(
 505                      'is_firefox'                    => true,
 506                      'check_firefox_version'         => array(
 507                          '1.5'                       => true,
 508                          '3.0'                       => true,
 509                      ),
 510  
 511                      'is_gecko'                      => true,
 512                      'check_gecko_version'           => array(
 513                          '1'                         => true,
 514                          '2'                         => true,
 515                          '20030516'                  => true,
 516                          '20051116'                  => true,
 517                          '2006010100'                => true,
 518                      ),
 519  
 520                      'versionclasses'                => array(
 521                          'gecko',
 522                          'gecko19',
 523                      ),
 524                  ),
 525              ),
 526  
 527              // Linux i686; Firefox 3.6.
 528              array(
 529                  'Mozilla/5.0 (X11; Linux i686; rv:2.0) Gecko/20100101 Firefox/3.6',
 530                  array(
 531                      'is_firefox'                    => true,
 532                      'check_firefox_version'         => array(
 533                          '1.5'                       => true,
 534                          '3.0'                       => true,
 535                      ),
 536  
 537                      'is_gecko'                      => true,
 538                      'check_gecko_version'           => array(
 539                          '1'                         => true,
 540                          '2'                         => true,
 541                          '20030516'                  => true,
 542                          '20051116'                  => true,
 543                          '2006010100'                => true,
 544                          '3.6'                       => true,
 545                          '20100101'                  => true,
 546                      ),
 547  
 548                      'versionclasses'                => array(
 549                          'gecko',
 550                          'gecko20',
 551                      ),
 552                  ),
 553              ),
 554  
 555              // Windows; Firefox 11.0.
 556              array(
 557                  'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko Firefox/11.0',
 558                  array(
 559                      'is_firefox'                    => true,
 560                      'check_firefox_version'         => array(
 561                          '1.5'                       => true,
 562                          '3.0'                       => true,
 563                          '4'                         => true,
 564                          '10'                        => true,
 565                      ),
 566  
 567                      'is_gecko'                      => true,
 568                      'check_gecko_version'           => array(
 569                          '1'                         => true,
 570                          '2'                         => true,
 571                          '20030516'                  => true,
 572                          '20051116'                  => true,
 573                          '2006010100'                => true,
 574                          '20100101'                  => true,
 575                          '3.6'                       => true,
 576                          '4.0'                       => true,
 577                      ),
 578  
 579                      'versionclasses'                => array(
 580                          'gecko',
 581                      ),
 582                  ),
 583              ),
 584  
 585              // Windows; Firefox 15.0a2.
 586              array(
 587                  'Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20120716 Firefox/15.0a2',
 588                  array(
 589                      'is_firefox'                    => true,
 590                      'check_firefox_version'         => array(
 591                          '1.5'                       => true,
 592                          '3.0'                       => true,
 593                          '4'                         => true,
 594                          '10'                        => true,
 595                          '15'                        => true,
 596                      ),
 597  
 598                      'is_gecko'                      => true,
 599                      'check_gecko_version'           => array(
 600                          '1'                         => true,
 601                          '2'                         => true,
 602                          '20030516'                  => true,
 603                          '20051116'                  => true,
 604                          '2006010100'                => true,
 605                          '20100101'                  => true,
 606                          '3.6'                       => true,
 607                          '4.0'                       => true,
 608                          '15.0'                      => true,
 609                      ),
 610  
 611                      'versionclasses'                => array(
 612                          'gecko',
 613                      ),
 614                  ),
 615              ),
 616  
 617              // Firefox 18; Mac OS X 10.
 618              array(
 619                  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:18.0) Gecko/18.0 Firefox/18.0',
 620                  array(
 621                      'is_firefox'                    => true,
 622                      'check_firefox_version'         => array(
 623                          '1.5'                       => true,
 624                          '3.0'                       => true,
 625                          '4'                         => true,
 626                          '10'                        => true,
 627                          '15'                        => true,
 628                          '18'                        => true,
 629                      ),
 630  
 631                      'is_gecko'                      => true,
 632                      'check_gecko_version'           => array(
 633                          '1'                         => true,
 634                          '2'                         => true,
 635                          '20030516'                  => true,
 636                          '20051116'                  => true,
 637                          '2006010100'                => true,
 638                          '3.6'                       => true,
 639                          '4.0'                       => true,
 640                          '15.0'                      => true,
 641                          '18.0'                      => true,
 642                          '20100101'                  => true,
 643                      ),
 644  
 645                      'versionclasses'                => array(
 646                          'gecko',
 647                      ),
 648                  ),
 649              ),
 650  
 651              // Firefox 33; Mac OS X 10.10.
 652              array(
 653                  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:33.0) Gecko/20100101 Firefox/33.0',
 654                  array(
 655                      'is_firefox'                    => true,
 656                      'check_firefox_version'         => array(
 657                          '1.5'                       => true,
 658                          '3.0'                       => true,
 659                          '4'                         => true,
 660                          '10'                        => true,
 661                          '15'                        => true,
 662                          '18'                        => true,
 663                          '19'                        => true,
 664                          '33'                        => true,
 665                      ),
 666  
 667                      'is_gecko'                      => true,
 668                      'check_gecko_version'           => array(
 669                          '1'                         => true,
 670                          '2'                         => true,
 671                          '20030516'                  => true,
 672                          '20051116'                  => true,
 673                          '2006010100'                => true,
 674                          '3.6'                       => true,
 675                          '4.0'                       => true,
 676                          '15.0'                      => true,
 677                          '18.0'                      => true,
 678                          '19.0'                      => true,
 679                          '20100101'                  => true,
 680                      ),
 681  
 682                      'versionclasses'                => array(
 683                          'gecko',
 684                      ),
 685                  ),
 686              ),
 687  
 688              // SeaMonkey 2.0; Windows.
 689              array(
 690                  'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1b3pre) Gecko/20081208 SeaMonkey/2.0',
 691                  array(
 692                      'is_gecko'                      => true,
 693                      'check_gecko_version'           => array(
 694                          '1'                         => true,
 695                          '2'                         => true,
 696                          '20030516'                  => true,
 697                          '20051106'                  => true,
 698                          '20051116'                  => true,
 699                          '2006010100'                => true,
 700                      ),
 701  
 702                      'versionclasses'                => array(
 703                          'gecko',
 704                          'gecko19',
 705                      ),
 706                  ),
 707              ),
 708  
 709              // SeaMonkey 2.1; Linux.
 710              array(
 711                  'Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20110609 Firefox/4.0.1 SeaMonkey/2.1',
 712                  array(
 713                      'is_gecko'                      => true,
 714                      'check_gecko_version'           => array(
 715                          '1'                         => true,
 716                          '2'                         => true,
 717                          '20030516'                  => true,
 718                          '20051116'                  => true,
 719                          '2006010100'                => true,
 720                          '20100101'                  => true,
 721                          '3.6'                       => true,
 722                          '4.0'                       => true,
 723                      ),
 724  
 725                      'is_firefox'                    => true,
 726                      'check_firefox_version'         => array(
 727                          '1.5'                       => true,
 728                          '3.0'                       => true,
 729                          '4'                         => true,
 730                      ),
 731  
 732                      'versionclasses'                => array(
 733                          'gecko',
 734                          'gecko20',
 735                      ),
 736                  ),
 737              ),
 738  
 739              // SeaMonkey 2.3; FreeBSD.
 740              array(
 741                  'Mozilla/5.0 (X11; FreeBSD amd64; rv:6.0) Gecko/20110818 Firefox/6.0 SeaMonkey/2.3',
 742                  array(
 743                      'is_gecko'                      => true,
 744                      'check_gecko_version'           => array(
 745                          '1'                         => true,
 746                          '2'                         => true,
 747                          '20030516'                  => true,
 748                          '20051116'                  => true,
 749                          '2006010100'                => true,
 750                          '20100101'                  => true,
 751                          '3.6'                       => true,
 752                          '4.0'                       => true,
 753                      ),
 754  
 755                      'is_firefox'                    => true,
 756                      'check_firefox_version'         => array(
 757                          '1.5'                       => true,
 758                          '3.0'                       => true,
 759                          '4'                         => true,
 760                      ),
 761  
 762                      'versionclasses'                => array(
 763                          'gecko',
 764                      ),
 765                  ),
 766              ),
 767  
 768              // Windows 7; MS Word 2010.
 769              array(
 770                  'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E; ms-office)',
 771                  array(
 772                      'is_ie'                         => true,
 773                      'check_ie_version'              => array(
 774                          '0'                         => true,
 775                          '5.0'                       => true,
 776                          '5.5'                       => true,
 777                          '6.0'                       => true,
 778                          '7.0'                       => true,
 779                          '8.0'                       => true,
 780                      ),
 781                      'iecompatibility'               => true,
 782                      'versionclasses'                => array(
 783                          'ie',
 784                          'ie8',
 785                      ),
 786  
 787                      'is_msword'                     => true,
 788  
 789                      'supports_svg'                  => false,
 790                      'supports_json_contenttype'     => false,
 791                  ),
 792              ),
 793  
 794              // Windows 7; MS Outlook 2010.
 795              array(
 796                  'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E; Microsoft Outlook 14.0.7113; ms-office; MSOffice 14)',
 797                  array(
 798                      'is_ie'                         => true,
 799                      'check_ie_version'              => array(
 800                          '0'                         => true,
 801                          '5.0'                       => true,
 802                          '5.5'                       => true,
 803                          '6.0'                       => true,
 804                          '7.0'                       => true,
 805                          '8.0'                       => true,
 806                      ),
 807                      'iecompatibility'               => true,
 808                      'versionclasses'                => array(
 809                          'ie',
 810                          'ie8',
 811                      ),
 812  
 813                      // Note: Outlook is deliberately not considered to be MS Word.
 814                      'is_msword'                     => false,
 815  
 816                      'supports_svg'                  => false,
 817                      'supports_json_contenttype'     => false,
 818                  ),
 819              ),
 820  
 821              // Mac OS X; MS Word 14.
 822              array(
 823                  'Mozilla/5.0 (Macintosh; Intel Mac OS X) Word/14.38.0',
 824                  array(
 825                      'versionclasses'                => array(
 826                      ),
 827  
 828                      'is_msword'                     => true,
 829                  ),
 830              ),
 831  
 832              // Safari 312; Max OS X.
 833              array(
 834                  'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/312.1 (KHTML, like Gecko) Safari/312',
 835                  array(
 836                      'is_safari'                     => true,
 837                      'check_safari_version'          => array(
 838                          '1'                         => true,
 839                          '312'                       => true,
 840                      ),
 841  
 842                      'is_webkit'                     => true,
 843  
 844                      'versionclasses'                => array(
 845                          'safari',
 846                      ),
 847                  ),
 848              ),
 849  
 850              // Safari 412; Max OS X.
 851              array(
 852                  'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412 (KHTML, like Gecko) Safari/412',
 853                  array(
 854                      'is_safari'                     => true,
 855                      'check_safari_version'          => array(
 856                          '1'                         => true,
 857                          '312'                       => true,
 858                      ),
 859  
 860                      'is_webkit'                     => true,
 861  
 862                      'versionclasses'                => array(
 863                          'safari',
 864                      ),
 865                  ),
 866              ),
 867  
 868              // Safari 2.0; Max OS X.
 869              array(
 870                  'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412 (KHTML, like Gecko) Safari/412',
 871                  array(
 872                      'is_safari'                     => true,
 873                      'check_safari_version'          => array(
 874                          '1'                         => true,
 875                          '312'                       => true,
 876                      ),
 877  
 878                      'is_webkit'                     => true,
 879  
 880                      'versionclasses'                => array(
 881                          'safari',
 882                      ),
 883                  ),
 884              ),
 885  
 886              // iOS Safari 528; iPhone.
 887              array(
 888                  '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',
 889                  array(
 890                      // Note: We do *not* identify mobile Safari as Safari.
 891                      'is_safari_ios'                 => true,
 892                      'is_ios'                        => true,
 893                      'check_safari_ios_version'      => array(
 894                          '527'                       => true,
 895                      ),
 896  
 897                      'is_webkit'                     => true,
 898  
 899                      'versionclasses'                => array(
 900                          'ios'
 901                      ),
 902  
 903                      'devicetype'                    => 'mobile',
 904                 ),
 905              ),
 906  
 907              // Safari; iPhone 6 Plus; iOS 8.1; Build 12B411.
 908              array(
 909                  'Mozilla/5.0 (iPhone; CPU iPhone OS 10_10 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B411 Safari/600.1.4',
 910                  array(
 911                      // Note: We do *not* identify mobile Safari as Safari.
 912                      'is_safari_ios'                 => true,
 913                      'is_ios'                        => true,
 914                      'check_safari_ios_version'      => array(
 915                          '527'                       => true,
 916                          '590'                       => true,
 917                          '600'                       => true,
 918                      ),
 919  
 920                      'is_webkit'                     => true,
 921  
 922                      'versionclasses'                => array(
 923                          'ios',
 924                      ),
 925  
 926                      'devicetype'                    => 'mobile',
 927                 ),
 928              ),
 929  
 930              // iOS Safari 533; iPad.
 931              array(
 932                  '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',
 933                  array(
 934                      // Note: We do *not* identify mobile Safari as Safari.
 935                      'is_safari_ios'                 => true,
 936                      'is_ios'                        => true,
 937                      'check_safari_ios_version'      => array(
 938                          '527'                       => true,
 939                      ),
 940  
 941                      'is_webkit'                     => true,
 942  
 943                      'versionclasses'                => array(
 944                          'ios',
 945                      ),
 946  
 947                      'devicetype'                    => 'tablet',
 948                 ),
 949              ),
 950  
 951              // Android WebKit 525; G1 Phone.
 952              'Android WebKit 525; G1 Phone' => array(
 953                  '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',
 954                  array(
 955                      'is_webkit_android'             => true,
 956                      'check_webkit_android_version'  => array(
 957                          '525'                       => true,
 958                      ),
 959  
 960                      'is_webkit'                     => true,
 961  
 962                      'versionclasses'                => array(
 963                          'android',
 964                      ),
 965  
 966                      'devicetype'                    => 'mobile',
 967  
 968                      'supports_svg'                  => false,
 969                 ),
 970              ),
 971  
 972              // Android WebKit 530; Nexus.
 973              'Android WebKit 530; Nexus' => array(
 974                  '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',
 975                  array(
 976                      'is_webkit_android'             => true,
 977                      'check_webkit_android_version'  => array(
 978                          '525'                       => true,
 979                          '527'                       => true,
 980                      ),
 981  
 982                      'is_webkit'                     => true,
 983  
 984                      'versionclasses'                => array(
 985                          'android',
 986                      ),
 987  
 988                      'devicetype'                    => 'mobile',
 989  
 990                      'supports_svg'                  => false,
 991                 ),
 992              ),
 993  
 994              // Android WebKit 537; Samsung GT-9505.
 995              array(
 996                  'Mozilla/5.0 (Linux; Android 4.3; it-it; SAMSUNG GT-I9505/I9505XXUEMJ7 Build/JSS15J) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.5 Chrome/28.0.1500.94 Mobile Safari/537.36',
 997                  array(
 998                      'is_webkit_android'             => true,
 999                      'check_webkit_android_version'  => array(
1000                          '525'                       => true,
1001                          '527'                       => true,
1002                      ),
1003  
1004                      'is_webkit'                     => true,
1005  
1006                      'is_chrome'                     => true,
1007                      'check_chrome_version'          => array(
1008                          '7'                         => true,
1009                          '8'                         => true,
1010                          '10'                        => true,
1011                      ),
1012  
1013                      'versionclasses'                => array(
1014                          'chrome',
1015                          'android',
1016                      ),
1017  
1018                      'devicetype'                    => 'mobile',
1019                  ),
1020              ),
1021  
1022              // Android WebKit 537; Nexus 5.
1023              array(
1024                  'Mozilla/5.0 (Linux; Android 5.0; Nexus 5 Build/LPX13D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.102 Mobile Safari/537.36',
1025                  array(
1026                      'is_webkit_android'             => true,
1027                      'check_webkit_android_version'  => array(
1028                          '525'                       => true,
1029                          '527'                       => true,
1030                      ),
1031  
1032                      'is_webkit'                     => true,
1033  
1034                      'is_chrome'                     => true,
1035                      'check_chrome_version'          => array(
1036                          '7'                         => true,
1037                          '8'                         => true,
1038                          '10'                        => true,
1039                      ),
1040  
1041                      'versionclasses'                => array(
1042                          'chrome',
1043                          'android',
1044                      ),
1045  
1046                      'devicetype'                    => 'mobile',
1047                  ),
1048              ),
1049  
1050              // Chrome 8; Mac OS X.
1051              array(
1052                  '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',
1053                  array(
1054                      'is_chrome'                     => true,
1055                      'check_chrome_version'          => array(
1056                          '7'                         => true,
1057                          '8'                         => true,
1058                      ),
1059  
1060                      'is_webkit'                     => true,
1061  
1062                      'versionclasses'                => array(
1063                          'chrome',
1064                      ),
1065                  ),
1066              ),
1067  
1068              // Chrome 39; Mac OS X.
1069              array(
1070                  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36',
1071                  array(
1072                      'is_chrome'                     => true,
1073                      'check_chrome_version'          => array(
1074                          '7'                         => true,
1075                          '8'                         => true,
1076                          '10'                        => true,
1077                          '39'                        => true,
1078                      ),
1079  
1080                      'is_webkit'                     => true,
1081  
1082                      'versionclasses'                => array(
1083                          'chrome',
1084                      ),
1085                  ),
1086              ),
1087  
1088              // Opera 8.51; Windows XP.
1089              array(
1090                  'Opera/8.51 (Windows NT 5.1; U; en)',
1091                  array(
1092                      'is_opera'                      => true,
1093                      'check_opera_version'           => array(
1094                          '8.0'                       => true,
1095                      ),
1096  
1097                      'versionclasses'                => array(
1098                          'opera',
1099                      ),
1100  
1101                      'supports_svg'                  => false,
1102                 ),
1103              ),
1104  
1105              // Opera 9.0; Windows XP.
1106              array(
1107                  'Opera/9.0 (Windows NT 5.1; U; en)',
1108                  array(
1109                      'is_opera'                      => true,
1110                      'check_opera_version'           => array(
1111                          '8.0'                       => true,
1112                          '9.0'                       => true,
1113                      ),
1114  
1115                      'versionclasses'                => array(
1116                          'opera',
1117                      ),
1118  
1119                      'supports_svg'                  => false,
1120                 ),
1121              ),
1122  
1123              // Opera 12.15 (Build 1748); Mac OS X.
1124              array(
1125                  'Opera/9.80 (Macintosh; Intel Mac OS X 10.10.0; Edition MAS) Presto/2.12.388 Version/12.15',
1126                  array(
1127                      'is_opera'                      => true,
1128                      'check_opera_version'           => array(
1129                          '8.0'                       => true,
1130                          '9.0'                       => true,
1131                          '10.0'                      => true,
1132                          '12.15'                     => true,
1133                      ),
1134  
1135                      'versionclasses'                => array(
1136                          'opera',
1137                      ),
1138  
1139                      'supports_svg'                  => false,
1140                 ),
1141              ),
1142  
1143              // Opera 9.0; Debian Linux.
1144              array(
1145                  'Opera/9.01 (X11; Linux i686; U; en)',
1146                  array(
1147                      'is_opera'                      => true,
1148                      'check_opera_version'           => array(
1149                          '8.0'                       => true,
1150                          '9.0'                       => true,
1151                      ),
1152  
1153                      'versionclasses'                => array(
1154                          'opera',
1155                      ),
1156  
1157                      'supports_svg'                  => false,
1158                 ),
1159              ),
1160  
1161              // Google web crawlers.
1162              array(
1163                  'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
1164                  array(
1165                      'is_web_crawler'                => true,
1166                      'versionclasses'                => array(
1167                      ),
1168                 ),
1169              ),
1170              array(
1171                  'Googlebot/2.1 (+http://www.googlebot.com/bot.html)',
1172                  array(
1173                      'is_web_crawler'                => true,
1174                      'versionclasses'                => array(
1175                      ),
1176                 ),
1177              ),
1178              array(
1179                  'Googlebot-Image/1.0',
1180                  array(
1181                      'is_web_crawler'                => true,
1182                      'versionclasses'                => array(
1183                      ),
1184                 ),
1185              ),
1186  
1187              // Yahoo crawlers.
1188              // See https://help.yahoo.com/kb/slurp-crawling-page-sln22600.html.
1189              array(
1190                  'Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)',
1191                  array(
1192                      'is_web_crawler'                => true,
1193                      'versionclasses'                => array(
1194                      ),
1195                 ),
1196              ),
1197  
1198              // Bing / MSN / AdIdx crawlers.
1199              // See http://www.bing.com/webmaster/help/which-crawlers-does-bing-use-8c184ec0.
1200              array(
1201                  'Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)',
1202                  array(
1203                      'is_web_crawler'                => true,
1204                      'versionclasses'                => array(
1205                      ),
1206                 ),
1207              ),
1208              array(
1209                  'Mozilla/5.0 (compatible; bingbot/2.0 +http://www.bing.com/bingbot.htm)',
1210                  array(
1211                      'is_web_crawler'                => true,
1212                      'versionclasses'                => array(
1213                      ),
1214                 ),
1215              ),
1216              array(
1217                  'Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)',
1218                  array(
1219                      'is_web_crawler'                => true,
1220                      'is_webkit'                     => true,
1221                      'is_safari_ios'                 => true,
1222                      'is_ios'                        => true,
1223                      'check_safari_ios_version'      => array(
1224                          '527'                       => true,
1225                      ),
1226  
1227                      'versionclasses'                => array(
1228                          'ios',
1229                      ),
1230  
1231                      'devicetype'                    => 'mobile',
1232                 ),
1233              ),
1234              array(
1235                  'Mozilla/5.0 (Windows Phone 8.1; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 530) like Gecko (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)',
1236                  array(
1237                      'is_web_crawler'                => true,
1238                      'is_ie'                         => true,
1239                      'check_ie_version'              => array(
1240                          '0'                         => true,
1241                          '5.0'                       => true,
1242                          '5.5'                       => true,
1243                          '6.0'                       => true,
1244                          '7.0'                       => true,
1245                          '8.0'                       => true,
1246                          '9.0'                       => true,
1247                          '10'                        => true,
1248                          '11'                        => true,
1249                      ),
1250                      'versionclasses'                => array(
1251                          'ie',
1252                          'ie11',
1253                      ),
1254                      'devicetype'                    => 'mobile',
1255                 ),
1256              ),
1257  
1258              array(
1259                  'msnbot/2.0b (+http://search.msn.com/msnbot.htm)',
1260                  array(
1261                      'is_web_crawler'                => true,
1262                      'versionclasses'                => array(
1263                      ),
1264                 ),
1265              ),
1266              array(
1267                  'msnbot/2.1',
1268                  array(
1269                      'is_web_crawler'                => true,
1270                      'versionclasses'                => array(
1271                      ),
1272                 ),
1273              ),
1274              array(
1275                  'msnbot-media/1.1 (+http://search.msn.com/msnbot.htm)',
1276                  array(
1277                      'is_web_crawler'                => true,
1278                      'versionclasses'                => array(
1279                      ),
1280                 ),
1281              ),
1282              array(
1283                  'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534+ (KHTML, like Gecko) BingPreview/1.0b',
1284                  array(
1285                      'is_web_crawler'                => true,
1286                      'is_webkit'                     => true,
1287                      'is_safari'                     => true,
1288                      'check_safari_version'          => array(
1289                          '1'                         => true,
1290                          '312'                       => true,
1291                          '500'                       => true,
1292                      ),
1293  
1294                      'versionclasses'                => array(
1295                          'safari',
1296                      ),
1297                 ),
1298              ),
1299              array(
1300                  'Mozilla/5.0 (Windows Phone 8.1; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 530) like Gecko BingPreview/1.0b',
1301                  array(
1302                      'is_web_crawler'                => true,
1303                      'is_ie'                         => true,
1304                      'check_ie_version'              => array(
1305                          '0'                         => true,
1306                          '5.0'                       => true,
1307                          '5.5'                       => true,
1308                          '6.0'                       => true,
1309                          '7.0'                       => true,
1310                          '8.0'                       => true,
1311                          '9.0'                       => true,
1312                          '10'                        => true,
1313                          '11'                        => true,
1314                      ),
1315                      'versionclasses'                => array(
1316                          'ie',
1317                          'ie11',
1318                      ),
1319                      'devicetype'                    => 'mobile',
1320                 ),
1321              ),
1322  
1323              // Yandex.
1324              // See http://help.yandex.com/search/robots/agent.xml.
1325              array(
1326                  'Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)',
1327                  array(
1328                      'is_web_crawler'                => true,
1329                      'versionclasses'                => array(
1330                      ),
1331                 ),
1332              ),
1333              array(
1334                  'Mozilla/5.0 (compatible; YandexImages/3.0; +http://yandex.com/bots)',
1335                  array(
1336                      'is_web_crawler'                => true,
1337                      'versionclasses'                => array(
1338                      ),
1339                 ),
1340              ),
1341  
1342              // AltaVista.
1343              array(
1344                  'AltaVista V2.0B crawler@evreka.com',
1345                  array(
1346                      'is_web_crawler'                => true,
1347                      'versionclasses'                => array(
1348                      ),
1349                 ),
1350              ),
1351  
1352              // ZoomSpider.
1353              array(
1354                  'ZoomSpider - wrensoft.com [ZSEBOT]',
1355                  array(
1356                      'is_web_crawler'                => true,
1357                      'versionclasses'                => array(
1358                      ),
1359                 ),
1360              ),
1361  
1362              // Baidu.
1363              array(
1364                  'Baiduspider+(+http://www.baidu.com/search/spider_jp.html)',
1365                  array(
1366                      'is_web_crawler'                => true,
1367                      'versionclasses'                => array(
1368                      ),
1369                 ),
1370              ),
1371              array(
1372                  'Baiduspider+(+http://www.baidu.com/search/spider.htm)',
1373                  array(
1374                      'is_web_crawler'                => true,
1375                      'versionclasses'                => array(
1376                      ),
1377                 ),
1378              ),
1379  
1380              // Ask.com.
1381              array(
1382                  'User-Agent: Mozilla/2.0 (compatible; Ask Jeeves/Teoma)',
1383                  array(
1384                      'is_web_crawler'                => true,
1385                      'versionclasses'                => array(
1386                      ),
1387                 ),
1388              ),
1389  
1390              // MoodleBot.
1391              array(
1392                  'User-Agent: MoodleBot/3.8 (+https://moodle.org)',
1393                  array(
1394                      'is_web_crawler'                => true,
1395                      'versionclasses'                => array(
1396                      ),
1397                 ),
1398              ),
1399  
1400              // Macos Desktop app.
1401              array(
1402                  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) moodlemobile/3.6.0 Chrome/69.0.3497.106 Electron/4.0.1 Safari/537.36 MoodleMobile',
1403                  array(
1404                      'is_moodle_app'                => true,
1405                      'is_webkit'                    => true,
1406                      'is_chrome'                    => true,
1407                      'check_chrome_version'         => array(
1408                          '7'                        => true,
1409                          '8'                        => true,
1410                          '10'                       => true,
1411                          '39'                       => true,
1412                      ),
1413                      'versionclasses'               => array(
1414                          'chrome',
1415                      ),
1416                 ),
1417              ),
1418  
1419              // Linux Desktop app.
1420              array(
1421                  'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) moodledesktop/3.6.0 Chrome/69.0.3497.106 Electron/4.0.1 Safari/537.36 MoodleMobile',
1422                  array(
1423                      'is_moodle_app'                => true,
1424                      'is_webkit'                    => true,
1425                      'is_chrome'                    => true,
1426                      'check_chrome_version'         => array(
1427                          '7'                        => true,
1428                          '8'                        => true,
1429                          '10'                       => true,
1430                          '39'                       => true,
1431                      ),
1432                      'versionclasses'               => array(
1433                          'chrome',
1434                      ),
1435                 ),
1436              ),
1437  
1438              // Windows Desktop app.
1439              array(
1440                  'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) moodledesktop/3.6.0 Chrome/69.0.3497.106 Electron/4.0.1 Safari/537.36 MoodleMobile',
1441                  array(
1442                      'is_moodle_app'                => true,
1443                      'is_webkit'                    => true,
1444                      'is_chrome'                    => true,
1445                      'check_chrome_version'         => array(
1446                          '7'                        => true,
1447                          '8'                        => true,
1448                          '10'                       => true,
1449                          '39'                       => true,
1450                      ),
1451                      'versionclasses'               => array(
1452                          'chrome',
1453                      ),
1454                 ),
1455              ),
1456  
1457              // Android app.
1458              array(
1459                  'Mozilla/5.0 (Linux; Android 7.1.1; Moto G Play Build/NPIS26.48-43-2; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/71.0.3578.99 Mobile Safari/537.36 MoodleMobile',
1460                  array(
1461                      'is_moodle_app'                => true,
1462                      'is_webkit'                    => true,
1463                      'is_webkit_android'            => true,
1464                      'is_chrome'                    => true,
1465                      'check_chrome_version'         => array(
1466                          '7'                        => true,
1467                          '8'                        => true,
1468                          '10'                       => true,
1469                          '39'                       => true,
1470                      ),
1471                      'devicetype'                   => 'mobile',
1472                      'check_webkit_android_version' => array(
1473                          '525'                       => true,
1474                          '527'                       => true,
1475                      ),
1476                      'versionclasses'               => array(
1477                          'android',
1478                          'chrome'
1479                      ),
1480                 ),
1481              ),
1482  
1483              // Android app, user agent lower case.
1484              array(
1485                  'Mozilla/5.0 (Linux; Android 7.1.1; Moto G Play Build/NPIS26.48-43-2; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/71.0.3578.99 Mobile Safari/537.36 moodlemobile',
1486                  array(
1487                      'is_moodle_app'                => true,
1488                      'is_webkit'                    => true,
1489                      'is_webkit_android'            => true,
1490                      'is_chrome'                    => true,
1491                      'check_chrome_version'         => array(
1492                          '7'                        => true,
1493                          '8'                        => true,
1494                          '10'                       => true,
1495                          '39'                       => true,
1496                      ),
1497                      'devicetype'                   => 'mobile',
1498                      'check_webkit_android_version' => array(
1499                          '525'                       => true,
1500                          '527'                       => true,
1501                      ),
1502                      'versionclasses'               => array(
1503                          'android',
1504                          'chrome'
1505                      ),
1506                 ),
1507              ),
1508  
1509              // iOS (iPhone) app.
1510              array(
1511                  'Mozilla/5.0 (iPhone; CPU OS 13_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Mobile/14G60 MoodleMobile',
1512                  array(
1513                      'is_moodle_app'                => true,
1514                      'is_ios'                       => true,
1515                      'is_webkit'                    => true,
1516                      'devicetype'                   => 'mobile',
1517                      'versionclasses'               => array(
1518                      ),
1519                 ),
1520              ),
1521  
1522              // iOS (iPad) app.
1523              array(
1524                  'Mozilla/5.0 (iPad; CPU OS 12_1_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16D39 MoodleMobile',
1525                  array(
1526                      'is_moodle_app'                => true,
1527                      'is_ios'                       => true,
1528                      'is_webkit'                    => true,
1529                      'devicetype'                   => 'tablet',
1530                      'versionclasses'               => array(
1531                      ),
1532                 ),
1533              ),
1534          );
1535      }
1536  
1537      /**
1538       * Test instance generation.
1539       */
1540      public function test_instance() {
1541          $this->assertInstanceOf('core_useragent', core_useragent::instance());
1542          $this->assertInstanceOf('core_useragent', core_useragent::instance(true));
1543      }
1544  
1545      /**
1546       * @dataProvider user_agents_providers
1547       */
1548      public function test_useragent_edge($useragent, $tests) {
1549          // Setup the core_useragent instance.
1550          core_useragent::instance(true, $useragent);
1551  
1552          // Edge Tests.
1553          if (isset($tests['is_edge']) && $tests['is_edge']) {
1554              $this->assertTrue(core_useragent::is_edge());
1555          } else {
1556              $this->assertFalse(core_useragent::is_edge());
1557          }
1558  
1559          $versions = array(
1560              // New versions of should be added here.
1561              '12'   => false,
1562          );
1563  
1564          if (isset($tests['check_edge_version'])) {
1565              // The test provider has overwritten some of the above checks.
1566              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1567              $versions = $tests['check_edge_version'] + $versions;
1568          }
1569  
1570          foreach ($versions as $version => $result) {
1571              $this->assertEquals($result, core_useragent::check_edge_version($version),
1572                  "Version incorrectly determined for Edge version '{$version}'");
1573          }
1574      }
1575  
1576      /**
1577       * @dataProvider user_agents_providers
1578       */
1579      public function test_useragent_ie($useragent, $tests) {
1580          // Setup the core_useragent instance.
1581          core_useragent::instance(true, $useragent);
1582  
1583          // IE Tests.
1584          if (isset($tests['is_ie']) && $tests['is_ie']) {
1585              $this->assertTrue(core_useragent::is_ie());
1586          } else {
1587              $this->assertFalse(core_useragent::is_ie());
1588          }
1589  
1590          $versions = array(
1591              // New versions of should be added here.
1592              '0'    => false,
1593              '5.0'  => false,
1594              '5.5'  => false,
1595              '6.0'  => false,
1596              '7.0'  => false,
1597              '8.0'  => false,
1598              '9.0'  => false,
1599              '10'   => false,
1600              '11'   => false,
1601              '12'   => false,
1602              '13'   => false,
1603              '14'   => false,
1604          );
1605  
1606          if (isset($tests['check_ie_version'])) {
1607              // The test provider has overwritten some of the above checks.
1608              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1609              $versions = $tests['check_ie_version'] + $versions;
1610          }
1611  
1612          foreach ($versions as $version => $result) {
1613              $this->assertEquals($result, core_useragent::check_ie_version($version),
1614                  "Version incorrectly determined for IE version '{$version}'");
1615          }
1616  
1617          // IE Compatibility mode.
1618          if (isset($tests['iecompatibility']) && $tests['iecompatibility']) {
1619              $this->assertTrue(core_useragent::check_ie_compatibility_view(), "IE Compability false negative");
1620          } else {
1621              $this->assertFalse(core_useragent::check_ie_compatibility_view(), "IE Compability false positive");
1622          }
1623  
1624      }
1625  
1626      /**
1627       * @dataProvider user_agents_providers
1628       */
1629      public function test_useragent_msword($useragent, $tests) {
1630          // Setup the core_useragent instance.
1631          core_useragent::instance(true, $useragent);
1632  
1633          // MSWord Tests.
1634          if (isset($tests['is_msword']) && $tests['is_msword']) {
1635              $this->assertTrue(core_useragent::is_msword());
1636          } else {
1637              $this->assertFalse(core_useragent::is_msword());
1638          }
1639      }
1640  
1641  
1642      /**
1643       * @dataProvider user_agents_providers
1644       */
1645      public function test_useragent_supports($useragent, $tests) {
1646          // Setup the core_useragent instance.
1647          core_useragent::instance(true, $useragent);
1648  
1649          // Supports SVG.
1650          if (!isset($tests['supports_svg']) || $tests['supports_svg']) {
1651              $this->assertTrue(core_useragent::supports_svg(),
1652                  "SVG Support was not reported (and should have been)");
1653          } else {
1654              $this->assertFalse(core_useragent::supports_svg(),
1655                  "SVG Support was reported (and should not have been)");
1656          }
1657  
1658          // Supports JSON ContentType.
1659          if (!isset($tests['supports_json_contenttype']) || $tests['supports_json_contenttype']) {
1660              $this->assertTrue(core_useragent::supports_json_contenttype(),
1661                  "JSON ContentType Support was not reported (and should have been)");
1662          } else {
1663              $this->assertFalse(core_useragent::supports_json_contenttype(),
1664                  "JSON ContentType Support was reported (and should not have been)");
1665          }
1666      }
1667  
1668      /**
1669       * @dataProvider user_agents_providers
1670       */
1671      public function test_useragent_webkit($useragent, $tests) {
1672          // Setup the core_useragent instance.
1673          core_useragent::instance(true, $useragent);
1674  
1675          if (isset($tests['is_webkit']) && $tests['is_webkit']) {
1676              $this->assertTrue(core_useragent::is_webkit(),
1677                  "Browser was not identified as a webkit browser");
1678              $this->assertTrue(core_useragent::check_webkit_version());
1679          } else {
1680              $this->assertFalse(core_useragent::is_webkit(),
1681                  "Browser was incorrectly identified as a webkit browser");
1682              $this->assertFalse(core_useragent::check_webkit_version());
1683          }
1684  
1685          $versions = array(
1686              // New versions should be added here.
1687          );
1688  
1689          if (isset($tests['check_webkit_version'])) {
1690              // The test provider has overwritten some of the above checks.
1691              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1692              $versions = $tests['check_webkit_version'] + $versions;
1693          }
1694  
1695          foreach ($versions as $version => $result) {
1696              $this->assertEquals($result, core_useragent::check_webkit_version($version),
1697                  "Version incorrectly determined for Webkit version '{$version}'");
1698          }
1699      }
1700  
1701      /**
1702       * @dataProvider user_agents_providers
1703       */
1704      public function test_useragent_webkit_android($useragent, $tests) {
1705          // Setup the core_useragent instance.
1706          core_useragent::instance(true, $useragent);
1707  
1708          if (isset($tests['is_webkit_android']) && $tests['is_webkit_android']) {
1709              $this->assertTrue(core_useragent::is_webkit_android(),
1710                  "Browser was not identified as an Android webkit browser");
1711              $this->assertTrue(core_useragent::check_webkit_android_version());
1712          } else {
1713              $this->assertFalse(core_useragent::is_webkit_android(),
1714                  "Browser was incorrectly identified as an Android webkit browser");
1715              $this->assertFalse(core_useragent::check_webkit_android_version());
1716          }
1717  
1718          $versions = array(
1719              // New versions should be added here.
1720              '525'       => false,
1721              '527'       => false,
1722              '590'       => false,
1723          );
1724  
1725          if (isset($tests['check_webkit_android_version'])) {
1726              // The test provider has overwritten some of the above checks.
1727              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1728              $versions = $tests['check_webkit_android_version'] + $versions;
1729          }
1730  
1731          foreach ($versions as $version => $result) {
1732              $this->assertEquals($result, core_useragent::check_webkit_android_version($version),
1733                  "Version incorrectly determined for Android webkit version '{$version}'");
1734          }
1735      }
1736  
1737      /**
1738       * @dataProvider user_agents_providers
1739       */
1740      public function test_useragent_chrome($useragent, $tests) {
1741          // Setup the core_useragent instance.
1742          core_useragent::instance(true, $useragent);
1743  
1744          if (isset($tests['is_chrome']) && $tests['is_chrome']) {
1745              $this->assertTrue(core_useragent::is_chrome(),
1746                  "Browser was not identified as a chrome browser");
1747              $this->assertTrue(core_useragent::check_chrome_version());
1748          } else {
1749              $this->assertFalse(core_useragent::is_chrome(),
1750                  "Browser was incorrectly identified as a chrome browser");
1751              $this->assertFalse(core_useragent::check_chrome_version());
1752          }
1753  
1754          $versions = array(
1755              // New versions should be added here.
1756              '7'         => false,
1757              '8'         => false,
1758              '10'        => false,
1759              '39'        => false,
1760          );
1761  
1762          if (isset($tests['check_chrome_version'])) {
1763              // The test provider has overwritten some of the above checks.
1764              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1765              $versions = $tests['check_chrome_version'] + $versions;
1766          }
1767  
1768          foreach ($versions as $version => $result) {
1769              $this->assertEquals($result, core_useragent::check_chrome_version($version),
1770                  "Version incorrectly determined for Chrome version '{$version}'");
1771          }
1772      }
1773  
1774      /**
1775       * @dataProvider user_agents_providers
1776       */
1777      public function test_useragent_safari($useragent, $tests) {
1778          // Setup the core_useragent instance.
1779          core_useragent::instance(true, $useragent);
1780  
1781          if (isset($tests['is_safari']) && $tests['is_safari']) {
1782              $this->assertTrue(core_useragent::is_safari(),
1783                  "Browser was not identified as a safari browser");
1784              $this->assertTrue(core_useragent::check_safari_version());
1785          } else {
1786              $this->assertFalse(core_useragent::is_safari(),
1787                  "Browser was incorrectly identified as a safari browser");
1788              $this->assertFalse(core_useragent::check_safari_version());
1789          }
1790  
1791          // Check Safari (generic).
1792          $versions = array(
1793              // New versions should be added here.
1794              '1'         => false,
1795              '312'       => false,
1796              '500'       => false,
1797          );
1798  
1799          if (isset($tests['check_safari_version'])) {
1800              // The test provider has overwritten some of the above checks.
1801              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1802              $versions = $tests['check_safari_version'] + $versions;
1803          }
1804  
1805          foreach ($versions as $version => $result) {
1806              $this->assertEquals($result, core_useragent::check_safari_version($version),
1807                  "Version incorrectly determined for Safari (generic) version '{$version}'");
1808          }
1809      }
1810  
1811      /**
1812       * @dataProvider user_agents_providers
1813       */
1814      public function test_useragent_ios_safari($useragent, $tests) {
1815          // Setup the core_useragent instance.
1816          core_useragent::instance(true, $useragent);
1817  
1818          if (isset($tests['is_safari_ios']) && $tests['is_safari_ios']) {
1819              $this->assertTrue(core_useragent::is_safari_ios(),
1820                  "Browser was not identified as an iOS safari browser");
1821              $this->assertTrue(core_useragent::check_safari_ios_version());
1822          } else {
1823              $this->assertFalse(core_useragent::is_safari_ios(),
1824                  "Browser was incorrectly identified as an iOS safari browser");
1825              $this->assertFalse(core_useragent::check_safari_ios_version());
1826          }
1827  
1828          // Check iOS Safari.
1829          $versions = array(
1830              // New versions should be added here.
1831              '527'       => false,
1832              '590'       => false,
1833              '600'       => false,
1834          );
1835  
1836          if (isset($tests['check_safari_ios_version'])) {
1837              // The test provider has overwritten some of the above checks.
1838              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1839              $versions = $tests['check_safari_ios_version'] + $versions;
1840          }
1841  
1842          foreach ($versions as $version => $result) {
1843              $this->assertEquals($result, core_useragent::check_safari_ios_version($version),
1844                  "Version incorrectly determined for iOS Safari version '{$version}'");
1845          }
1846      }
1847  
1848      /**
1849       * @dataProvider user_agents_providers
1850       */
1851      public function test_useragent_ios($useragent, $tests) {
1852          // Setup the core_useragent instance.
1853          core_useragent::instance(true, $useragent);
1854  
1855          if (isset($tests['is_ios']) && $tests['is_ios']) {
1856              $this->assertTrue(core_useragent::is_ios(),
1857                  "Browser was not identified as an iOS device browser");
1858              // The iOS app is not Safari based.
1859              if (!isset($tests['is_moodle_app']) || !$tests['is_moodle_app']) {
1860                  $this->assertTrue(core_useragent::check_safari_ios_version());
1861              }
1862          } else {
1863              $this->assertFalse(core_useragent::is_ios(),
1864                  "Browser was incorrectly identified as an iOS device browser");
1865              $this->assertFalse(core_useragent::check_safari_ios_version());
1866          }
1867      }
1868  
1869      /**
1870       * @dataProvider user_agents_providers
1871       */
1872      public function test_useragent_gecko($useragent, $tests) {
1873          // Setup the core_useragent instance.
1874          core_useragent::instance(true, $useragent);
1875  
1876          if (isset($tests['is_gecko']) && $tests['is_gecko']) {
1877              $this->assertTrue(core_useragent::is_gecko(),
1878                  "Browser was not identified as a gecko browser");
1879              $this->assertTrue(core_useragent::check_gecko_version());
1880          } else {
1881              $this->assertFalse(core_useragent::is_gecko(),
1882                  "Browser was incorrectly identified as a gecko browser");
1883              $this->assertFalse(core_useragent::check_gecko_version());
1884          }
1885  
1886          $versions = array(
1887              // New versions should be added here.
1888              '1'             => false,
1889              '2'             => false,
1890              '3.6'           => false,
1891              '4.0'           => false,
1892              '20030516'      => false,
1893              '20051116'      => false,
1894              '2006010100'    => false,
1895              '20100101'      => false,
1896              '15.0'          => false,
1897              '18.0'          => false,
1898              '19.0'          => false,
1899          );
1900  
1901          if (isset($tests['check_gecko_version'])) {
1902              // The test provider has overwritten some of the above checks.
1903              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1904              $versions = $tests['check_gecko_version'] + $versions;
1905          }
1906  
1907          foreach ($versions as $version => $result) {
1908              $this->assertEquals($result, core_useragent::check_gecko_version($version),
1909                  "Version incorrectly determined for Gecko version '{$version}'");
1910          }
1911      }
1912  
1913      /**
1914       * @dataProvider user_agents_providers
1915       */
1916      public function test_useragent_firefox($useragent, $tests) {
1917          // Setup the core_useragent instance.
1918          core_useragent::instance(true, $useragent);
1919  
1920          if (isset($tests['is_firefox']) && $tests['is_firefox']) {
1921              $this->assertTrue(core_useragent::is_firefox(),
1922                  "Browser was not identified as a firefox browser");
1923              $this->assertTrue(core_useragent::check_firefox_version());
1924          } else {
1925              $this->assertFalse(core_useragent::is_firefox(),
1926                  "Browser was incorrectly identified as a firefox browser");
1927              $this->assertFalse(core_useragent::check_firefox_version());
1928          }
1929  
1930          $versions = array(
1931              // New versions should be added here.
1932              '1.5'       => false,
1933              '3.0'       => false,
1934              '4'         => false,
1935              '10'        => false,
1936              '15'        => false,
1937              '18'        => false,
1938              '19'        => false,
1939              '33'        => false,
1940          );
1941  
1942          if (isset($tests['check_firefox_version'])) {
1943              // The test provider has overwritten some of the above checks.
1944              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1945              $versions = $tests['check_firefox_version'] + $versions;
1946          }
1947  
1948          foreach ($versions as $version => $result) {
1949              $this->assertEquals($result, core_useragent::check_firefox_version($version),
1950                  "Version incorrectly determined for Firefox version '{$version}'");
1951          }
1952      }
1953  
1954      /**
1955       * @dataProvider user_agents_providers
1956       */
1957      public function test_useragent_opera($useragent, $tests) {
1958          // Setup the core_useragent instance.
1959          core_useragent::instance(true, $useragent);
1960  
1961          if (isset($tests['is_opera']) && $tests['is_opera']) {
1962              $this->assertTrue(core_useragent::is_opera(),
1963                  "Browser was not identified as a opera browser");
1964              $this->assertTrue(core_useragent::check_opera_version());
1965          } else {
1966              $this->assertFalse(core_useragent::is_opera(),
1967                  "Browser was incorrectly identified as a opera browser");
1968              $this->assertFalse(core_useragent::check_opera_version());
1969          }
1970  
1971          $versions = array(
1972              // New versions should be added here.
1973              '8.0'       => false,
1974              '9.0'       => false,
1975              '10.0'      => false,
1976              '12.15'     => false,
1977          );
1978  
1979          if (isset($tests['check_opera_version'])) {
1980              // The test provider has overwritten some of the above checks.
1981              // Must use the '+' operator, because array_merge will incorrectly rewrite the array keys for integer-based indexes.
1982              $versions = $tests['check_opera_version'] + $versions;
1983          }
1984  
1985          foreach ($versions as $version => $result) {
1986              $this->assertEquals($result, core_useragent::check_opera_version($version),
1987                  "Version incorrectly determined for Opera version '{$version}'");
1988          }
1989      }
1990  
1991      /**
1992       * @dataProvider user_agents_providers
1993       */
1994      public function test_get_device_type($useragent, $tests) {
1995          // Setup the core_useragent instance.
1996          core_useragent::instance(true, $useragent);
1997  
1998          $expected = 'default';
1999          if (isset($tests['devicetype'])) {
2000              $expected = $tests['devicetype'];
2001          }
2002  
2003          $this->assertEquals($expected, core_useragent::get_device_type(),
2004              "Device Type was not correctly identified");
2005      }
2006  
2007      /**
2008       * @dataProvider user_agents_providers
2009       */
2010      public function test_get_browser_version_classes($useragent, $tests) {
2011          // Setup the core_useragent instance.
2012          core_useragent::instance(true, $useragent);
2013  
2014          $actual = core_useragent::get_browser_version_classes();
2015          foreach ($tests['versionclasses'] as $expectedclass) {
2016              $this->assertContains($expectedclass, $actual);
2017          }
2018          $this->assertCount(count($tests['versionclasses']), $actual);
2019      }
2020  
2021      /**
2022       * @dataProvider user_agents_providers
2023       */
2024      public function test_useragent_web_crawler($useragent, $tests) {
2025          // Setup the core_useragent instance.
2026          core_useragent::instance(true, $useragent);
2027  
2028          $expectation = isset($tests['is_web_crawler']) ? $tests['is_web_crawler'] : false;
2029          $this->assertSame($expectation, core_useragent::is_web_crawler());
2030      }
2031  
2032      /**
2033       * @dataProvider user_agents_providers
2034       */
2035      public function test_useragent_moodle_app($useragent, $tests) {
2036          // Setup the core_useragent instance.
2037          core_useragent::instance(true, $useragent);
2038  
2039          $expectation = isset($tests['is_moodle_app']) ? $tests['is_moodle_app'] : false;
2040          $this->assertSame($expectation, core_useragent::is_moodle_app());
2041      }
2042  }