diff options
-rw-r--r-- | core/Tracker.php | 30 | ||||
-rw-r--r-- | libs/UserAgentParser/UserAgentParser.php | 9 | ||||
-rw-r--r-- | plugins/DevicesDetection/DevicesDetection.php | 4 | ||||
-rw-r--r-- | plugins/DevicesDetection/UserAgentParserEnhanced/UserAgentParserEnhanced.php | 1455 | ||||
-rw-r--r-- | plugins/DevicesDetection/UserAgentParserEnhanced/regexes/browsers.yml | 814 | ||||
-rw-r--r-- | plugins/DevicesDetection/UserAgentParserEnhanced/regexes/mobiles.yml | 1914 | ||||
-rw-r--r-- | plugins/DevicesDetection/UserAgentParserEnhanced/regexes/oss.yml | 852 | ||||
-rw-r--r-- | plugins/DevicesDetection/UserAgentParserEnhanced/spyc.php | 2090 | ||||
-rw-r--r-- | plugins/DevicesDetection/functions.php | 12 | ||||
-rw-r--r-- | plugins/DevicesDetection/lang/en.php | 2 | ||||
-rwxr-xr-x | tests/LocalTracker.php | 1 | ||||
-rw-r--r-- | tests/PHPUnit/Core/PluginsFunctions/WidgetsListTest.php | 8 | ||||
-rw-r--r-- | tests/PHPUnit/Core/SegmentTest.php | 5 | ||||
-rwxr-xr-x | tests/PHPUnit/IntegrationTestCase.php | 2 | ||||
-rwxr-xr-x | tests/PHPUnit/proxy/piwik.php | 7 |
15 files changed, 3622 insertions, 3583 deletions
diff --git a/core/Tracker.php b/core/Tracker.php index 89fa433836..625d7d2175 100644 --- a/core/Tracker.php +++ b/core/Tracker.php @@ -46,6 +46,7 @@ class Piwik_Tracker static protected $forcedVisitorId = null; static protected $pluginsNotToLoad = array(); + static protected $pluginsToLoad = array(); /** * The set of visits to track. @@ -126,6 +127,17 @@ class Piwik_Tracker return self::$pluginsNotToLoad; } + static public function getPluginsToLoad() + { + return self::$pluginsToLoad; + } + static public function setPluginsToLoad($plugins) + { + self::$pluginsToLoad = $plugins; + } + + + /** * Update Tracker config * @@ -357,6 +369,7 @@ class Piwik_Tracker $pluginsToLoad = Piwik_Config::getInstance()->Plugins['Plugins']; $pluginsForcedNotToLoad = Piwik_Tracker::getPluginsNotToLoad(); $pluginsToLoad = array_diff($pluginsToLoad, $pluginsForcedNotToLoad); + $pluginsToLoad = array_merge($pluginsToLoad, Piwik_Tracker::getPluginsToLoad()); $pluginsManager->loadPlugins($pluginsToLoad); } } @@ -589,15 +602,15 @@ class Piwik_Tracker } try { - $pluginsTracker = Piwik_Config::getInstance()->Plugins_Tracker; - if (is_array($pluginsTracker) - && count($pluginsTracker) != 0 - ) { - $pluginsTracker['Plugins_Tracker'] = array_diff($pluginsTracker['Plugins_Tracker'], self::getPluginsNotToLoad()); + $pluginsTracker = Piwik_Config::getInstance()->Plugins_Tracker['Plugins_Tracker']; + if (count($pluginsTracker) > 0) { + $pluginsTracker = $pluginsTracker; + $pluginsTracker = array_diff($pluginsTracker, self::getPluginsNotToLoad()); Piwik_PluginsManager::getInstance()->doNotLoadAlwaysActivatedPlugins(); - Piwik_PluginsManager::getInstance()->loadPlugins($pluginsTracker['Plugins_Tracker']); - printDebug("Loading plugins: { " . implode(",", $pluginsTracker['Plugins_Tracker']) . " }"); + Piwik_PluginsManager::getInstance()->loadPlugins($pluginsTracker); + + printDebug("Loading plugins: { " . implode(",", $pluginsTracker) . " }"); } } catch (Exception $e) { printDebug("ERROR: " . $e->getMessage()); @@ -757,6 +770,9 @@ class Piwik_Tracker // Disable provider plugin, because it is so slow to do reverse ip lookup in dev environment somehow self::setPluginsNotToLoad($pluginsDisabled); + + // we load 'DevicesDetection' in tests only (disabled by default) + self::setPluginsToLoad( array('DevicesDetection') ); } } diff --git a/libs/UserAgentParser/UserAgentParser.php b/libs/UserAgentParser/UserAgentParser.php index c65ed056f6..85c9225cc5 100644 --- a/libs/UserAgentParser/UserAgentParser.php +++ b/libs/UserAgentParser/UserAgentParser.php @@ -653,6 +653,11 @@ class UserAgentParser if (isset(self::$browserIdToName[$browserId])) { return self::$browserIdToName[$browserId]; } + if(class_exists('UserAgentParserEnhanced')) { + if( !empty(UserAgentParserEnhanced::$browsers[$browserId])) { + return UserAgentParserEnhanced::$browsers[$browserId]; + } + } return false; } @@ -684,6 +689,10 @@ class UserAgentParser if (isset(self::$operatingSystemsIdToName[$osId])) { return self::$operatingSystemsIdToName[$osId]; } + + if(class_exists('UserAgentParserEnhanced')) { + return UserAgentParserEnhanced::getOsNameFromId($osId); + } return false; } diff --git a/plugins/DevicesDetection/DevicesDetection.php b/plugins/DevicesDetection/DevicesDetection.php index e9cb732e8c..d18f768b21 100644 --- a/plugins/DevicesDetection/DevicesDetection.php +++ b/plugins/DevicesDetection/DevicesDetection.php @@ -21,8 +21,8 @@ class Piwik_DevicesDetection extends Piwik_Plugin public function getInformation() { return array( - 'description' => Piwik_Translate("DevicesDetection_description"), - 'author' => 'Clearcode.cc', + 'description' => "[Beta Plugin] " . Piwik_Translate("DevicesDetection_description"), + 'author' => 'Piwik and Clearcode.cc', 'author_homepage' => 'http://clearcode.cc', 'version' => '1.12-b6', 'TrackerPlugin' => true, diff --git a/plugins/DevicesDetection/UserAgentParserEnhanced/UserAgentParserEnhanced.php b/plugins/DevicesDetection/UserAgentParserEnhanced/UserAgentParserEnhanced.php index 9031b0fd33..f107455ad9 100644 --- a/plugins/DevicesDetection/UserAgentParserEnhanced/UserAgentParserEnhanced.php +++ b/plugins/DevicesDetection/UserAgentParserEnhanced/UserAgentParserEnhanced.php @@ -1,722 +1,735 @@ -<?php
-
-/**
- * Piwik - Open source web analytics
- *
- * @link http://piwik.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- *
- * @category Piwik_Plugins
- * @package Piwik_DevicesDetection
- */
-//yml parser
-require_once('spyc.php');
-
-class UserAgentParserEnhanced
-{
-
- public static $deviceTypes = array('car browser', 'console', 'desktop', 'feature phone', 'smartphone', 'tablet', 'tv');
- public static $deviceBrands = array(
- 'AC' => 'Acer',
- 'AI' => 'Airness',
- 'AL' => 'Alcatel',
- 'AO' => 'Amoi',
- 'AP' => 'Apple',
- 'AU' => 'Asus',
- 'AV' => 'Avvio',
- 'AX' => 'Audiovox',
- 'BE' => 'Becker',
- 'BI' => 'Bird',
- 'BL' => 'Beetel',
- 'BQ' => 'BenQ',
- 'BS' => 'BenQ-Siemens',
- 'CK' => 'Cricket',
- 'CL' => 'Compal',
- 'CT' => 'Capitel',
- 'DB' => 'Dbtel',
- 'DC' => 'DoCoMo',
- 'DI' => 'Dicam',
- 'DL' => 'Dell',
- 'DP' => 'Dopod',
- 'EC' => 'Ericsson',
- 'EI' => 'Ezio',
- 'ER' => 'Ericy',
- 'ET' => 'eTouch',
- 'EZ' => 'Ezze',
- 'FL' => 'Fly',
- 'GI' => 'Gionee',
- 'GO' => 'Google',
- 'GR' => 'Gradiente',
- 'GU' => 'Grundig',
- 'HA' => 'Haier',
- 'HP' => 'HP',
- 'HT' => 'HTC',
- 'HU' => 'Huawei',
- 'IK' => 'iKoMo',
- 'IM' => 'i-mate',
- 'IN' => 'Innostream',
- 'IO' => 'i-mobile',
- 'IQ' => 'INQ',
- 'KA' => 'Karbonn',
- 'KD' => 'KDDI',
- 'KN' => 'Kindle',
- 'KO' => 'Konka',
- 'KY' => 'Kyocera',
- 'LA' => 'Lanix',
- 'LC' => 'LCT',
- 'LE' => 'Lenovo',
- 'LG' => 'LG',
- 'LU' => 'LGUPlus',
- 'MI' => 'MicroMax',
- 'MO' => 'Mio',
- 'MR' => 'Motorola',
- 'MS' => 'Microsoft',
- 'MT' => 'Mitsubishi',
- 'MY' => 'MyPhone',
- 'NE' => 'NEC',
- 'NG' => 'NGM',
- 'NI' => 'Nintendo',
- 'NK' => 'Nokia',
- 'NW' => 'Newgen',
- 'NX' => 'Nexian',
- 'OD' => 'Onda',
- 'OP' => 'OPPO',
- 'OR' => 'Orange',
- 'OT' => 'O2',
- 'PA' => 'Panasonic',
- 'PH' => 'Philips',
- 'PM' => 'Palm',
- 'PO' => 'phoneOne',
- 'PT' => 'Pantech',
- 'QT' => 'Qtek',
- 'RM' => 'RIM',
- 'RO' => 'Rover',
- 'SA' => 'Samsung',
- 'SD' => 'Sega',
- 'SE' => 'Sony Ericsson',
- 'SF' => 'Softbank',
- 'SG' => 'Sagem',
- 'SH' => 'Sharp',
- 'SI' => 'Siemens',
- 'SN' => 'Sendo',
- 'SO' => 'Sony',
- 'SP' => 'Spice',
- 'SY' => 'Sanyo',
- 'TA' => 'Tesla',
- 'TC' => 'TCL',
- 'TE' => 'Telit',
- 'TH' => 'TiPhone',
- 'TI' => 'TIANYU',
- 'TM' => 'T-Mobile',
- 'TO' => 'Toplux',
- 'TS' => 'Toshiba',
- 'UT' => 'UTStarcom',
- 'VD' => 'Videocon',
- 'VE' => 'Vertu',
- 'VI' => 'Vitelcom',
- 'VK' => 'VK Mobile',
- 'VO' => 'Voxtel',
- 'WB' => 'Web TV',
- 'WE' => 'WellcoM',
- 'WO' => 'Wonu',
- 'XX' => 'Unknown',
- 'ZO' => 'Zonda',
- 'ZT' => 'ZTE',
- );
- public static $osShorts = array(
- 'AIX' => 'AIX',
- 'Android' => 'AND',
- 'Apple TV' => 'ATV',
- 'Arch Linux' => 'ARL',
- 'BackTrack' => 'BTR',
- 'Bada' => 'SBA',
- 'BlackBerry OS' => 'BLB',
- 'BlackBerry Tablet OS' => 'QNX',
- 'Bot' => 'BOT',
- 'Brew' => 'BMP',
- 'CentOS' => 'CES',
- 'Chrome OS' => 'COS',
- 'Debian' => 'DEB',
- 'DragonFly' => 'DFB',
- 'Fedora' => 'FED',
- 'Firefox OS' => 'FOS',
- 'FreeBSD' => 'BSD',
- 'Gentoo' => 'GNT',
- 'Google TV' => 'GTV',
- 'HP-UX' => 'HPX',
- 'IRIX' => 'IRI',
- 'Knoppix' => 'KNO',
- 'Kubuntu' => 'KBT',
- 'Linux' => 'LIN',
- 'Lubuntu' => 'LBT',
- 'Mac' => 'MAC',
- 'Mandriva' => 'MDR',
- 'MeeGo' => 'SMG',
- 'Mint' => 'MIN',
- 'NetBSD' => 'NBS',
- 'Nintendo' => 'WII',
- 'Nintendo Mobile' => 'NDS',
- 'OS/2' => 'OS2',
- 'OSF1' => 'T64',
- 'OpenBSD' => 'OBS',
- 'PlayStation' => 'PSP',
- 'PlayStation 3' => 'PS3',
- 'Presto' => 'PRS',
- 'Puppy' => 'PPY',
- 'Red Hat' => 'RHT',
- 'SUSE' => 'SSE',
- 'Slackware' => 'SLW',
- 'Solaris' => 'SOS',
- 'Syllable' => 'SYL',
- 'Symbian' => 'SYM',
- 'Symbian OS' => 'SYS',
- 'Symbian OS Series 40' => 'S40',
- 'Symbian OS Series 60' => 'S60',
- 'Symbian^3' => 'SY3',
- 'Talkatone' => 'TKT',
- 'Tizen' => 'TIZ',
- 'Ubuntu' => 'UBT',
- 'WebTV' => 'WTV',
- 'WinWAP' => 'WWP',
- 'Windows' => 'WIN',
- 'Windows 2000' => 'W2K',
- 'Windows 3.1' => 'W31',
- 'Windows 7' => 'WI7',
- 'Windows 8' => 'WI8',
- 'Windows 95' => 'W95',
- 'Windows 98' => 'W98',
- 'Windows CE' => 'WCE',
- 'Windows ME' => 'WME',
- 'Windows Mobile' => 'WMO',
- 'Windows NT' => 'WNT',
- 'Windows Phone' => 'WPH',
- 'Windows RT' => 'WRT',
- 'Windows Server 2003' => 'WS3',
- 'Windows Vista' => 'WVI',
- 'Windows XP' => 'WXP',
- 'Xbox' => 'XBX',
- 'Xubuntu' => 'XBT',
- 'YunOs' => 'YNS',
- 'iOS' => 'IOS',
- 'palmOS' => 'POS',
- 'webOS' => 'WOS'
- );
- protected static $desktopOsArray = array('IBM', 'Linux', 'Mac', 'Unix', 'Windows');
- public static $osFamilies = array(
- 'Android' => array('AND'),
- 'Apple TV' => array('ATV'),
- 'BlackBerry' => array('BLB'),
- 'Bot' => array('BOT'),
- 'Brew' => array('BMP'),
- 'Chrome OS' => array('COS'),
- 'Firefox OS' => array('FOS'),
- 'Gaming Console' => array('WII', 'PS3'),
- 'Google TV' => array('GTV'),
- 'IBM' => array('OS2'),
- 'iOS' => array('IOS'),
- 'Linux' => array('LIN', 'ARL', 'DEB', 'KNO', 'MIN', 'UBT', 'KBT', 'XBT', 'LBT', 'FED', 'RHT', 'MDR', 'GNT', 'SLW', 'SSE', 'PPY', 'CES', 'BTR', 'YNS', 'PRS'),
- 'Mac' => array('MAC'),
- 'Mobile Gaming Console' => array('PSP', 'NDS', 'XBX'),
- 'Other Mobile' => array('WOS', 'POS', 'QNX', 'SBA', 'TIZ'),
- 'Simulator' => array('TKT', 'WWP'),
- 'Symbian' => array('SYM', 'SYS', 'SY3', 'S60', 'S40', 'SMG'),
- 'Unix' => array('SOS', 'AIX', 'HPX', 'BSD', 'NBS', 'OBS', 'DFB', 'SYL', 'IRI', 'T64'),
- 'WebTV' => array('WTV'),
- 'Windows' => array('WI8', 'WI7', 'WVI', 'WS3', 'WXP', 'W2K', 'WNT', 'WME', 'W98', 'W95', 'WRT', 'W31', 'WIN'),
- 'Windows Mobile' => array('WPH', 'WMO', 'WCE')
- );
- public static $browserFamilies = array(
- 'Android Browser' => array('AN'),
- 'BlackBerry Browser' => array('BB'),
- 'Chrome' => array('CH', 'CM', 'CI', 'CF', 'CR', 'RM'),
- 'Firefox' => array('FF', 'FE', 'SX', 'FB', 'PX', 'MB'),
- 'Internet Explorer' => array('IE', 'IM'),
- 'Konqueror' => array('KO'),
- 'NetFront' => array('NF'),
- 'Nokia Browser' => array('NB'),
- 'Opera' => array('OP', 'OM', 'OI'),
- 'Safari' => array('SF', 'MF')
- );
- public static $browsers = array(
- 'AB' => 'ABrowse',
- 'AM' => 'Amaya',
- 'AN' => 'Android Browser',
- 'AR' => 'Arora',
- 'AV' => 'Amiga Voyager',
- 'AW' => 'Amiga Aweb',
- 'BB' => 'BlackBerry Browser',
- 'BD' => 'Baidu Browser',
- 'BE' => 'Beonex',
- 'BX' => 'BrowseX',
- 'CA' => 'Camino',
- 'CF' => 'Chrome Frame',
- 'CH' => 'Chrome',
- 'CI' => 'Chrome Mobile iOS',
- 'CK' => 'Conkeror',
- 'CM' => 'Chrome Mobile',
- 'CO' => 'CometBird',
- 'CR' => 'Chromium',
- 'CS' => 'Cheshire',
- 'DF' => 'Dolphin',
- 'DI' => 'Dillo',
- 'EL' => 'Elinks',
- 'EP' => 'Epiphany',
- 'FB' => 'Firebird',
- 'FD' => 'Fluid',
- 'FE' => 'Fennec',
- 'FF' => 'Firefox',
- 'FL' => 'Flock',
- 'FN' => 'Fireweb Navigator',
- 'GA' => 'Galeon',
- 'GE' => 'Google Earth',
- 'HJ' => 'HotJava',
- 'IB' => 'IBrowse',
- 'IC' => 'iCab',
- 'IE' => 'Internet Explorer',
- 'IM' => 'IE Mobile',
- 'IR' => 'Iron',
- 'JS' => 'Jasmine',
- 'KI' => 'Kindle Browser',
- 'KM' => 'K-meleon',
- 'KO' => 'Konqueror',
- 'KP' => 'Kapiko',
- 'KZ' => 'Kazehakase',
- 'LG' => 'Lightning',
- 'LI' => 'Links',
- 'LX' => 'Lynx',
- 'MB' => 'MicroB',
- 'MC' => 'NCSA Mosaic',
- 'MF' => 'Mobile Safari',
- 'MI' => 'Midori',
- 'MS' => 'Mobile Silk',
- 'MX' => 'Maxthon',
- 'NB' => 'Nokia Browser',
- 'NF' => 'NetFront',
- 'NL' => 'NetFront Life',
- 'NS' => 'Netscape',
- 'OB' => 'Obigo',
- 'OI' => 'Opera Mini',
- 'OM' => 'Opera Mobile',
- 'OP' => 'Opera',
- 'OV' => 'Openwave Mobile Browser',
- 'OW' => 'OmniWeb',
- 'PL' => 'Palm Blazer',
- 'PR' => 'Palm Pre',
- 'PX' => 'Phoenix',
- 'RK' => 'Rekonq',
- 'RM' => 'RockMelt',
- 'SF' => 'Safari',
- 'SM' => 'SeaMonkey',
- 'SN' => 'Snowshoe',
- 'SX' => 'Swiftfox',
- 'TZ' => 'Tizen Browser',
- 'UC' => 'UC Browser',
- 'WO' => 'wOSBrowser',
- 'YA' => 'Yandex Browser'
- );
-
- const UNKNOWN = "UNK";
- protected static $regexesDir = '/regexes/';
- protected static $osRegexesFile = 'oss.yml';
- protected static $browserRegexesFile = 'browsers.yml';
- protected static $mobileRegexesFile = 'mobiles.yml';
- protected $userAgent;
- protected $os;
- protected $browser;
- protected $device;
- protected $brand;
- protected $model;
- protected $debug = false;
-
- public function __construct($userAgent)
- {
- $this->userAgent = $userAgent;
- }
-
- protected function getOsRegexes()
- {
- return Spyc::YAMLLoad(__DIR__ . self::$regexesDir . self::$osRegexesFile);
- }
-
- protected function getBrowserRegexes()
- {
- return Spyc::YAMLLoad(__DIR__ . self::$regexesDir . self::$browserRegexesFile);
- }
-
- protected function getMobileRegexes()
- {
- return Spyc::YAMLLoad(__DIR__ . self::$regexesDir . self::$mobileRegexesFile);
- }
-
- public function parse()
- {
- $this->parseOs();
- if ($this->isBot() || $this->isSimulator())
- return;
-
- $this->parseBrowser();
-
- if ($this->isMobile()) {
- $this->parseMobile();
- } else {
- $this->device = array_search('desktop', self::$deviceTypes);
- }
- if ($this->debug) {
- var_dump($this->brand, $this->model, $this->device);
- }
- }
-
- protected function parseOs()
- {
- foreach ($this->getOsRegexes() as $osRegex) {
- $matches = $this->matchUserAgent($osRegex['regex']);
- if ($matches)
- break;
- }
-
- if (!$matches)
- return;
-
- if (in_array($osRegex['name'], self::$osShorts)) {
- $short = self::$osShorts[$osRegex['name']];
- } else {
- $short = 'UNK';
- }
-
- $this->os = array(
- 'name' => $this->buildOsName($osRegex['name'], $matches),
- 'short_name' => $short,
- 'version' => $this->buildOsVersion($osRegex['version'], $matches)
- );
-
- if (array_key_exists($this->os['name'], self::$osShorts)) {
- $this->os['short_name'] = self::$osShorts[$this->os['name']];
- }
- }
-
- protected function parseBrowser()
- {
- foreach ($this->getBrowserRegexes() as $browserRegex) {
- $matches = $this->matchUserAgent($browserRegex['regex']);
- if ($matches)
- break;
- }
-
- if (!$matches)
- return;
-
- if (in_array($browserRegex['name'], self::$browsers)) {
- $short = array_search($browserRegex['name'], self::$browsers);
- } else {
- $short = 'XX';
- }
-
- $this->browser = array(
- 'name' => $this->buildBrowserName($browserRegex['name'], $matches),
- 'short_name' => $short,
- 'version' => $this->buildBrowserVersion($browserRegex['version'], $matches)
- );
- }
-
- protected function parseMobile()
- {
- $mobileRegexes = $this->getMobileRegexes();
- $this->parseBrand($mobileRegexes);
- $this->parseModel($mobileRegexes);
- }
-
- protected function parseBrand($mobileRegexes)
- {
- foreach ($mobileRegexes as $brand => $mobileRegex) {
- $matches = $this->matchUserAgent($mobileRegex['regex']);
- if ($matches)
- break;
- }
-
- if (!$matches)
- return;
- $this->brand = array_search($brand, self::$deviceBrands);
- $this->fullName = $brand;
-
- if (isset($mobileRegex['device'])) {
- $this->device = array_search($mobileRegex['device'],self::$deviceTypes);
- }
-
- if (isset($mobileRegex['model'])) {
- $this->model = $this->buildModel($mobileRegex['model'], $matches);
- }
- }
-
- protected function parseModel($mobileRegexes)
- {
- if (empty($this->brand) || !empty($this->model))
- return;
-
- foreach ($mobileRegexes[$this->fullName]['models'] as $modelRegex) {
- $matches = $this->matchUserAgent($modelRegex['regex']);
- if ($matches)
- break;
- }
-
- if (!$matches) {
- return;
- }
-
- $this->model = $this->buildModel($modelRegex['model'], $matches);
-
- if (isset($modelRegex['device'])) {
- $this->device = array_search($modelRegex['device'], self::$deviceTypes);
- }
- }
-
- protected function matchUserAgent($regex)
- {
- $regex = '/' . str_replace('/', '\/', $regex) . '/i';
-
- if (preg_match($regex, $this->userAgent, $matches)) {
- return $matches;
- }
-
- return false;
- }
-
- protected function buildOsName($osName, $matches)
- {
- return $this->buildByMatch($osName, $matches);
- }
-
- protected function buildOsVersion($osVersion, $matches)
- {
- $osVersion = $this->buildByMatch($osVersion, $matches);
-
- $osVersion = $this->buildByMatch($osVersion, $matches, '2');
-
- $osVersion = str_replace('_', '.', $osVersion);
-
- return $osVersion;
- }
-
- protected function buildBrowserName($browserName, $matches)
- {
- return $this->buildByMatch($browserName, $matches);
- }
-
- protected function buildBrowserVersion($browserVersion, $matches)
- {
- $browserVersion = $this->buildByMatch($browserVersion, $matches);
-
- $browserVersion = $this->buildByMatch($browserVersion, $matches, '2');
-
- $browserVersion = str_replace('_', '.', $browserVersion);
-
- return $browserVersion;
- }
-
- protected function buildModel($model, $matches)
- {
- $model = $this->buildByMatch($model, $matches);
-
- $model = $this->buildByMatch($model, $matches, '2');
-
- $model = $this->buildModelExceptions($model);
-
- $model = str_replace('_', ' ', $model);
-
- return $model;
- }
-
- protected function buildModelExceptions($model)
- {
- if ($this->brand == 'O2') {
- $model = preg_replace('/([a-z])([A-Z])/', '$1 $2', $model);
- $model = ucwords(str_replace('_', ' ', $model));
- }
-
- return $model;
- }
-
- /**
- * This method is used in this class for processing results of pregmatch
- * results into string containing recognized information.
- *
- * General algorithm:
- * Parsing UserAgent string consists of trying to match it against list of
- * regular expressions for three different information:
- * browser + version,
- * OS + version,
- * device manufacturer + model.
- *
- * After match has been found iteration stops, and results are processed
- * by buildByMatch.
- * As $item we get decoded name (name of browser, name of OS, name of manufacturer).
- * In array $match we recieve preg_match results containing whole string matched at index 0
- * and following matches in further indexes. Desired action now is to concatenate
- * decoded name ($item) with matches found. First step is to append first found match,
- * which is located in index=1 (that's why $nb is 1 by default).
- * In other cases, where whe know that preg_match may return more than 1 result,
- * we call buildByMatch with $nb = 2 or more, depending on what will be returned from
- * regular expression.
- *
- * Example:
- * We are parsing UserAgent of Firefox 20.0 browser.
- * UserAgentParserEnhanced calls buildBrowserName() and buildBrowserVersion() in order
- * to retrieve those information.
- * In buildBrowserName() we only have one call of buildByMatch, where passed argument
- * is regular expression testing given string for browser name. In this case, we are only
- * interrested in first hit, so no $nb parameter will be set to 1. After finding match, and calling
- * buildByMatch - we will receive just the name of browser.
- *
- * Also after decoding browser we will get list of regular expressions for this browser name
- * testing UserAgent string for version number. Again we iterate over this list, and after finding first
- * occurence - we break loop and proceed to build by match. Since browser regular expressions can
- * contain two hits (major version and minor version) in function buildBrowserVersion() we have
- * two calls to buildByMatch, one without 3rd parameter, and second with $nb set to 2.
- * This way we can retrieve version number, and assign it to object property.
- *
- * In case of mobiles.yml this schema slightly varies, but general idea is the same.
- *
- * @param string $item
- * @param array $matches
- * @param int $nb
- * @return type
- */
- protected function buildByMatch($item, $matches, $nb = '1')
- {
- if (strpos($item, '$' . $nb) === false)
- return $item;
-
- $replace = isset($matches[$nb]) ? $matches[$nb] : '';
- return trim(str_replace('$' . $nb, $replace, $item));
- }
-
- public function isBot()
- {
- $decodedFamily = '';
- if (in_array($this->getOs('name'), self::$osShorts)) {
- $osShort = self::$osShorts[$this->getOs('name')];
- } else {
- $osShort = '';
- }
- foreach (self::$osFamilies as $family => $familyOs) {
- if (in_array($osShort, $familyOs)) {
- $decodedFamily = $family;
- break;
- }
- }
-
- return $decodedFamily == 'Bot';
- }
-
- public function isSimulator()
- {
- $decodedFamily = '';
- if (in_array($this->getOs('name'), self::$osShorts)) {
- $osShort = self::$osShorts[$this->getOs('name')];
- } else {
- $osShort = '';
- }
- foreach (self::$osFamilies as $family => $familyOs) {
- if (in_array($osShort, $familyOs)) {
- $decodedFamily = $family;
- break;
- }
- }
- return $decodedFamily == 'Simulator';
- }
-
- public function isMobile()
- {
- return !$this->isDesktop();
- }
-
- public function isDesktop()
- {
- $osName = $this->getOs('name');
- if (empty($osName) || empty(self::$osShorts[$osName])) {
- return false;
- }
-
- $osShort = self::$osShorts[$osName];
- foreach (self::$osFamilies as $family => $familyOs) {
- if (in_array($osShort, $familyOs)) {
- $decodedFamily = $family;
- break;
- }
- }
- return in_array($decodedFamily, self::$desktopOsArray);
- }
-
- public function getOs($attr = '')
- {
- if ($attr == '') {
- return $this->os;
- }
-
- if (!isset($this->os[$attr])) {
- return self::UNKNOWN;
- }
-
- if ($attr == 'version') {
- $this->os['version'] = $this->os['version'];
- }
- return $this->os[$attr];
- }
-
- public function getBrowser($attr = '')
- {
- if ($attr == '') {
- return $this->browser;
- }
-
- if (!isset($this->browser[$attr])) {
- return self::UNKNOWN;
- }
-
- return $this->browser[$attr];
- }
-
- public function getDevice()
- {
- return $this->device;
- }
-
- public function getBrand()
- {
- return $this->brand;
- }
-
- public function getModel()
- {
- return $this->model;
- }
-
- public function getUserAgent()
- {
- return $this->userAgent;
- }
-
- public static function getOsFamily($osLabel)
- {
- $osShortName = substr($osLabel, 0, 3);
-
- foreach (self::$osFamilies as $osFamily => $osShortNames) {
- if (in_array($osShortName, $osShortNames)) {
- return $osFamily;
- }
- }
-
- return 'Other';
- }
-
- public static function getBrowserFamily($browserLabel)
- {
- foreach (self::$browserFamilies as $browserFamily => $browserShortNames) {
- if (in_array($browserLabel, $browserShortNames)) {
- return $browserFamily;
- }
- }
-
- return 'Other';
- }
-
+<?php + +/** + * Piwik - Open source web analytics + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + * @category Piwik_Plugins + * @package Piwik_DevicesDetection + */ +//yml parser +require_once('spyc.php'); + +class UserAgentParserEnhanced +{ + + public static $deviceTypes = array('car browser', 'console', 'desktop', 'feature phone', 'smartphone', 'tablet', 'tv'); + public static $deviceBrands = array( + 'AC' => 'Acer', + 'AI' => 'Airness', + 'AL' => 'Alcatel', + 'AO' => 'Amoi', + 'AP' => 'Apple', + 'AU' => 'Asus', + 'AV' => 'Avvio', + 'AX' => 'Audiovox', + 'BE' => 'Becker', + 'BI' => 'Bird', + 'BL' => 'Beetel', + 'BQ' => 'BenQ', + 'BS' => 'BenQ-Siemens', + 'CK' => 'Cricket', + 'CL' => 'Compal', + 'CT' => 'Capitel', + 'DB' => 'Dbtel', + 'DC' => 'DoCoMo', + 'DI' => 'Dicam', + 'DL' => 'Dell', + 'DP' => 'Dopod', + 'EC' => 'Ericsson', + 'EI' => 'Ezio', + 'ER' => 'Ericy', + 'ET' => 'eTouch', + 'EZ' => 'Ezze', + 'FL' => 'Fly', + 'GI' => 'Gionee', + 'GO' => 'Google', + 'GR' => 'Gradiente', + 'GU' => 'Grundig', + 'HA' => 'Haier', + 'HP' => 'HP', + 'HT' => 'HTC', + 'HU' => 'Huawei', + 'IK' => 'iKoMo', + 'IM' => 'i-mate', + 'IN' => 'Innostream', + 'IO' => 'i-mobile', + 'IQ' => 'INQ', + 'KA' => 'Karbonn', + 'KD' => 'KDDI', + 'KN' => 'Kindle', + 'KO' => 'Konka', + 'KY' => 'Kyocera', + 'LA' => 'Lanix', + 'LC' => 'LCT', + 'LE' => 'Lenovo', + 'LG' => 'LG', + 'LU' => 'LGUPlus', + 'MI' => 'MicroMax', + 'MO' => 'Mio', + 'MR' => 'Motorola', + 'MS' => 'Microsoft', + 'MT' => 'Mitsubishi', + 'MY' => 'MyPhone', + 'NE' => 'NEC', + 'NG' => 'NGM', + 'NI' => 'Nintendo', + 'NK' => 'Nokia', + 'NW' => 'Newgen', + 'NX' => 'Nexian', + 'OD' => 'Onda', + 'OP' => 'OPPO', + 'OR' => 'Orange', + 'OT' => 'O2', + 'PA' => 'Panasonic', + 'PH' => 'Philips', + 'PM' => 'Palm', + 'PO' => 'phoneOne', + 'PT' => 'Pantech', + 'QT' => 'Qtek', + 'RM' => 'RIM', + 'RO' => 'Rover', + 'SA' => 'Samsung', + 'SD' => 'Sega', + 'SE' => 'Sony Ericsson', + 'SF' => 'Softbank', + 'SG' => 'Sagem', + 'SH' => 'Sharp', + 'SI' => 'Siemens', + 'SN' => 'Sendo', + 'SO' => 'Sony', + 'SP' => 'Spice', + 'SY' => 'Sanyo', + 'TA' => 'Tesla', + 'TC' => 'TCL', + 'TE' => 'Telit', + 'TH' => 'TiPhone', + 'TI' => 'TIANYU', + 'TM' => 'T-Mobile', + 'TO' => 'Toplux', + 'TS' => 'Toshiba', + 'UT' => 'UTStarcom', + 'VD' => 'Videocon', + 'VE' => 'Vertu', + 'VI' => 'Vitelcom', + 'VK' => 'VK Mobile', + 'VO' => 'Voxtel', + 'WB' => 'Web TV', + 'WE' => 'WellcoM', + 'WO' => 'Wonu', + 'XX' => 'Unknown', + 'ZO' => 'Zonda', + 'ZT' => 'ZTE', + ); + public static $osShorts = array( + 'AIX' => 'AIX', + 'Android' => 'AND', + 'Apple TV' => 'ATV', + 'Arch Linux' => 'ARL', + 'BackTrack' => 'BTR', + 'Bada' => 'SBA', + 'BlackBerry OS' => 'BLB', + 'BlackBerry Tablet OS' => 'QNX', + 'Bot' => 'BOT', + 'Brew' => 'BMP', + 'CentOS' => 'CES', + 'Chrome OS' => 'COS', + 'Debian' => 'DEB', + 'DragonFly' => 'DFB', + 'Fedora' => 'FED', + 'Firefox OS' => 'FOS', + 'FreeBSD' => 'BSD', + 'Gentoo' => 'GNT', + 'Google TV' => 'GTV', + 'HP-UX' => 'HPX', + 'IRIX' => 'IRI', + 'Knoppix' => 'KNO', + 'Kubuntu' => 'KBT', + 'Linux' => 'LIN', + 'Lubuntu' => 'LBT', + 'Mac' => 'MAC', + 'Mandriva' => 'MDR', + 'MeeGo' => 'SMG', + 'Mint' => 'MIN', + 'NetBSD' => 'NBS', + 'Nintendo' => 'WII', + 'Nintendo Mobile' => 'NDS', + 'OS/2' => 'OS2', + 'OSF1' => 'T64', + 'OpenBSD' => 'OBS', + 'PlayStation' => 'PSP', + 'PlayStation 3' => 'PS3', + 'Presto' => 'PRS', + 'Puppy' => 'PPY', + 'Red Hat' => 'RHT', + 'SUSE' => 'SSE', + 'Slackware' => 'SLW', + 'Solaris' => 'SOS', + 'Syllable' => 'SYL', + 'Symbian' => 'SYM', + 'Symbian OS' => 'SYS', + 'Symbian OS Series 40' => 'S40', + 'Symbian OS Series 60' => 'S60', + 'Symbian^3' => 'SY3', + 'Talkatone' => 'TKT', + 'Tizen' => 'TIZ', + 'Ubuntu' => 'UBT', + 'WebTV' => 'WTV', + 'WinWAP' => 'WWP', + 'Windows' => 'WIN', + 'Windows 2000' => 'W2K', + 'Windows 3.1' => 'W31', + 'Windows 7' => 'WI7', + 'Windows 8' => 'WI8', + 'Windows 95' => 'W95', + 'Windows 98' => 'W98', + 'Windows CE' => 'WCE', + 'Windows ME' => 'WME', + 'Windows Mobile' => 'WMO', + 'Windows NT' => 'WNT', + 'Windows Phone' => 'WPH', + 'Windows RT' => 'WRT', + 'Windows Server 2003' => 'WS3', + 'Windows Vista' => 'WVI', + 'Windows XP' => 'WXP', + 'Xbox' => 'XBX', + 'Xubuntu' => 'XBT', + 'YunOs' => 'YNS', + 'iOS' => 'IOS', + 'palmOS' => 'POS', + 'webOS' => 'WOS' + ); + protected static $desktopOsArray = array('IBM', 'Linux', 'Mac', 'Unix', 'Windows'); + public static $osFamilies = array( + 'Android' => array('AND'), + 'Apple TV' => array('ATV'), + 'BlackBerry' => array('BLB'), + 'Bot' => array('BOT'), + 'Brew' => array('BMP'), + 'Chrome OS' => array('COS'), + 'Firefox OS' => array('FOS'), + 'Gaming Console' => array('WII', 'PS3'), + 'Google TV' => array('GTV'), + 'IBM' => array('OS2'), + 'iOS' => array('IOS'), + 'Linux' => array('LIN', 'ARL', 'DEB', 'KNO', 'MIN', 'UBT', 'KBT', 'XBT', 'LBT', 'FED', 'RHT', 'MDR', 'GNT', 'SLW', 'SSE', 'PPY', 'CES', 'BTR', 'YNS', 'PRS'), + 'Mac' => array('MAC'), + 'Mobile Gaming Console' => array('PSP', 'NDS', 'XBX'), + 'Other Mobile' => array('WOS', 'POS', 'QNX', 'SBA', 'TIZ'), + 'Simulator' => array('TKT', 'WWP'), + 'Symbian' => array('SYM', 'SYS', 'SY3', 'S60', 'S40', 'SMG'), + 'Unix' => array('SOS', 'AIX', 'HPX', 'BSD', 'NBS', 'OBS', 'DFB', 'SYL', 'IRI', 'T64'), + 'WebTV' => array('WTV'), + 'Windows' => array('WI8', 'WI7', 'WVI', 'WS3', 'WXP', 'W2K', 'WNT', 'WME', 'W98', 'W95', 'WRT', 'W31', 'WIN'), + 'Windows Mobile' => array('WPH', 'WMO', 'WCE') + ); + public static $browserFamilies = array( + 'Android Browser' => array('AN'), + 'BlackBerry Browser' => array('BB'), + 'Chrome' => array('CH', 'CM', 'CI', 'CF', 'CR', 'RM'), + 'Firefox' => array('FF', 'FE', 'SX', 'FB', 'PX', 'MB'), + 'Internet Explorer' => array('IE', 'IM'), + 'Konqueror' => array('KO'), + 'NetFront' => array('NF'), + 'Nokia Browser' => array('NB'), + 'Opera' => array('OP', 'OM', 'OI'), + 'Safari' => array('SF', 'MF') + ); + public static $browsers = array( + 'AB' => 'ABrowse', + 'AM' => 'Amaya', + 'AN' => 'Android Browser', + 'AR' => 'Arora', + 'AV' => 'Amiga Voyager', + 'AW' => 'Amiga Aweb', + 'BB' => 'BlackBerry Browser', + 'BD' => 'Baidu Browser', + 'BE' => 'Beonex', + 'BX' => 'BrowseX', + 'CA' => 'Camino', + 'CF' => 'Chrome Frame', + 'CH' => 'Chrome', + 'CI' => 'Chrome Mobile iOS', + 'CK' => 'Conkeror', + 'CM' => 'Chrome Mobile', + 'CO' => 'CometBird', + 'CR' => 'Chromium', + 'CS' => 'Cheshire', + 'DF' => 'Dolphin', + 'DI' => 'Dillo', + 'EL' => 'Elinks', + 'EP' => 'Epiphany', + 'FB' => 'Firebird', + 'FD' => 'Fluid', + 'FE' => 'Fennec', + 'FF' => 'Firefox', + 'FL' => 'Flock', + 'FN' => 'Fireweb Navigator', + 'GA' => 'Galeon', + 'GE' => 'Google Earth', + 'HJ' => 'HotJava', + 'IB' => 'IBrowse', + 'IC' => 'iCab', + 'IE' => 'Internet Explorer', + 'IM' => 'IE Mobile', + 'IR' => 'Iron', + 'JS' => 'Jasmine', + 'KI' => 'Kindle Browser', + 'KM' => 'K-meleon', + 'KO' => 'Konqueror', + 'KP' => 'Kapiko', + 'KZ' => 'Kazehakase', + 'LG' => 'Lightning', + 'LI' => 'Links', + 'LX' => 'Lynx', + 'MB' => 'MicroB', + 'MC' => 'NCSA Mosaic', + 'MF' => 'Mobile Safari', + 'MI' => 'Midori', + 'MS' => 'Mobile Silk', + 'MX' => 'Maxthon', + 'NB' => 'Nokia Browser', + 'NF' => 'NetFront', + 'NL' => 'NetFront Life', + 'NS' => 'Netscape', + 'OB' => 'Obigo', + 'OI' => 'Opera Mini', + 'OM' => 'Opera Mobile', + 'OP' => 'Opera', + 'OV' => 'Openwave Mobile Browser', + 'OW' => 'OmniWeb', + 'PL' => 'Palm Blazer', + 'PR' => 'Palm Pre', + 'PX' => 'Phoenix', + 'RK' => 'Rekonq', + 'RM' => 'RockMelt', + 'SF' => 'Safari', + 'SM' => 'SeaMonkey', + 'SN' => 'Snowshoe', + 'SX' => 'Swiftfox', + 'TZ' => 'Tizen Browser', + 'UC' => 'UC Browser', + 'WO' => 'wOSBrowser', + 'YA' => 'Yandex Browser' + ); + + const UNKNOWN = "UNK"; + protected static $regexesDir = '/regexes/'; + protected static $osRegexesFile = 'oss.yml'; + protected static $browserRegexesFile = 'browsers.yml'; + protected static $mobileRegexesFile = 'mobiles.yml'; + protected $userAgent; + protected $os; + protected $browser; + protected $device; + protected $brand; + protected $model; + protected $debug = false; + + public function __construct($userAgent) + { + $this->userAgent = $userAgent; + } + + protected function getOsRegexes() + { + return Spyc::YAMLLoad(__DIR__ . self::$regexesDir . self::$osRegexesFile); + } + + protected function getBrowserRegexes() + { + return Spyc::YAMLLoad(__DIR__ . self::$regexesDir . self::$browserRegexesFile); + } + + protected function getMobileRegexes() + { + return Spyc::YAMLLoad(__DIR__ . self::$regexesDir . self::$mobileRegexesFile); + } + + public function parse() + { + $this->parseOs(); + if ($this->isBot() || $this->isSimulator()) + return; + + $this->parseBrowser(); + + if ($this->isMobile()) { + $this->parseMobile(); + } else { + $this->device = array_search('desktop', self::$deviceTypes); + } + if ($this->debug) { + var_dump($this->brand, $this->model, $this->device); + } + } + + protected function parseOs() + { + foreach ($this->getOsRegexes() as $osRegex) { + $matches = $this->matchUserAgent($osRegex['regex']); + if ($matches) + break; + } + + if (!$matches) + return; + + if (in_array($osRegex['name'], self::$osShorts)) { + $short = self::$osShorts[$osRegex['name']]; + } else { + $short = 'UNK'; + } + + $this->os = array( + 'name' => $this->buildOsName($osRegex['name'], $matches), + 'short_name' => $short, + 'version' => $this->buildOsVersion($osRegex['version'], $matches) + ); + + if (array_key_exists($this->os['name'], self::$osShorts)) { + $this->os['short_name'] = self::$osShorts[$this->os['name']]; + } + } + + protected function parseBrowser() + { + foreach ($this->getBrowserRegexes() as $browserRegex) { + $matches = $this->matchUserAgent($browserRegex['regex']); + if ($matches) + break; + } + + if (!$matches) + return; + + if (in_array($browserRegex['name'], self::$browsers)) { + $short = array_search($browserRegex['name'], self::$browsers); + } else { + $short = 'XX'; + } + + $this->browser = array( + 'name' => $this->buildBrowserName($browserRegex['name'], $matches), + 'short_name' => $short, + 'version' => $this->buildBrowserVersion($browserRegex['version'], $matches) + ); + } + + protected function parseMobile() + { + $mobileRegexes = $this->getMobileRegexes(); + $this->parseBrand($mobileRegexes); + $this->parseModel($mobileRegexes); + } + + protected function parseBrand($mobileRegexes) + { + foreach ($mobileRegexes as $brand => $mobileRegex) { + $matches = $this->matchUserAgent($mobileRegex['regex']); + if ($matches) + break; + } + + if (!$matches) + return; + $this->brand = array_search($brand, self::$deviceBrands); + $this->fullName = $brand; + + if (isset($mobileRegex['device'])) { + $this->device = array_search($mobileRegex['device'],self::$deviceTypes); + } + + if (isset($mobileRegex['model'])) { + $this->model = $this->buildModel($mobileRegex['model'], $matches); + } + } + + protected function parseModel($mobileRegexes) + { + if (empty($this->brand) || !empty($this->model)) + return; + + foreach ($mobileRegexes[$this->fullName]['models'] as $modelRegex) { + $matches = $this->matchUserAgent($modelRegex['regex']); + if ($matches) + break; + } + + if (!$matches) { + return; + } + + $this->model = $this->buildModel($modelRegex['model'], $matches); + + if (isset($modelRegex['device'])) { + $this->device = array_search($modelRegex['device'], self::$deviceTypes); + } + } + + protected function matchUserAgent($regex) + { + $regex = '/' . str_replace('/', '\/', $regex) . '/i'; + + if (preg_match($regex, $this->userAgent, $matches)) { + return $matches; + } + + return false; + } + + protected function buildOsName($osName, $matches) + { + return $this->buildByMatch($osName, $matches); + } + + protected function buildOsVersion($osVersion, $matches) + { + $osVersion = $this->buildByMatch($osVersion, $matches); + + $osVersion = $this->buildByMatch($osVersion, $matches, '2'); + + $osVersion = str_replace('_', '.', $osVersion); + + return $osVersion; + } + + protected function buildBrowserName($browserName, $matches) + { + return $this->buildByMatch($browserName, $matches); + } + + protected function buildBrowserVersion($browserVersion, $matches) + { + $browserVersion = $this->buildByMatch($browserVersion, $matches); + + $browserVersion = $this->buildByMatch($browserVersion, $matches, '2'); + + $browserVersion = str_replace('_', '.', $browserVersion); + + return $browserVersion; + } + + protected function buildModel($model, $matches) + { + $model = $this->buildByMatch($model, $matches); + + $model = $this->buildByMatch($model, $matches, '2'); + + $model = $this->buildModelExceptions($model); + + $model = str_replace('_', ' ', $model); + + return $model; + } + + protected function buildModelExceptions($model) + { + if ($this->brand == 'O2') { + $model = preg_replace('/([a-z])([A-Z])/', '$1 $2', $model); + $model = ucwords(str_replace('_', ' ', $model)); + } + + return $model; + } + + /** + * This method is used in this class for processing results of pregmatch + * results into string containing recognized information. + * + * General algorithm: + * Parsing UserAgent string consists of trying to match it against list of + * regular expressions for three different information: + * browser + version, + * OS + version, + * device manufacturer + model. + * + * After match has been found iteration stops, and results are processed + * by buildByMatch. + * As $item we get decoded name (name of browser, name of OS, name of manufacturer). + * In array $match we recieve preg_match results containing whole string matched at index 0 + * and following matches in further indexes. Desired action now is to concatenate + * decoded name ($item) with matches found. First step is to append first found match, + * which is located in index=1 (that's why $nb is 1 by default). + * In other cases, where whe know that preg_match may return more than 1 result, + * we call buildByMatch with $nb = 2 or more, depending on what will be returned from + * regular expression. + * + * Example: + * We are parsing UserAgent of Firefox 20.0 browser. + * UserAgentParserEnhanced calls buildBrowserName() and buildBrowserVersion() in order + * to retrieve those information. + * In buildBrowserName() we only have one call of buildByMatch, where passed argument + * is regular expression testing given string for browser name. In this case, we are only + * interrested in first hit, so no $nb parameter will be set to 1. After finding match, and calling + * buildByMatch - we will receive just the name of browser. + * + * Also after decoding browser we will get list of regular expressions for this browser name + * testing UserAgent string for version number. Again we iterate over this list, and after finding first + * occurence - we break loop and proceed to build by match. Since browser regular expressions can + * contain two hits (major version and minor version) in function buildBrowserVersion() we have + * two calls to buildByMatch, one without 3rd parameter, and second with $nb set to 2. + * This way we can retrieve version number, and assign it to object property. + * + * In case of mobiles.yml this schema slightly varies, but general idea is the same. + * + * @param string $item + * @param array $matches + * @param int $nb + * @return type + */ + protected function buildByMatch($item, $matches, $nb = '1') + { + if (strpos($item, '$' . $nb) === false) + return $item; + + $replace = isset($matches[$nb]) ? $matches[$nb] : ''; + return trim(str_replace('$' . $nb, $replace, $item)); + } + + public function isBot() + { + $decodedFamily = ''; + if (in_array($this->getOs('name'), self::$osShorts)) { + $osShort = self::$osShorts[$this->getOs('name')]; + } else { + $osShort = ''; + } + foreach (self::$osFamilies as $family => $familyOs) { + if (in_array($osShort, $familyOs)) { + $decodedFamily = $family; + break; + } + } + + return $decodedFamily == 'Bot'; + } + + public function isSimulator() + { + $decodedFamily = ''; + if (in_array($this->getOs('name'), self::$osShorts)) { + $osShort = self::$osShorts[$this->getOs('name')]; + } else { + $osShort = ''; + } + foreach (self::$osFamilies as $family => $familyOs) { + if (in_array($osShort, $familyOs)) { + $decodedFamily = $family; + break; + } + } + return $decodedFamily == 'Simulator'; + } + + public function isMobile() + { + return !$this->isDesktop(); + } + + public function isDesktop() + { + $osName = $this->getOs('name'); + if (empty($osName) || empty(self::$osShorts[$osName])) { + return false; + } + + $osShort = self::$osShorts[$osName]; + foreach (self::$osFamilies as $family => $familyOs) { + if (in_array($osShort, $familyOs)) { + $decodedFamily = $family; + break; + } + } + return in_array($decodedFamily, self::$desktopOsArray); + } + + public function getOs($attr = '') + { + if ($attr == '') { + return $this->os; + } + + if (!isset($this->os[$attr])) { + return self::UNKNOWN; + } + + if ($attr == 'version') { + $this->os['version'] = $this->os['version']; + } + return $this->os[$attr]; + } + + public function getBrowser($attr = '') + { + if ($attr == '') { + return $this->browser; + } + + if (!isset($this->browser[$attr])) { + return self::UNKNOWN; + } + + return $this->browser[$attr]; + } + + public function getDevice() + { + return $this->device; + } + + public function getBrand() + { + return $this->brand; + } + + public function getModel() + { + return $this->model; + } + + public function getUserAgent() + { + return $this->userAgent; + } + + public static function getOsFamily($osLabel) + { + $osShortName = substr($osLabel, 0, 3); + + foreach (self::$osFamilies as $osFamily => $osShortNames) { + if (in_array($osShortName, $osShortNames)) { + return $osFamily; + } + } + + return 'Other'; + } + + public static function getBrowserFamily($browserLabel) + { + foreach (self::$browserFamilies as $browserFamily => $browserShortNames) { + if (in_array($browserLabel, $browserShortNames)) { + return $browserFamily; + } + } + + return 'Other'; + } + + public static function getOsNameFromId($os, $ver = false) + { + $osFullName = array_search($os, self::$osShorts); + if ($osFullName) { + if (in_array($os, self::$osFamilies['Windows'])) { + return $osFullName; + } else { + return trim($osFullName . " " . $ver); + } + } + return false; + } + }
\ No newline at end of file diff --git a/plugins/DevicesDetection/UserAgentParserEnhanced/regexes/browsers.yml b/plugins/DevicesDetection/UserAgentParserEnhanced/regexes/browsers.yml index c9f3a72e5a..0a4d2a6669 100644 --- a/plugins/DevicesDetection/UserAgentParserEnhanced/regexes/browsers.yml +++ b/plugins/DevicesDetection/UserAgentParserEnhanced/regexes/browsers.yml @@ -1,408 +1,408 @@ -###############
-# Piwik - Open source web analytics
-#
-# @link http://piwik.org
-# @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
-#
-# @category Piwik_Plugins
-# @package Piwik_DevicesDetection
-###############
-
-# SeaMonkey
-- regex: '(Iceape|SeaMonkey)/(\d+\.\d+)'
- name: $1
- version: '$2'
-
-# Camino
-- regex: 'Camino/(\d+\.\d+)'
- name: Camino
- version: '$1'
-
-#Fennec (Firefox for mobile)
-- regex: 'Fennec/(\d+\.\d+)'
- name: Fennec
- version: '$1'
-
-#MicroB
-- regex: 'Firefox.*Tablet browser (\d+\.\d+)'
- name: MicroB
- version: '$1'
-
-#Firefox
-- regex: 'Firefox/(\d+\.\d+)'
- name: Firefox
- version: '$1'
-- regex: '(BonEcho|GranParadiso|Lorentz|Minefield|Namoroka|Shiretoko)/(\d+\.\d+)'
- name: Firefox '$1'
- version: '$2'
-
-#Flock
-- regex: 'Flock/(\d+\.\d+)'
- name: Flock
- version: '$1'
-
-#RockMelt
-- regex: 'RockMelt/(\d+\.\d+)'
- name: RockMelt
- version: '$1'
-
-#Netscape
-- regex: '(?:Navigator|Netscape6)/(\d+\.\d+)'
- name: Netscape
- version: '$1'
-
-#Opera
-- regex: '(:?Opera Tablet.*Version|Opera/.+Opera Mobi.+Version|Safari.*OPR)/(\d+\.\d+)'
- name: Opera Mobile
- version: '$2'
-- regex: 'Opera Mini/(:?att/)?(\d+\.\d+)'
- name: Opera Mini
- version: '$2'
-- regex: 'Opera[/ ](?:9.80.*Version/)?(\d+\.\d+)'
- name: Opera
- version: '$1'
-
-#wOSBrowser
-- regex: '(?:hpw|web)OS/(\d+\.\d+)'
- name: wOSBrowser
- version: '$1'
-
-#Swiftfox
-- regex: 'Firefox/(\d+\.\d+).*\(Swiftfox\)'
- name: Swiftfox
- version: '$1'
-
-#Rekonq
-- regex: 'rekonq'
- name: Rekonq
- version: ''
-
-#Conkeror
-- regex: 'Conkeror/(\d+\.\d+)'
- name: Conkeror
- version: '$1'
-
-#Konqueror
-- regex: 'Konqueror/(\d+\.\d+)'
- name: Konqueror
- version: '$1'
-
-#Baidu Browser
-- regex: 'baidubrowser[/ ](\d+)'
- name: Baidu Browser
- version: '$1'
-
-#Yandex Browser
-- regex: 'YaBrowser/(\d+)'
- name: Yandex Browser
- version: '$1'
-
-#Chrome
-- regex: 'CrMo/(\d+\.\d+)'
- name: Chrome Mobile
- version: '$1'
-- regex: 'CriOS/(\d+\.\d+)'
- name: Chrome Mobile iOS
- version: '$1'
-- regex: 'Chrome/(\d+\.\d+).*Mobile'
- name: Chrome Mobile
- version: '$1'
-- regex: 'chromeframe/(\d+\.\d+)'
- name: Chrome Frame
- version: '$1'
-- regex: 'Chrome/(\d+\.\d+)'
- name: Chrome
- version: '$1'
-- regex: 'Chromium/(\d+\.\d+)'
- name: Chromium
- version: '$1'
-
-#UC Browser
-- regex: 'UC[ ]?Browser[ /](\d+\.\d+)'
- name: UC Browser
- version: '$1'
-- regex: '(?:UC Browser|UCBrowser|UCWEB)(\d+\.\d+)'
- name: UC Browser
- version: '$1'
-
-#Tizen Browser
-- regex: '(?:Tizen|SLP) Browser/(\d+\.\d+)'
- name: Tizen Browser
- version: '$1'
-
-#Epiphany
-- regex: 'Epiphany/(\d+\.\d+)'
- name: Epiphany
- version: '$1'
-
-#Fireweb Navigator
-- regex: 'Fireweb Navigator/(\d+\.\d+)'
- name: Fireweb Navigator
- version: '$1'
-
-#Jasmine
-- regex: 'Jasmine[ /](\d+\.\d+)'
- name: Jasmine
- version: '$1'
-
-#Lynx
-- regex: 'Lynx/(\d+\.\d+)'
- name: Lynx
- version: '$1'
-
-#Midori
-- regex: 'Midori/(\d+\.\d+)'
- name: Midori
- version: '$1'
-
-#NCSA Mosaic
-- regex: 'NCSA_Mosaic/(\d+\.\d+)'
- name: NCSA Mosaic
- version: '$1'
-
-#ABrowse
-- regex: 'ABrowse (\d+\.\d+)'
- name: ABrowse
- version: '$1'
-
-#Amaya
-- regex: 'amaya/(\d+\.\d+)'
- name: Amaya
- version: '$1'
-
-#Amiga Voyager
-- regex: 'AmigaVoyager/(\d+\.\d+)'
- name: Amiga Voyager
- version: '$1'
-
-#Amiga Aweb
-- regex: 'Amiga-Aweb/(\d+\.\d+)'
- name: Amiga Aweb
- version: '$1'
-
-#Arora
-- regex: 'Arora/(\d+\.\d+)'
- name: Arora
- version: '$1'
-
-#Beonex
-- regex: 'Beonex/(\d+\.\d+)'
- name: Beonex
- version: '$1'
-
-#BlackBerry Browser
-- regex: 'Black[bB]erry|PlayBook|BB10'
- name: BlackBerry Browser
- version: ''
-
-#BrowseX
-- regex: 'BrowseX \((\d+\.\d+)'
- name: BrowseX
- version: '$1'
-
-#Cheshire
-- regex: 'Cheshire/(\d+\.\d+)'
- name: Cheshire
- version: '$1'
-
-#CometBird
-- regex: 'CometBird/(\d+\.\d+)'
- name: CometBird
- version: '$1'
-
-#Dillo
-- regex: 'Dillo/(\d+\.\d+)'
- name: Dillo
- version: '$1'
-
-#Dolphin
-- regex: 'Dolfin/(\d+\.\d+)|dolphin'
- name: Dolphin
- version: '$1'
-
-#Elinks
-- regex: 'Elinks/(\d+\.\d+)'
- name: Elinks
- version: '$1'
-
-#Firebird
-- regex: 'Firebird/(\d+\.\d+)'
- name: Firebird
- version: '$1'
-
-#Fluid
-- regex: 'Fluid/(\d+\.\d+)'
- name: Fluid
- version: '$1'
-
-#Galeon
-- regex: 'Galeon/(\d+\.\d+)'
- name: Galeon
- version: '$1'
-
-#Google Earth
-- regex: 'Google Earth/(\d+\.\d+)'
- name: Google Earth
- version: '$1'
-
-#HotJava
-- regex: 'HotJava/(\d+\.\d+)'
- name: HotJava
- version: '$1'
-
-#IBrowse
-- regex: 'IBrowse[ /](\d+\.\d+)'
- name: IBrowse
- version: '$1'
-
-#iCab
-- regex: 'iCab[ /](\d+\.\d+)'
- name: iCab
- version: '$1'
-
-#Internet Explorer
-- regex: 'IEMobile[ /](\d+\.\d+)'
- name: IE Mobile
- version: '$1'
-- regex: 'MSIE (\d+\.\d+).*XBLWP7'
- name: IE Mobile
- version: '$1'
-- regex: 'MSIE (\d+\.\d+)'
- name: Internet Explorer
- version: '$1'
-
-#Iron
-- regex: 'Iron/(\d+\.\d+)'
- name: Iron
- version: '$1'
-
-#Kapiko
-- regex: 'Kapiko/(\d+\.\d+)'
- name: Kapiko
- version: '$1'
-
-#Kazehakase
-- regex: 'Kazehakase/(\d+\.\d+)'
- name: Kazehakase
- version: '$1'
-
-#Kindle Browser
-- regex: 'Kindle/(\d+\.\d+)'
- name: Kindle Browser
- version: '$1'
-
-#K-meleon
-- regex: 'K-meleon/(\d+\.\d+)'
- name: K-meleon
- version: '$1'
-
-#Lightning
-- regex: 'Lightning/(\d+\.\d+)'
- name: Lightning
- version: '$1'
-
-#Links
-- regex: 'Links \((\d+\.\d+)'
- name: Links
- version: '$1'
-
-#Maxthon
-- regex: 'Maxthon (\d+\.\d+)'
- name: Maxthon
- version: '$1'
-- regex: '(?:Maxthon|MyIE2|Uzbl|Shiira)'
- name: Maxthon
- version: ''
-
-#Openwave Mobile Browser
-- regex: 'UP.Browser/(\d+\.\d+)'
- name: Openwave Mobile Browser
- version: '$1'
-
-#OmniWeb
-- regex: 'OmniWeb/[v]?(\d+\.\d+)'
- name: OmniWeb
- version: '$1'
-
-#Phoenix
-- regex: 'Phoenix/(\d+\.\d+)'
- name: Phoenix
- version: '$1'
-
-#Mobile Silk
-- regex: 'Silk/(\d+\.\d+)'
- name: Mobile Silk
- version: '$1'
-
-#Nokia Browser
-- regex: '(?:NokiaBrowser|BrowserNG)/(\d+\.\d+)'
- name: Nokia Browser
- version: '$1'
-- regex: 'Series60/5\.0'
- name: Nokia Browser
- version: '7.0'
-- regex: 'Series60/(\d+\.\d+)'
- name: Nokia OSS Browser
- version: '$1'
-- regex: 'S40OviBrowser/(\d+\.\d+)'
- name: Nokia Ovi Browser
- version: '$1'
-- regex: '^Nokia|Nokia[EN]?\d+'
- name: Nokia Browser
- version: ''
-
-#NetFront
-- regex: 'NetFrontLifeBrowser/(\d+\.\d+)'
- name: NetFront Life
- version: '$1'
-- regex: 'NetFront/(\d+\.\d+)'
- name: NetFront
- version: '$1'
-- regex: 'PLAYSTATION|NINTENDO 3|AppleWebKit.+ NX/\d+\.\d+\.\d+'
- name: NetFront
- version: ''
-
-#Obigo
-- regex: 'Obigo[ ]?(?:InternetBrowser|Browser)?[ /]([A-Za-z0-9]*)'
- name: Obigo
- version: '$1'
-- regex: 'Obigo|Teleca'
- name: Obigo
- version: ''
-
-#Palm Blazer
-- regex: 'Blazer/(\d+\.\d+)'
- name: Palm Blazer
- version: '$1'
-- regex: 'Pre/(\d+\.\d+)'
- name: Palm Pre
- version: '$1'
-
-#Polaris
-- regex: '(?:Polaris|Embider)/(\d+\.\d+)'
- name: Polaris
- version: '$1'
-
-#Snowshoe
-- regex: 'Snowshoe/(\d+\.\d+)'
- name: Snowshoe
- version: '$1'
-
-#Safari
-- regex: '(?:iPod|iPad|iPhone).+Version/(\d+\.\d+)'
- name: Mobile Safari
- version: '$1'
-- regex: 'Version/(\d+\.\d+).*Mobile.*Safari/'
- name: Mobile Safari
- version: '$1'
-- regex: '(?:iPod|iPhone|iPad)'
- name: Mobile Safari
- version: ''
-- regex: 'Version/(\d+\.\d+).*Safari/|Safari/\d+'
- name: Safari
- version: '$1'
-
-#Android Browser
-- regex: 'Android'
- name: Android Browser
+############### +# Piwik - Open source web analytics +# +# @link http://piwik.org +# @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later +# +# @category Piwik_Plugins +# @package Piwik_DevicesDetection +############### + +# SeaMonkey +- regex: '(Iceape|SeaMonkey)/(\d+\.\d+)' + name: $1 + version: '$2' + +# Camino +- regex: 'Camino/(\d+\.\d+)' + name: Camino + version: '$1' + +#Fennec (Firefox for mobile) +- regex: 'Fennec/(\d+\.\d+)' + name: Fennec + version: '$1' + +#MicroB +- regex: 'Firefox.*Tablet browser (\d+\.\d+)' + name: MicroB + version: '$1' + +#Firefox +- regex: 'Firefox/(\d+\.\d+)' + name: Firefox + version: '$1' +- regex: '(BonEcho|GranParadiso|Lorentz|Minefield|Namoroka|Shiretoko)/(\d+\.\d+)' + name: Firefox '$1' + version: '$2' + +#Flock +- regex: 'Flock/(\d+\.\d+)' + name: Flock + version: '$1' + +#RockMelt +- regex: 'RockMelt/(\d+\.\d+)' + name: RockMelt + version: '$1' + +#Netscape +- regex: '(?:Navigator|Netscape6)/(\d+\.\d+)' + name: Netscape + version: '$1' + +#Opera +- regex: '(:?Opera Tablet.*Version|Opera/.+Opera Mobi.+Version|Safari.*OPR)/(\d+\.\d+)' + name: Opera Mobile + version: '$2' +- regex: 'Opera Mini/(:?att/)?(\d+\.\d+)' + name: Opera Mini + version: '$2' +- regex: 'Opera[/ ](?:9.80.*Version/)?(\d+\.\d+)' + name: Opera + version: '$1' + +#wOSBrowser +- regex: '(?:hpw|web)OS/(\d+\.\d+)' + name: wOSBrowser + version: '$1' + +#Swiftfox +- regex: 'Firefox/(\d+\.\d+).*\(Swiftfox\)' + name: Swiftfox + version: '$1' + +#Rekonq +- regex: 'rekonq' + name: Rekonq + version: '' + +#Conkeror +- regex: 'Conkeror/(\d+\.\d+)' + name: Conkeror + version: '$1' + +#Konqueror +- regex: 'Konqueror/(\d+\.\d+)' + name: Konqueror + version: '$1' + +#Baidu Browser +- regex: 'baidubrowser[/ ](\d+)' + name: Baidu Browser + version: '$1' + +#Yandex Browser +- regex: 'YaBrowser/(\d+)' + name: Yandex Browser + version: '$1' + +#Chrome +- regex: 'CrMo/(\d+\.\d+)' + name: Chrome Mobile + version: '$1' +- regex: 'CriOS/(\d+\.\d+)' + name: Chrome Mobile iOS + version: '$1' +- regex: 'Chrome/(\d+\.\d+).*Mobile' + name: Chrome Mobile + version: '$1' +- regex: 'chromeframe/(\d+\.\d+)' + name: Chrome Frame + version: '$1' +- regex: 'Chrome/(\d+\.\d+)' + name: Chrome + version: '$1' +- regex: 'Chromium/(\d+\.\d+)' + name: Chromium + version: '$1' + +#UC Browser +- regex: 'UC[ ]?Browser[ /](\d+\.\d+)' + name: UC Browser + version: '$1' +- regex: '(?:UC Browser|UCBrowser|UCWEB)(\d+\.\d+)' + name: UC Browser + version: '$1' + +#Tizen Browser +- regex: '(?:Tizen|SLP) Browser/(\d+\.\d+)' + name: Tizen Browser + version: '$1' + +#Epiphany +- regex: 'Epiphany/(\d+\.\d+)' + name: Epiphany + version: '$1' + +#Fireweb Navigator +- regex: 'Fireweb Navigator/(\d+\.\d+)' + name: Fireweb Navigator + version: '$1' + +#Jasmine +- regex: 'Jasmine[ /](\d+\.\d+)' + name: Jasmine + version: '$1' + +#Lynx +- regex: 'Lynx/(\d+\.\d+)' + name: Lynx + version: '$1' + +#Midori +- regex: 'Midori/(\d+\.\d+)' + name: Midori + version: '$1' + +#NCSA Mosaic +- regex: 'NCSA_Mosaic/(\d+\.\d+)' + name: NCSA Mosaic + version: '$1' + +#ABrowse +- regex: 'ABrowse (\d+\.\d+)' + name: ABrowse + version: '$1' + +#Amaya +- regex: 'amaya/(\d+\.\d+)' + name: Amaya + version: '$1' + +#Amiga Voyager +- regex: 'AmigaVoyager/(\d+\.\d+)' + name: Amiga Voyager + version: '$1' + +#Amiga Aweb +- regex: 'Amiga-Aweb/(\d+\.\d+)' + name: Amiga Aweb + version: '$1' + +#Arora +- regex: 'Arora/(\d+\.\d+)' + name: Arora + version: '$1' + +#Beonex +- regex: 'Beonex/(\d+\.\d+)' + name: Beonex + version: '$1' + +#BlackBerry Browser +- regex: 'Black[bB]erry|PlayBook|BB10' + name: BlackBerry Browser + version: '' + +#BrowseX +- regex: 'BrowseX \((\d+\.\d+)' + name: BrowseX + version: '$1' + +#Cheshire +- regex: 'Cheshire/(\d+\.\d+)' + name: Cheshire + version: '$1' + +#CometBird +- regex: 'CometBird/(\d+\.\d+)' + name: CometBird + version: '$1' + +#Dillo +- regex: 'Dillo/(\d+\.\d+)' + name: Dillo + version: '$1' + +#Dolphin +- regex: 'Dolfin/(\d+\.\d+)|dolphin' + name: Dolphin + version: '$1' + +#Elinks +- regex: 'Elinks/(\d+\.\d+)' + name: Elinks + version: '$1' + +#Firebird +- regex: 'Firebird/(\d+\.\d+)' + name: Firebird + version: '$1' + +#Fluid +- regex: 'Fluid/(\d+\.\d+)' + name: Fluid + version: '$1' + +#Galeon +- regex: 'Galeon/(\d+\.\d+)' + name: Galeon + version: '$1' + +#Google Earth +- regex: 'Google Earth/(\d+\.\d+)' + name: Google Earth + version: '$1' + +#HotJava +- regex: 'HotJava/(\d+\.\d+)' + name: HotJava + version: '$1' + +#IBrowse +- regex: 'IBrowse[ /](\d+\.\d+)' + name: IBrowse + version: '$1' + +#iCab +- regex: 'iCab[ /](\d+\.\d+)' + name: iCab + version: '$1' + +#Internet Explorer +- regex: 'IEMobile[ /](\d+\.\d+)' + name: IE Mobile + version: '$1' +- regex: 'MSIE (\d+\.\d+).*XBLWP7' + name: IE Mobile + version: '$1' +- regex: 'MSIE (\d+\.\d+)' + name: Internet Explorer + version: '$1' + +#Iron +- regex: 'Iron/(\d+\.\d+)' + name: Iron + version: '$1' + +#Kapiko +- regex: 'Kapiko/(\d+\.\d+)' + name: Kapiko + version: '$1' + +#Kazehakase +- regex: 'Kazehakase/(\d+\.\d+)' + name: Kazehakase + version: '$1' + +#Kindle Browser +- regex: 'Kindle/(\d+\.\d+)' + name: Kindle Browser + version: '$1' + +#K-meleon +- regex: 'K-meleon/(\d+\.\d+)' + name: K-meleon + version: '$1' + +#Lightning +- regex: 'Lightning/(\d+\.\d+)' + name: Lightning + version: '$1' + +#Links +- regex: 'Links \((\d+\.\d+)' + name: Links + version: '$1' + +#Maxthon +- regex: 'Maxthon (\d+\.\d+)' + name: Maxthon + version: '$1' +- regex: '(?:Maxthon|MyIE2|Uzbl|Shiira)' + name: Maxthon + version: '' + +#Openwave Mobile Browser +- regex: 'UP.Browser/(\d+\.\d+)' + name: Openwave Mobile Browser + version: '$1' + +#OmniWeb +- regex: 'OmniWeb/[v]?(\d+\.\d+)' + name: OmniWeb + version: '$1' + +#Phoenix +- regex: 'Phoenix/(\d+\.\d+)' + name: Phoenix + version: '$1' + +#Mobile Silk +- regex: 'Silk/(\d+\.\d+)' + name: Mobile Silk + version: '$1' + +#Nokia Browser +- regex: '(?:NokiaBrowser|BrowserNG)/(\d+\.\d+)' + name: Nokia Browser + version: '$1' +- regex: 'Series60/5\.0' + name: Nokia Browser + version: '7.0' +- regex: 'Series60/(\d+\.\d+)' + name: Nokia OSS Browser + version: '$1' +- regex: 'S40OviBrowser/(\d+\.\d+)' + name: Nokia Ovi Browser + version: '$1' +- regex: '^Nokia|Nokia[EN]?\d+' + name: Nokia Browser + version: '' + +#NetFront +- regex: 'NetFrontLifeBrowser/(\d+\.\d+)' + name: NetFront Life + version: '$1' +- regex: 'NetFront/(\d+\.\d+)' + name: NetFront + version: '$1' +- regex: 'PLAYSTATION|NINTENDO 3|AppleWebKit.+ NX/\d+\.\d+\.\d+' + name: NetFront + version: '' + +#Obigo +- regex: 'Obigo[ ]?(?:InternetBrowser|Browser)?[ /]([A-Za-z0-9]*)' + name: Obigo + version: '$1' +- regex: 'Obigo|Teleca' + name: Obigo + version: '' + +#Palm Blazer +- regex: 'Blazer/(\d+\.\d+)' + name: Palm Blazer + version: '$1' +- regex: 'Pre/(\d+\.\d+)' + name: Palm Pre + version: '$1' + +#Polaris +- regex: '(?:Polaris|Embider)/(\d+\.\d+)' + name: Polaris + version: '$1' + +#Snowshoe +- regex: 'Snowshoe/(\d+\.\d+)' + name: Snowshoe + version: '$1' + +#Safari +- regex: '(?:iPod|iPad|iPhone).+Version/(\d+\.\d+)' + name: Mobile Safari + version: '$1' +- regex: 'Version/(\d+\.\d+).*Mobile.*Safari/' + name: Mobile Safari + version: '$1' +- regex: '(?:iPod|iPhone|iPad)' + name: Mobile Safari + version: '' +- regex: 'Version/(\d+\.\d+).*Safari/|Safari/\d+' + name: Safari + version: '$1' + +#Android Browser +- regex: 'Android' + name: Android Browser version: ''
\ No newline at end of file diff --git a/plugins/DevicesDetection/UserAgentParserEnhanced/regexes/mobiles.yml b/plugins/DevicesDetection/UserAgentParserEnhanced/regexes/mobiles.yml index 64b1470ef2..d9a2a22f88 100644 --- a/plugins/DevicesDetection/UserAgentParserEnhanced/regexes/mobiles.yml +++ b/plugins/DevicesDetection/UserAgentParserEnhanced/regexes/mobiles.yml @@ -1,958 +1,958 @@ -###############
-# Piwik - Open source web analytics
-#
-# @link http://piwik.org
-# @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
-#
-# @category Piwik_Plugins
-# @package Piwik_DevicesDetection
-###############
-
-# HTC
-HTC:
- regex: 'HTC|Sprint APA|ADR[A-Za-z0-9]+'
- device: 'smartphone'
- models:
- - regex: 'HTC ([A-Za-z0-9]+) Build'
- model: '$1'
- - regex: 'HTC ([A-Za-z0-9]+(?: [A-Za-z0-9]+)?)'
- model: '$1'
- - regex: 'USCCHTC(\d+)'
- model: '$1'
- - regex: 'Sprint APA(9292)'
- model: '$1 (Sprint)'
- - regex: 'HTC_([A-Za-z0-9_]+)'
- model: '$1'
- - regex: 'HTC(?:[\-/ ])?([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'HTC;(?: )?([A-Za-z0-9 ]+)'
- model: '$1'
- - regex: '(ADR[A-Za-z0-9]+)'
- model: '$1'
-
-# Tesla Model S
-Tesla:
- regex: 'QtCarBrowser'
- device: 'car browser'
- model: 'Model S'
-
-# Kindle
-Kindle:
- regex: 'KF(?:OT|TT|JWI|JWA) Build|Kindle|Silk/(\d+)\.(\d+)'
- device: 'tablet'
- models:
- - regex: 'KFOT|Kindle Fire|Silk/(\d+)\.(\d+)'
- model: 'Fire'
- - regex: 'KFTT'
- model: 'Fire HD'
- - regex: 'KFJWI'
- model: 'Fire HD 8.9" WiFi'
- - regex: 'KFJWA'
- model: 'Fire HD 8.9" 4G'
-
-# NOKIA
-Nokia:
- regex: 'Nokia|Lumia|Maemo RX|portalmmm/2\.0 N7|portalmmm/2\.0 NK|nok[0-9]+|Symbian.*\s([a-zA-Z0-9]+)$'
- device: 'smartphone'
- models:
- - regex: 'NokiaInternal|Nokia-WAP-Toolkit|Nokia-MIT-Browser|Nokia Mobile|Nokia Browser|Nokia/Series'
- model: ''
- - regex: 'Nokia(N[0-9]+)'
- model: '$1'
- - regex: 'Nokia-([A-Za-z0-9]+)'
- model: 'N$1'
- - regex: 'NOKIA; ([A-Za-z0-9\- ]+)'
- model: '$1'
- - regex: 'NOKIA[ ]?([A-Za-z0-9\-]+)'
- model: '$1'
- - regex: 'NOKIA/([A-Za-z0-9 ]+)'
- model: '$1'
- - regex: '(Lumia [A-Za-z0-9\-]+)'
- model: '$1'
- - regex: 'Maemo RX-51 ([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'Maemo RX-34'
- model: 'N800'
- - regex: 'portalmmm/2\.0 (N7[37]|NK[A-Za-z0-9]+)'
- model: '$1'
- - regex: 'nok([0-9]+)'
- model: '$1'
- - regex: 'Symbian.*\s([a-zA-Z0-9]+)$'
- device: 'feature phone'
- model: '$1'
-
-# RIM/BlackBerry
-RIM:
- regex: 'BB10;|BlackBerry|rim[0-9]+|PlayBook'
- device: 'smartphone'
-
- models:
- - regex: 'BB10; ([A-Za-z0-9\- ]+)\)'
- model: 'BlackBerry $1'
- - regex: 'PlayBook.+RIM Tablet OS'
- model: 'BlackBerry Playbook'
- device: 'tablet'
- - regex: 'BlackBerry(?: )?([A-Za-z0-9]+)'
- model: 'BlackBerry $1'
- - regex: 'rim([0-9]+)'
- model: 'BlackBerry $1'
- - regex: 'BlackBerry'
- model: 'BlackBerry'
-
-# PALM
-Palm:
- regex: '(?:Pre|Pixi)/(\d+)\.(\d+)|Palm|Treo'
- device: 'smartphone'
- models:
- - regex: '((?:Pre|Pixi))/(\d+\.\d+)'
- model: '$1 $2'
- - regex: 'Palm(?: )?([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'Treo([A-Za-z0-9]+)'
- model: 'Treo $1'
-
-# HP
-HP:
- regex: 'Touch[Pp]ad|hp-tablet|HP(?: )?iPAQ|webOS.*(P160U)'
- device: 'smartphone'
- models:
- - regex: 'Touch[Pp]ad/(\d+\.\d+)|hp-tablet'
- model: 'TouchPad'
- device: 'tablet'
- - regex: 'HP(?: )?iPAQ(?: )?([A-Za-z0-9]+)'
- model: 'iPAQ $1'
- - regex: 'webOS.*(P160U)'
- model: 'Veer'
-
-# TiPhone
-TiPhone:
- regex: 'TiPhone(?: )?([A-Za-z0-9]+)'
- device: 'smartphone'
- model: '$1'
-
-# Apple
-Apple:
- regex: 'AppleTV|iPad|iPod|iPhone'
- models:
- - regex: 'AppleTV'
- model: 'Apple TV'
- device: 'tv'
- - regex: 'iPad'
- model: 'iPad'
- device: 'tablet'
- - regex: 'iPod'
- model: 'iPod Touch'
- device: 'palmtop'
- - regex: 'iPhone'
- model: 'iPhone'
- device: 'smartphone'
-
-# Acer
-Acer:
- regex: 'acer[\-_]([A-Za-z0-9]+)'
- device: 'smartphone'
- model: '$1'
-
-# Airness
-Airness:
- regex: 'AIRNESS-([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Alcatel
-Alcatel:
- regex: 'Alcatel|Alc([A-Za-z0-9]+)'
- device: 'smartphone'
- models:
- - regex: 'Alcatel UP'
- model: ''
- - regex: 'ALCATEL[ \-]([A-Za-z0-9\-]+)'
- model: '$1'
- - regex: 'ALCATEL_([A-Za-z0-9_]+)'
- model: '$1'
- - regex: 'Alc([A-Za-z0-9]+)'
- model: '$1'
-
-# Amoi
-Amoi:
- regex: 'Amoi'
- device: 'smartphone'
- models:
- - regex: 'Amoi[\- /](A-Za-z0-9]+)'
- mobile: '$1'
- - regex: 'Amoisonic-([A-Za-z0-9]+)'
- model: '$1'
-
-# Asus
-Asus:
- regex: 'Asus'
- device: 'smartphone'
- models:
- - regex: 'Asus(?:-|;)?([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'ASUS (Transformer Pad TF300T)'
- device: 'tablet'
- model: '$1'
-
-# Audiovox
-Audiovox:
- regex: 'Audiovox|CDM|UTS(?:TARCOM)?\-|audio([A-Za-z0-9\-]+)'
- device: 'smartphone'
- models:
- - regex: 'Audiovox[_\-]([A-Za-z0-9\-]+)'
- model: '$1'
- - regex: 'CDM(?:-)?([A-Za-z0-9]+)'
- model: 'CDM-$1'
- - regex: 'UTS(?:TARCOM)?-([A-Za-z0-9\-]+)'
- model: 'CDM-$1'
- - regex: 'audio([A-Za-z0-9\-]+)'
- model: 'CDM-$1'
-
-# Avvio
-Avvio:
- regex: 'Avvio[ _]([A-Za-z0-9\-]+)'
- device: 'smartphone'
- model: '$1'
-
-# Bird
-Bird:
- regex: 'BIRD[\-. _]([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Becker
-Becker:
- regex: 'Becker-([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Beetel
-Beetel:
- regex: 'Beetel ([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# BenQ-Siemens
-BenQ-Siemens:
- regex: 'BENQ-SIEMENS - ([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# BenQ
-BenQ:
- regex: 'BENQ(?:[ \-])?([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Capitel
-Capitel:
- regex: 'Capitel-([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Compal
-Compal:
- regex: 'Compal-([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Cricket
-Cricket:
- regex: 'Cricket-([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Dell
-Dell:
- regex: 'Dell ([A-Za-z0-9]+)'
- device: 'smartphone'
- model: '$1'
-
-# Dbtel
-Dbtel:
- regex: 'DBTEL(?:[\-/])?([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Dicam
-Dicam:
- regex: 'DICAM-([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# DoCoMo
-DoCoMo:
- regex: 'DoCoMo|\;FOMA|KGT/1\.0'
- device: 'feature phone'
- models:
- - regex: 'DoCoMo/[12]\.0[/ ]([A-Za-z0-9]+)'
- model: '$1'
- - regex: '([A-Za-z0-9]+)(?:_W)?\;FOMA'
- model: '$1'
- - regex: 'KGT/1\.0 ([A-Za-z0-9]+)'
- model: '$1'
-
-# Dopod
-Dopod:
- regex: 'Dopod(?: )?([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Ericy
-Ericy:
- regex: 'Ericy-([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Sony Ericsson
-Sony Ericsson:
- regex: 'Sony(?: )?Ericsson|portalmmm/2\.0 K'
- device: 'smartphone'
- models:
- - regex: 'SonyEricsson([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'Sony(?: )?Ericsson ([A-Za-z0-9\-]+)'
- model: '$1'
- - regex: 'portalmmm/2.0 K([A-Za-z0-9]+)'
- model: 'K$1'
-
-# Ericsson
-Ericsson:
- regex: 'Ericsson(?:/ )?([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# eTouch
-eTouch:
- regex: 'eTouch(?: )?([A-Za-z0-9]+)'
- device: 'smartphone'
- model: '$1'
-
-# Ezze
-Ezze:
- regex: 'EZZE-|EZ([A-Za-z0-9]+)'
- device: 'feature phone'
- models:
- - regex: 'EZZE-([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'EZ([A-Za-z0-9]+)'
- model: 'EZ$1'
-
-# Ezio
-Ezio:
- regex: 'EZIO-([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Gionee
-Gionee:
- regex: 'GIONEE-([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Google
-Google:
- regex: 'Nexus|GoogleTV'
- device: 'smartphone'
- models:
- - regex: '(Galaxy Nexus)'
- model: '$1'
- - regex: '(Nexus (:?S|4|One))'
- model: '$1'
- - regex: '(Nexus (:?7|10))'
- device: 'tablet'
- model: '$1'
- - regex: '(GoogleTV)'
- device: 'tv'
- model: '$1'
-
-# Gradiente
-Gradiente:
- regex: 'GRADIENTE'
- device: 'feature phone'
- models:
- - regex: 'GRADIENTE-([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'GRADIENTE ([A-Za-z0-9\-]+)'
- model: '$1'
-
-# Grundig
-Grundig:
- regex: 'GRUNDIG|portalmmm/2\.0 G'
- device: 'tv'
- models:
- - regex: 'GRUNDIG ([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'portalmmm/2\.0 G([A-Za-z0-9]+)'
- model: 'G$1'
-
-# Haier
-Haier:
- regex: 'Haier[ -]([A-Za-z0-9\-]+)'
- device: 'feature phone'
- model: '$1'
-
-# Huawei
-Huawei:
- regex: 'Huawei|vodafone([A-Za-z0-9]+)'
- device: 'smartphone'
- models:
- - regex: 'Huawei(?:[\- /_]|/1\.0/)?([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'vodafone([A-Za-z0-9]+)'
- model: 'Vodafone $1'
-
-# Innostream
-Innostream:
- regex: 'INNO([A-Za-z0-9]+)'
- device: 'feature phone'
- model: 'INNO$1'
-
-# Inq
-INQ:
- regex: 'INQ/([A-Za-z0-9\-]+)'
- device: 'feature phone'
- model: '$1'
-
-# i-mate
-i-mate:
- regex: 'i-mate ([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# i-mobile
-i-mobile:
- regex: 'i-mobile(?: )?([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# ikomo
-iKoMo:
- regex: 'iKoMo ([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# kddi
-KDDI:
- regex: 'kddi-([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# kyocera
-Kyocera:
- regex: 'Kyocera|KWC-|QC-'
- device: 'smartphone'
- models:
- - regex: 'Kyocera-KZ-([A-Za-z0-9]+)'
- model: 'KZ $1'
- - regex: 'Kyocera(:?[\-/])?([A-Za-z0-9]+)'
- model: '$1'
- - regex: '(?:KWC|QC)-([A-Za-z0-9]+)'
- model: '$1'
-
-# lanix
-Lanix:
- regex: 'LANIX-([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# lct
-LCT:
- regex: 'LCT_([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# lenovo
-Lenovo:
- regex: 'Lenovo[\-_]([A-Za-z0-9]+)'
- device: 'smartphone'
- model: '$1'
-
-# lguplus
-LGUPlus:
- regex: 'LGUPlus'
- device: 'smartphone'
- model: ''
-
-# lg
-LG:
- regex: 'LG|portalmmm/2\.0 (?:KE|KG|KP|L3)|VX[0-9]+'
- device: 'smartphone'
- models:
- - regex: 'LGE_DLNA_SDK'
- device: 'tv'
- model: 'NetCast'
- - regex: 'LGE(?: |-LG| LG-AX|-)([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'LGE;([A-Za-z0-9\-]+)'
- model: '$1'
- - regex: 'LG(?:/|-LG| |-)?([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'LG; ([A-Za-z0-9 ]+)'
- model: '$1'
- - regex: 'portalmmm/2.0 ((?:KE|KG|KP|L3)[A-Za-z0-9]+)'
- model: '$1'
- - regex: '(VX[0-9]+)'
- model: '$1'
-
-# microsoft
-Microsoft:
- regex: 'Xbox|KIN\.(?:One|Two)'
- device: 'console'
- model: 'Xbox 360'
-
-# Konka
-Konka:
- regex: 'KONKA_([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Karbonn
-Karbonn:
- regex: 'Karbonn_([A-Za-z0-9]+)'
- device: 'smartphone'
- model: '$1'
-
-# Sagem
-Sagem:
- regex: 'SAGEM|portalmmm/2.0 (?:SG|my)'
- device: 'smartphone'
- models:
- - regex: 'SAGEM ([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'SAGEM-([A-Za-z0-9\-]+)'
- model: '$1'
- - regex: 'portalmmm/2.0 ((?:SG|my)[A-Za-z0-9]+)'
- model: '$1'
-
-# micromax
-MicroMax:
- regex: 'MicroMax(?:[ \-])?([A-Za-z0-9]+)'
- device: 'smartphone'
- model: '$1'
-
-# mio
-Mio:
- regex: 'MIO(?:/)?([A-Za-z0-9]+)'
- device: 'smartphone'
- model: '$1'
-
-# mitsubishi
-Mitsubishi:
- regex: 'MITSU|portalmmm/[12]\.0 M'
- device: 'feature phone'
- models:
- - regex: 'MITSU/[A-Za-z0-9.]+ \(([A-Za-z0-9]+)\)'
- model: '$1'
- - regex: 'MITSU[ \-]?([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'portalmmm/[12]\.0 (M[A-Za-z0-9]+)'
- model: '$1'
-
-# motorola
-Motorola:
- regex: 'MOT|(?<!AN)DROID (?:Build|([A-Za-z0-9]+))|portalmmm/2.0 (?:E378i|L6|L7|v3)'
- device: 'smartphone'
- models:
- - regex: 'Motorola[ \-]([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'MOTORAZR[ \-]([A-Za-z0-9]+)'
- model: 'RAZR $1'
- - regex: 'MOTORIZR[ \-]([A-Za-z0-9]+)'
- model: 'RIZR $1'
- - regex: 'MOT[O]?[\-]?([A-Za-z0-9.]+)'
- model: '$1'
- - regex: '(?<!AN)DROID (?:Build|([A-Za-z0-9]+))'
- model: 'DROID $1'
- - regex: 'portalmmm/2.0 ((?:E378i|L6|L7|V3)[A-Za-z0-9]+)'
- model: '$1'
-
-# myphone
-MyPhone:
- regex: 'MyPhone([A-Za-z0-9]+)'
- device: 'smartphone'
- model: '$1'
-
-# nec
-NEC:
- regex: 'NEC|KGT/2\.0|portalmmm/1\.0 (?:DB|N)|(?:portalmmm|o2imode)/2.0[ ,]N'
- device: 'smartphone'
- models:
- - regex: '(?:NEC-|KGT/2\.0 )([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'portalmmm/1\.0 ((?:DB|N)[A-Za-z0-9]+)'
- model: '$1'
- - regex: '(?:portalmmm|o2imode)/2\.0[ ,](N[A-Za-z0-9]+)'
- model: '$1'
-
-# newgen
-Newgen:
- regex: 'NEWGEN\-([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# nintendo
-Nintendo:
- regex: 'Nintendo (([3]?DS[i]?)|Wii[U]?)'
- device: 'console'
- model: '$1'
-
-# ngm
-NGM:
- regex: 'NGM_([A-Za-z0-9]+)'
- device: 'smartphone'
- model: '$1'
-
-# nexian
-Nexian:
- regex: 'Nexian'
- device: 'smartphone'
- models:
- - regex: 'Nexian[ ]?([A-Za-z0-9\-]+)'
- model: '$1'
- - regex: 'Nexian-([A-Za-z0-9]+)'
- model: '$1'
-
-# o2
-O2:
- regex: 'Xda|O2[ \-]|COCOON'
- device: 'smartphone'
- models:
- - regex: '(Xda[ _][A-Za-z0-9_]+)'
- models: '$1'
- - regex: '(COCOON)'
- models: '$1'
- - regex: 'O2 ([A-Za-z0-9 ]+)'
- models: '$1'
- - regex: 'O2-([A-Za-z0-9]+)'
- models: '$1'
-
-# onda
-Onda:
- regex: 'Onda'
- device: 'smartphone'
- models:
- regex: '([A-Za-z0-9]+)[ _]Onda'
- model: '$1'
- regex: 'Onda ([A-Za-z0-9]+)'
- model: '$1'
-
-# oppo
-OPPO:
- regex: 'OPPO[ ]?([A-Za-z0-9]+)'
- device: 'smartphone'
- model: '$1'
-
-# orange
-Orange:
- regex: 'SPV[ \-]?([A-Za-z0-9]+)'
- device: 'smartphone'
- model: 'SPV $1'
-
-# panasonic
-Panasonic:
- regex: 'Panasonic'
- device: 'smartphone'
- models:
- - regex: 'Panasonic MIL DLNA'
- device: 'tv'
- model: 'Viera Cast'
- - regex: 'Panasonic[ \-]?([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'portalmmm/2.0 (P[A-Za-z0-9]+)'
- model: '$1'
-
-# philips
-Philips:
- regex: 'Philips'
- device: 'smartphone'
- models:
- - regex: 'Philips-FISIO ([A-Za-z0-9]+)'
- model: 'Fisio $1'
- - regex: 'Philips[ ]?([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'Philips-([A-Za-z0-9\-@]+)'
- model: '$1'
-
-# phoneOne
-phoneOne:
- regex: 'phoneOne[ \-]?([A-Za-z0-9]+)'
- device: 'smartphone'
- model: '$1'
-
-# Rover
-Rover:
- regex: 'Rover ([0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Siemens
-Siemens:
- regex: 'SIEMENS|SIE-|portalmmm/2\.0 SI|S55|SL45i'
- device: 'smartphone'
- models:
- - regex: 'SIEMENS[ \-]([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'SIE(?:MENS )?[\-]?([A-Za-z0-9]+)'
- model: '$1'
- - regex: '(S55|SL45i)'
- model: '$1'
- - regex: 'portalmmm/2.0 (SI[A-Za-z0-9]+)'
- model: '$1'
-
-# Samsung
-Samsung:
- regex: 'SAMSUNG|S(?:CH|GH|PH|EC|AM)-|SMART-TV|GT-|Galaxy|(?:portalmmm|o2imode)/2\.0 [SZ]|sam[rua]'
- device: 'smartphone'
- models:
- - regex: 'SAMSUNG[\-;][ ]?([A-Za-z0-9]+[\-_][A-Za-z0-9]+)'
- model: '$1'
- - regex: 'SAMSUNG[ _/]?([A-Za-z0-9\-]+)'
- model: '$1'
- - regex: 'SAMSUNG;[ ]?([A-Za-z0-9 ]+)'
- model: '$1'
- - regex: '((?:SCH|SGH|SPH|GT)-[A-Za-z0-9]+)'
- model: '$1'
- - regex: 'SEC-([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'SAM-([A-Za-z0-9]+)'
- model: 'SCH-$1'
- - regex: 'SMART-TV'
- device: 'tv'
- model: 'Smart TV'
- - regex: '(Galaxy [A-Za-z0-9]+)'
- model: '$1'
- - regex: '(?:portalmmm|o2imode)/2\.0 ([SZ][A-Za-z0-9]+)'
- model: '$1'
- - regex: 'sam([rua][0-9]+)'
- model: 'SCH-$1'
-
-# pantech
-Pantech:
- regex: 'Pantech|P[GTN]-|TX[T]?[0-9]+'
- device: 'smartphone'
- models:
- - regex: 'Pantech[ \-]?([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'Pantech_([A-Za-z0-9\-]+)'
- model: '$1'
- - regex: '(P[GTN]-[A-Za-z0-9]+)'
- model: '$1'
- - regex: '(TX[T]?[0-9]+)'
- model: '$1'
-
-# Sanyo
-Sanyo:
- regex: 'Sanyo|MobilePhone '
- device: 'smartphone'
- models:
- - regex: 'SANYO[ \-_]([A-Za-z0-9\-]+)'
- model: '$1'
- - regex: 'MobilePhone ([A-Za-z0-9\-]+)'
- model: '$1'
-
-# Sega
-Sega:
- regex: 'Dreamcast'
- device: 'console'
- model: 'Dreamcast'
-
-# Sendo
-Sendo:
- regex: 'Sendo([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Spice
-Spice:
- regex: 'Spice'
- device: 'smartphone'
- models:
- - regex: 'Spice ([A-Za-z0-9\-]+)'
- model: '$1'
- - regex: 'Spice-([A-Za-z0-9]+)'
- model: '$1'
-
-# Sharp
-Sharp:
- regex: 'SHARP|SBM'
- device: 'smartphone'
- models:
- - regex: 'SHARP-AQUOS'
- device: 'tv'
- model: 'Aquos Net Plus'
- - regex: 'SHARP[ \-]([A-Za-z0-9\-]+)'
- model: '$1'
- - regex: '(?:SHARP|SBM)([A-Za-z0-9]+)'
- model: '$1'
-
-# Softbank
-Softbank:
- regex: 'Softbank|J-PHONE'
- device: 'smartphone'
- models:
- - regex: 'Softbank/[12]\.0/([A-Za-z0-9]+)'
- model: '$1'
- - regex: '([A-Za-z0-9]+);Softbank;'
- model: '$1'
- - regex: 'J-PHONE/[0-9]\.[0-9]/([A-Za-z0-9\-]+)'
- model: '$1'
-
-# Sony
-Sony:
- regex: 'Sony|PlayStation'
- device: 'smartphone'
- models:
- - regex: 'Sony[ ]?([A-Za-z0-9\-]+)'
- model: '$1'
- - regex: '(PlayStation (?:3|Portable|Vita))'
- device: 'console'
- model: '$1'
-
-# Qtek
-Qtek:
- regex: 'Qtek[ _]?([A-Za-z0-9]+)'
- device: 'smartphone'
- model: '$1'
-
-# T-Mobile
-T-Mobile:
- regex: 'T-Mobile[ _]([A-Za-z0-9 ]+)'
- device: 'smartphone'
- model: '$1'
-
-# Tcl
-TCL:
- regex: 'TCL-([A-Za-z0-9]+)'
- device: 'smartphone'
- model: '$1'
-
-# Telit
-Telit:
- regex: 'Telit'
- device: 'feature phone'
- models:
- - regex: 'Telit_Mobile_Terminals-([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'Telit[\-_]?([A-Za-z0-9]+)'
- model: '$1'
-
-# Tianyu
-TIANYU:
- regex: 'TIANYU'
- device: 'feature phone'
- models:
- - regex: 'TIANYU ([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'TIANYU-KTOUCH/([A-Za-z0-9]+)'
- model: '$1'
-
-# Toplux
-Toplux:
- regex: 'Toplux ([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# UTStarcom
-UTStarcom:
- regex: 'utstar([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Vitelcom
-Vitelcom:
- regex: 'Vitelcom|portalmmm/[12].0 TSM'
- device: 'feature phone'
- models:
- - regex: 'TSM-([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'TSM([A-Za-z0-9\-]+)'
- model: '$1'
- - regex: 'portalmmm/[12].0 (TSM[A-Za-z0-9 ]+)'
- model: '$1'
-
-# VK Mobile
-VK Mobile:
- regex: 'VK[\-]?([A-Za-z0-9 ]+)'
- device: 'feature phone'
- model: '$1'
-
-# Vertu
-Vertu:
- regex: 'Vertu[ ]?([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Videocon
-Videocon:
- regex: 'Videocon_([A-Za-z0-9]+)'
- device: 'smartphone'
- model: '$1'
-
-# Voxtel
-Voxtel:
- regex: 'Voxtel_([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Wellcom
-WellcoM:
- regex: 'WELLCOM[ _\-/]([A-Za-z0-9]+)'
- device: 'smartphone'
- model: '$1'
-
-# Wonu
-Wonu:
- regex: 'Wonu ([A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Zonda
-Zonda:
- regex: '(ZM(?:CK|EM|TFTV|TN)[A-Za-z0-9]+)'
- device: 'feature phone'
- model: '$1'
-
-# Toshiba
-Toshiba:
- regex: 'Toshiba|portalmmm/[12].0 TS'
- device: 'smartphone'
- models:
- - regex: 'Toshiba[ /_\-]?([A-Za-z0-9 ]+)'
- model: '$1'
- - regex: 'portalmmm/[12].0 (TS[A-Za-z0-9 ]+)'
- model: '$1'
-
-# Fly
-Fly:
- regex: 'Fly|MERIDIAN-'
- device: 'smartphone'
- models:
- - regex: 'Fly[ _\-]?([A-Za-z0-9]+)'
- model: '$1'
- - regex: 'MERIDIAN-([A-Za-z0-9]+)'
- model: '$1'
-
-# WebTV
-WebTV:
- regex: 'WebTV/(\d+\.\d+)'
- device: 'tv'
- model: '$1'
-
-# ZTE
-ZTE:
- regex: 'ZTE|Z331'
- device: 'smartphone'
- models:
- - regex: '(Z331)'
- model: '$1'
- - regex: 'ZTE-(?:G |G-)?([A-Za-z0-9 _]+)'
- model: '$1'
- - regex: 'ZTE ([A-Za-z0-9]+)'
- model: '$1'
-
-# Symbian to Nokia ??
-# Change name from Nokia to other to not change above Nokia element
-#Nokia:
-# regex: 'Symbian'
+############### +# Piwik - Open source web analytics +# +# @link http://piwik.org +# @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later +# +# @category Piwik_Plugins +# @package Piwik_DevicesDetection +############### + +# HTC +HTC: + regex: 'HTC|Sprint APA|ADR[A-Za-z0-9]+' + device: 'smartphone' + models: + - regex: 'HTC ([A-Za-z0-9]+) Build' + model: '$1' + - regex: 'HTC ([A-Za-z0-9]+(?: [A-Za-z0-9]+)?)' + model: '$1' + - regex: 'USCCHTC(\d+)' + model: '$1' + - regex: 'Sprint APA(9292)' + model: '$1 (Sprint)' + - regex: 'HTC_([A-Za-z0-9_]+)' + model: '$1' + - regex: 'HTC(?:[\-/ ])?([A-Za-z0-9]+)' + model: '$1' + - regex: 'HTC;(?: )?([A-Za-z0-9 ]+)' + model: '$1' + - regex: '(ADR[A-Za-z0-9]+)' + model: '$1' + +# Tesla Model S +Tesla: + regex: 'QtCarBrowser' + device: 'car browser' + model: 'Model S' + +# Kindle +Kindle: + regex: 'KF(?:OT|TT|JWI|JWA) Build|Kindle|Silk/(\d+)\.(\d+)' + device: 'tablet' + models: + - regex: 'KFOT|Kindle Fire|Silk/(\d+)\.(\d+)' + model: 'Fire' + - regex: 'KFTT' + model: 'Fire HD' + - regex: 'KFJWI' + model: 'Fire HD 8.9" WiFi' + - regex: 'KFJWA' + model: 'Fire HD 8.9" 4G' + +# NOKIA +Nokia: + regex: 'Nokia|Lumia|Maemo RX|portalmmm/2\.0 N7|portalmmm/2\.0 NK|nok[0-9]+|Symbian.*\s([a-zA-Z0-9]+)$' + device: 'smartphone' + models: + - regex: 'NokiaInternal|Nokia-WAP-Toolkit|Nokia-MIT-Browser|Nokia Mobile|Nokia Browser|Nokia/Series' + model: '' + - regex: 'Nokia(N[0-9]+)' + model: '$1' + - regex: 'Nokia-([A-Za-z0-9]+)' + model: 'N$1' + - regex: 'NOKIA; ([A-Za-z0-9\- ]+)' + model: '$1' + - regex: 'NOKIA[ ]?([A-Za-z0-9\-]+)' + model: '$1' + - regex: 'NOKIA/([A-Za-z0-9 ]+)' + model: '$1' + - regex: '(Lumia [A-Za-z0-9\-]+)' + model: '$1' + - regex: 'Maemo RX-51 ([A-Za-z0-9]+)' + model: '$1' + - regex: 'Maemo RX-34' + model: 'N800' + - regex: 'portalmmm/2\.0 (N7[37]|NK[A-Za-z0-9]+)' + model: '$1' + - regex: 'nok([0-9]+)' + model: '$1' + - regex: 'Symbian.*\s([a-zA-Z0-9]+)$' + device: 'feature phone' + model: '$1' + +# RIM/BlackBerry +RIM: + regex: 'BB10;|BlackBerry|rim[0-9]+|PlayBook' + device: 'smartphone' + + models: + - regex: 'BB10; ([A-Za-z0-9\- ]+)\)' + model: 'BlackBerry $1' + - regex: 'PlayBook.+RIM Tablet OS' + model: 'BlackBerry Playbook' + device: 'tablet' + - regex: 'BlackBerry(?: )?([A-Za-z0-9]+)' + model: 'BlackBerry $1' + - regex: 'rim([0-9]+)' + model: 'BlackBerry $1' + - regex: 'BlackBerry' + model: 'BlackBerry' + +# PALM +Palm: + regex: '(?:Pre|Pixi)/(\d+)\.(\d+)|Palm|Treo' + device: 'smartphone' + models: + - regex: '((?:Pre|Pixi))/(\d+\.\d+)' + model: '$1 $2' + - regex: 'Palm(?: )?([A-Za-z0-9]+)' + model: '$1' + - regex: 'Treo([A-Za-z0-9]+)' + model: 'Treo $1' + +# HP +HP: + regex: 'Touch[Pp]ad|hp-tablet|HP(?: )?iPAQ|webOS.*(P160U)' + device: 'smartphone' + models: + - regex: 'Touch[Pp]ad/(\d+\.\d+)|hp-tablet' + model: 'TouchPad' + device: 'tablet' + - regex: 'HP(?: )?iPAQ(?: )?([A-Za-z0-9]+)' + model: 'iPAQ $1' + - regex: 'webOS.*(P160U)' + model: 'Veer' + +# TiPhone +TiPhone: + regex: 'TiPhone(?: )?([A-Za-z0-9]+)' + device: 'smartphone' + model: '$1' + +# Apple +Apple: + regex: 'AppleTV|iPad|iPod|iPhone' + models: + - regex: 'AppleTV' + model: 'Apple TV' + device: 'tv' + - regex: 'iPad' + model: 'iPad' + device: 'tablet' + - regex: 'iPod' + model: 'iPod Touch' + device: 'palmtop' + - regex: 'iPhone' + model: 'iPhone' + device: 'smartphone' + +# Acer +Acer: + regex: 'acer[\-_]([A-Za-z0-9]+)' + device: 'smartphone' + model: '$1' + +# Airness +Airness: + regex: 'AIRNESS-([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Alcatel +Alcatel: + regex: 'Alcatel|Alc([A-Za-z0-9]+)' + device: 'smartphone' + models: + - regex: 'Alcatel UP' + model: '' + - regex: 'ALCATEL[ \-]([A-Za-z0-9\-]+)' + model: '$1' + - regex: 'ALCATEL_([A-Za-z0-9_]+)' + model: '$1' + - regex: 'Alc([A-Za-z0-9]+)' + model: '$1' + +# Amoi +Amoi: + regex: 'Amoi' + device: 'smartphone' + models: + - regex: 'Amoi[\- /](A-Za-z0-9]+)' + mobile: '$1' + - regex: 'Amoisonic-([A-Za-z0-9]+)' + model: '$1' + +# Asus +Asus: + regex: 'Asus' + device: 'smartphone' + models: + - regex: 'Asus(?:-|;)?([A-Za-z0-9]+)' + model: '$1' + - regex: 'ASUS (Transformer Pad TF300T)' + device: 'tablet' + model: '$1' + +# Audiovox +Audiovox: + regex: 'Audiovox|CDM|UTS(?:TARCOM)?\-|audio([A-Za-z0-9\-]+)' + device: 'smartphone' + models: + - regex: 'Audiovox[_\-]([A-Za-z0-9\-]+)' + model: '$1' + - regex: 'CDM(?:-)?([A-Za-z0-9]+)' + model: 'CDM-$1' + - regex: 'UTS(?:TARCOM)?-([A-Za-z0-9\-]+)' + model: 'CDM-$1' + - regex: 'audio([A-Za-z0-9\-]+)' + model: 'CDM-$1' + +# Avvio +Avvio: + regex: 'Avvio[ _]([A-Za-z0-9\-]+)' + device: 'smartphone' + model: '$1' + +# Bird +Bird: + regex: 'BIRD[\-. _]([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Becker +Becker: + regex: 'Becker-([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Beetel +Beetel: + regex: 'Beetel ([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# BenQ-Siemens +BenQ-Siemens: + regex: 'BENQ-SIEMENS - ([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# BenQ +BenQ: + regex: 'BENQ(?:[ \-])?([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Capitel +Capitel: + regex: 'Capitel-([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Compal +Compal: + regex: 'Compal-([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Cricket +Cricket: + regex: 'Cricket-([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Dell +Dell: + regex: 'Dell ([A-Za-z0-9]+)' + device: 'smartphone' + model: '$1' + +# Dbtel +Dbtel: + regex: 'DBTEL(?:[\-/])?([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Dicam +Dicam: + regex: 'DICAM-([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# DoCoMo +DoCoMo: + regex: 'DoCoMo|\;FOMA|KGT/1\.0' + device: 'feature phone' + models: + - regex: 'DoCoMo/[12]\.0[/ ]([A-Za-z0-9]+)' + model: '$1' + - regex: '([A-Za-z0-9]+)(?:_W)?\;FOMA' + model: '$1' + - regex: 'KGT/1\.0 ([A-Za-z0-9]+)' + model: '$1' + +# Dopod +Dopod: + regex: 'Dopod(?: )?([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Ericy +Ericy: + regex: 'Ericy-([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Sony Ericsson +Sony Ericsson: + regex: 'Sony(?: )?Ericsson|portalmmm/2\.0 K' + device: 'smartphone' + models: + - regex: 'SonyEricsson([A-Za-z0-9]+)' + model: '$1' + - regex: 'Sony(?: )?Ericsson ([A-Za-z0-9\-]+)' + model: '$1' + - regex: 'portalmmm/2.0 K([A-Za-z0-9]+)' + model: 'K$1' + +# Ericsson +Ericsson: + regex: 'Ericsson(?:/ )?([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# eTouch +eTouch: + regex: 'eTouch(?: )?([A-Za-z0-9]+)' + device: 'smartphone' + model: '$1' + +# Ezze +Ezze: + regex: 'EZZE-|EZ([A-Za-z0-9]+)' + device: 'feature phone' + models: + - regex: 'EZZE-([A-Za-z0-9]+)' + model: '$1' + - regex: 'EZ([A-Za-z0-9]+)' + model: 'EZ$1' + +# Ezio +Ezio: + regex: 'EZIO-([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Gionee +Gionee: + regex: 'GIONEE-([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Google +Google: + regex: 'Nexus|GoogleTV' + device: 'smartphone' + models: + - regex: '(Galaxy Nexus)' + model: '$1' + - regex: '(Nexus (:?S|4|One))' + model: '$1' + - regex: '(Nexus (:?7|10))' + device: 'tablet' + model: '$1' + - regex: '(GoogleTV)' + device: 'tv' + model: '$1' + +# Gradiente +Gradiente: + regex: 'GRADIENTE' + device: 'feature phone' + models: + - regex: 'GRADIENTE-([A-Za-z0-9]+)' + model: '$1' + - regex: 'GRADIENTE ([A-Za-z0-9\-]+)' + model: '$1' + +# Grundig +Grundig: + regex: 'GRUNDIG|portalmmm/2\.0 G' + device: 'tv' + models: + - regex: 'GRUNDIG ([A-Za-z0-9]+)' + model: '$1' + - regex: 'portalmmm/2\.0 G([A-Za-z0-9]+)' + model: 'G$1' + +# Haier +Haier: + regex: 'Haier[ -]([A-Za-z0-9\-]+)' + device: 'feature phone' + model: '$1' + +# Huawei +Huawei: + regex: 'Huawei|vodafone([A-Za-z0-9]+)' + device: 'smartphone' + models: + - regex: 'Huawei(?:[\- /_]|/1\.0/)?([A-Za-z0-9]+)' + model: '$1' + - regex: 'vodafone([A-Za-z0-9]+)' + model: 'Vodafone $1' + +# Innostream +Innostream: + regex: 'INNO([A-Za-z0-9]+)' + device: 'feature phone' + model: 'INNO$1' + +# Inq +INQ: + regex: 'INQ/([A-Za-z0-9\-]+)' + device: 'feature phone' + model: '$1' + +# i-mate +i-mate: + regex: 'i-mate ([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# i-mobile +i-mobile: + regex: 'i-mobile(?: )?([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# ikomo +iKoMo: + regex: 'iKoMo ([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# kddi +KDDI: + regex: 'kddi-([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# kyocera +Kyocera: + regex: 'Kyocera|KWC-|QC-' + device: 'smartphone' + models: + - regex: 'Kyocera-KZ-([A-Za-z0-9]+)' + model: 'KZ $1' + - regex: 'Kyocera(:?[\-/])?([A-Za-z0-9]+)' + model: '$1' + - regex: '(?:KWC|QC)-([A-Za-z0-9]+)' + model: '$1' + +# lanix +Lanix: + regex: 'LANIX-([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# lct +LCT: + regex: 'LCT_([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# lenovo +Lenovo: + regex: 'Lenovo[\-_]([A-Za-z0-9]+)' + device: 'smartphone' + model: '$1' + +# lguplus +LGUPlus: + regex: 'LGUPlus' + device: 'smartphone' + model: '' + +# lg +LG: + regex: 'LG|portalmmm/2\.0 (?:KE|KG|KP|L3)|VX[0-9]+' + device: 'smartphone' + models: + - regex: 'LGE_DLNA_SDK' + device: 'tv' + model: 'NetCast' + - regex: 'LGE(?: |-LG| LG-AX|-)([A-Za-z0-9]+)' + model: '$1' + - regex: 'LGE;([A-Za-z0-9\-]+)' + model: '$1' + - regex: 'LG(?:/|-LG| |-)?([A-Za-z0-9]+)' + model: '$1' + - regex: 'LG; ([A-Za-z0-9 ]+)' + model: '$1' + - regex: 'portalmmm/2.0 ((?:KE|KG|KP|L3)[A-Za-z0-9]+)' + model: '$1' + - regex: '(VX[0-9]+)' + model: '$1' + +# microsoft +Microsoft: + regex: 'Xbox|KIN\.(?:One|Two)' + device: 'console' + model: 'Xbox 360' + +# Konka +Konka: + regex: 'KONKA_([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Karbonn +Karbonn: + regex: 'Karbonn_([A-Za-z0-9]+)' + device: 'smartphone' + model: '$1' + +# Sagem +Sagem: + regex: 'SAGEM|portalmmm/2.0 (?:SG|my)' + device: 'smartphone' + models: + - regex: 'SAGEM ([A-Za-z0-9]+)' + model: '$1' + - regex: 'SAGEM-([A-Za-z0-9\-]+)' + model: '$1' + - regex: 'portalmmm/2.0 ((?:SG|my)[A-Za-z0-9]+)' + model: '$1' + +# micromax +MicroMax: + regex: 'MicroMax(?:[ \-])?([A-Za-z0-9]+)' + device: 'smartphone' + model: '$1' + +# mio +Mio: + regex: 'MIO(?:/)?([A-Za-z0-9]+)' + device: 'smartphone' + model: '$1' + +# mitsubishi +Mitsubishi: + regex: 'MITSU|portalmmm/[12]\.0 M' + device: 'feature phone' + models: + - regex: 'MITSU/[A-Za-z0-9.]+ \(([A-Za-z0-9]+)\)' + model: '$1' + - regex: 'MITSU[ \-]?([A-Za-z0-9]+)' + model: '$1' + - regex: 'portalmmm/[12]\.0 (M[A-Za-z0-9]+)' + model: '$1' + +# motorola +Motorola: + regex: 'MOT|(?<!AN)DROID (?:Build|([A-Za-z0-9]+))|portalmmm/2.0 (?:E378i|L6|L7|v3)' + device: 'smartphone' + models: + - regex: 'Motorola[ \-]([A-Za-z0-9]+)' + model: '$1' + - regex: 'MOTORAZR[ \-]([A-Za-z0-9]+)' + model: 'RAZR $1' + - regex: 'MOTORIZR[ \-]([A-Za-z0-9]+)' + model: 'RIZR $1' + - regex: 'MOT[O]?[\-]?([A-Za-z0-9.]+)' + model: '$1' + - regex: '(?<!AN)DROID (?:Build|([A-Za-z0-9]+))' + model: 'DROID $1' + - regex: 'portalmmm/2.0 ((?:E378i|L6|L7|V3)[A-Za-z0-9]+)' + model: '$1' + +# myphone +MyPhone: + regex: 'MyPhone([A-Za-z0-9]+)' + device: 'smartphone' + model: '$1' + +# nec +NEC: + regex: 'NEC|KGT/2\.0|portalmmm/1\.0 (?:DB|N)|(?:portalmmm|o2imode)/2.0[ ,]N' + device: 'smartphone' + models: + - regex: '(?:NEC-|KGT/2\.0 )([A-Za-z0-9]+)' + model: '$1' + - regex: 'portalmmm/1\.0 ((?:DB|N)[A-Za-z0-9]+)' + model: '$1' + - regex: '(?:portalmmm|o2imode)/2\.0[ ,](N[A-Za-z0-9]+)' + model: '$1' + +# newgen +Newgen: + regex: 'NEWGEN\-([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# nintendo +Nintendo: + regex: 'Nintendo (([3]?DS[i]?)|Wii[U]?)' + device: 'console' + model: '$1' + +# ngm +NGM: + regex: 'NGM_([A-Za-z0-9]+)' + device: 'smartphone' + model: '$1' + +# nexian +Nexian: + regex: 'Nexian' + device: 'smartphone' + models: + - regex: 'Nexian[ ]?([A-Za-z0-9\-]+)' + model: '$1' + - regex: 'Nexian-([A-Za-z0-9]+)' + model: '$1' + +# o2 +O2: + regex: 'Xda|O2[ \-]|COCOON' + device: 'smartphone' + models: + - regex: '(Xda[ _][A-Za-z0-9_]+)' + models: '$1' + - regex: '(COCOON)' + models: '$1' + - regex: 'O2 ([A-Za-z0-9 ]+)' + models: '$1' + - regex: 'O2-([A-Za-z0-9]+)' + models: '$1' + +# onda +Onda: + regex: 'Onda' + device: 'smartphone' + models: + regex: '([A-Za-z0-9]+)[ _]Onda' + model: '$1' + regex: 'Onda ([A-Za-z0-9]+)' + model: '$1' + +# oppo +OPPO: + regex: 'OPPO[ ]?([A-Za-z0-9]+)' + device: 'smartphone' + model: '$1' + +# orange +Orange: + regex: 'SPV[ \-]?([A-Za-z0-9]+)' + device: 'smartphone' + model: 'SPV $1' + +# panasonic +Panasonic: + regex: 'Panasonic' + device: 'smartphone' + models: + - regex: 'Panasonic MIL DLNA' + device: 'tv' + model: 'Viera Cast' + - regex: 'Panasonic[ \-]?([A-Za-z0-9]+)' + model: '$1' + - regex: 'portalmmm/2.0 (P[A-Za-z0-9]+)' + model: '$1' + +# philips +Philips: + regex: 'Philips' + device: 'smartphone' + models: + - regex: 'Philips-FISIO ([A-Za-z0-9]+)' + model: 'Fisio $1' + - regex: 'Philips[ ]?([A-Za-z0-9]+)' + model: '$1' + - regex: 'Philips-([A-Za-z0-9\-@]+)' + model: '$1' + +# phoneOne +phoneOne: + regex: 'phoneOne[ \-]?([A-Za-z0-9]+)' + device: 'smartphone' + model: '$1' + +# Rover +Rover: + regex: 'Rover ([0-9]+)' + device: 'feature phone' + model: '$1' + +# Siemens +Siemens: + regex: 'SIEMENS|SIE-|portalmmm/2\.0 SI|S55|SL45i' + device: 'smartphone' + models: + - regex: 'SIEMENS[ \-]([A-Za-z0-9]+)' + model: '$1' + - regex: 'SIE(?:MENS )?[\-]?([A-Za-z0-9]+)' + model: '$1' + - regex: '(S55|SL45i)' + model: '$1' + - regex: 'portalmmm/2.0 (SI[A-Za-z0-9]+)' + model: '$1' + +# Samsung +Samsung: + regex: 'SAMSUNG|S(?:CH|GH|PH|EC|AM)-|SMART-TV|GT-|Galaxy|(?:portalmmm|o2imode)/2\.0 [SZ]|sam[rua]' + device: 'smartphone' + models: + - regex: 'SAMSUNG[\-;][ ]?([A-Za-z0-9]+[\-_][A-Za-z0-9]+)' + model: '$1' + - regex: 'SAMSUNG[ _/]?([A-Za-z0-9\-]+)' + model: '$1' + - regex: 'SAMSUNG;[ ]?([A-Za-z0-9 ]+)' + model: '$1' + - regex: '((?:SCH|SGH|SPH|GT)-[A-Za-z0-9]+)' + model: '$1' + - regex: 'SEC-([A-Za-z0-9]+)' + model: '$1' + - regex: 'SAM-([A-Za-z0-9]+)' + model: 'SCH-$1' + - regex: 'SMART-TV' + device: 'tv' + model: 'Smart TV' + - regex: '(Galaxy [A-Za-z0-9]+)' + model: '$1' + - regex: '(?:portalmmm|o2imode)/2\.0 ([SZ][A-Za-z0-9]+)' + model: '$1' + - regex: 'sam([rua][0-9]+)' + model: 'SCH-$1' + +# pantech +Pantech: + regex: 'Pantech|P[GTN]-|TX[T]?[0-9]+' + device: 'smartphone' + models: + - regex: 'Pantech[ \-]?([A-Za-z0-9]+)' + model: '$1' + - regex: 'Pantech_([A-Za-z0-9\-]+)' + model: '$1' + - regex: '(P[GTN]-[A-Za-z0-9]+)' + model: '$1' + - regex: '(TX[T]?[0-9]+)' + model: '$1' + +# Sanyo +Sanyo: + regex: 'Sanyo|MobilePhone ' + device: 'smartphone' + models: + - regex: 'SANYO[ \-_]([A-Za-z0-9\-]+)' + model: '$1' + - regex: 'MobilePhone ([A-Za-z0-9\-]+)' + model: '$1' + +# Sega +Sega: + regex: 'Dreamcast' + device: 'console' + model: 'Dreamcast' + +# Sendo +Sendo: + regex: 'Sendo([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Spice +Spice: + regex: 'Spice' + device: 'smartphone' + models: + - regex: 'Spice ([A-Za-z0-9\-]+)' + model: '$1' + - regex: 'Spice-([A-Za-z0-9]+)' + model: '$1' + +# Sharp +Sharp: + regex: 'SHARP|SBM' + device: 'smartphone' + models: + - regex: 'SHARP-AQUOS' + device: 'tv' + model: 'Aquos Net Plus' + - regex: 'SHARP[ \-]([A-Za-z0-9\-]+)' + model: '$1' + - regex: '(?:SHARP|SBM)([A-Za-z0-9]+)' + model: '$1' + +# Softbank +Softbank: + regex: 'Softbank|J-PHONE' + device: 'smartphone' + models: + - regex: 'Softbank/[12]\.0/([A-Za-z0-9]+)' + model: '$1' + - regex: '([A-Za-z0-9]+);Softbank;' + model: '$1' + - regex: 'J-PHONE/[0-9]\.[0-9]/([A-Za-z0-9\-]+)' + model: '$1' + +# Sony +Sony: + regex: 'Sony|PlayStation' + device: 'smartphone' + models: + - regex: 'Sony[ ]?([A-Za-z0-9\-]+)' + model: '$1' + - regex: '(PlayStation (?:3|Portable|Vita))' + device: 'console' + model: '$1' + +# Qtek +Qtek: + regex: 'Qtek[ _]?([A-Za-z0-9]+)' + device: 'smartphone' + model: '$1' + +# T-Mobile +T-Mobile: + regex: 'T-Mobile[ _]([A-Za-z0-9 ]+)' + device: 'smartphone' + model: '$1' + +# Tcl +TCL: + regex: 'TCL-([A-Za-z0-9]+)' + device: 'smartphone' + model: '$1' + +# Telit +Telit: + regex: 'Telit' + device: 'feature phone' + models: + - regex: 'Telit_Mobile_Terminals-([A-Za-z0-9]+)' + model: '$1' + - regex: 'Telit[\-_]?([A-Za-z0-9]+)' + model: '$1' + +# Tianyu +TIANYU: + regex: 'TIANYU' + device: 'feature phone' + models: + - regex: 'TIANYU ([A-Za-z0-9]+)' + model: '$1' + - regex: 'TIANYU-KTOUCH/([A-Za-z0-9]+)' + model: '$1' + +# Toplux +Toplux: + regex: 'Toplux ([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# UTStarcom +UTStarcom: + regex: 'utstar([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Vitelcom +Vitelcom: + regex: 'Vitelcom|portalmmm/[12].0 TSM' + device: 'feature phone' + models: + - regex: 'TSM-([A-Za-z0-9]+)' + model: '$1' + - regex: 'TSM([A-Za-z0-9\-]+)' + model: '$1' + - regex: 'portalmmm/[12].0 (TSM[A-Za-z0-9 ]+)' + model: '$1' + +# VK Mobile +VK Mobile: + regex: 'VK[\-]?([A-Za-z0-9 ]+)' + device: 'feature phone' + model: '$1' + +# Vertu +Vertu: + regex: 'Vertu[ ]?([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Videocon +Videocon: + regex: 'Videocon_([A-Za-z0-9]+)' + device: 'smartphone' + model: '$1' + +# Voxtel +Voxtel: + regex: 'Voxtel_([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Wellcom +WellcoM: + regex: 'WELLCOM[ _\-/]([A-Za-z0-9]+)' + device: 'smartphone' + model: '$1' + +# Wonu +Wonu: + regex: 'Wonu ([A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Zonda +Zonda: + regex: '(ZM(?:CK|EM|TFTV|TN)[A-Za-z0-9]+)' + device: 'feature phone' + model: '$1' + +# Toshiba +Toshiba: + regex: 'Toshiba|portalmmm/[12].0 TS' + device: 'smartphone' + models: + - regex: 'Toshiba[ /_\-]?([A-Za-z0-9 ]+)' + model: '$1' + - regex: 'portalmmm/[12].0 (TS[A-Za-z0-9 ]+)' + model: '$1' + +# Fly +Fly: + regex: 'Fly|MERIDIAN-' + device: 'smartphone' + models: + - regex: 'Fly[ _\-]?([A-Za-z0-9]+)' + model: '$1' + - regex: 'MERIDIAN-([A-Za-z0-9]+)' + model: '$1' + +# WebTV +WebTV: + regex: 'WebTV/(\d+\.\d+)' + device: 'tv' + model: '$1' + +# ZTE +ZTE: + regex: 'ZTE|Z331' + device: 'smartphone' + models: + - regex: '(Z331)' + model: '$1' + - regex: 'ZTE-(?:G |G-)?([A-Za-z0-9 _]+)' + model: '$1' + - regex: 'ZTE ([A-Za-z0-9]+)' + model: '$1' + +# Symbian to Nokia ?? +# Change name from Nokia to other to not change above Nokia element +#Nokia: +# regex: 'Symbian' # device: 'feature phone'
\ No newline at end of file diff --git a/plugins/DevicesDetection/UserAgentParserEnhanced/regexes/oss.yml b/plugins/DevicesDetection/UserAgentParserEnhanced/regexes/oss.yml index f1660d636f..71b85f987f 100644 --- a/plugins/DevicesDetection/UserAgentParserEnhanced/regexes/oss.yml +++ b/plugins/DevicesDetection/UserAgentParserEnhanced/regexes/oss.yml @@ -1,427 +1,427 @@ -###############
-# Piwik - Open source web analytics
-#
-# @link http://piwik.org
-# @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
-#
-# @category Piwik_Plugins
-# @package Piwik_DevicesDetection
-###############
-
-##########
-# Tizen
-##########
-- regex: 'Tizen'
- name: 'Tizen'
- version: ''
-
-
-
-##########
-# Android
-##########
-- regex: 'Android[ /](\d+\.\d+)'
- name: 'Android'
- version: '$1'
-
-
-- regex: 'Android|Silk-Accelerated=[a-z]{4,5}'
- name: 'Android'
- version: ''
-
-
-
-##########
-# Linux
-##########
-- regex: 'Linux; .*((?:Arch Linux|Debian|Knoppix|Mint|Ubuntu|Kubuntu|Xubuntu|Lubuntu|Fedora|Red Hat|Mandriva|Gentoo|Slackware|SUSE|Puppy|CentOS|BackTrack|YunOs|Presto))[ /](\d+\.\d+)'
- name: '$1'
- version: '$2'
-
-
-- regex: '((?:Arch Linux|Debian|Knoppix|Mint|Ubuntu|Kubuntu|Xubuntu|Lubuntu|Fedora|Red Hat|Mandriva|Gentoo|Slackware|SUSE|Puppy|CentOS|BackTrack|YunOs|Presto));.*Linux'
- name: '$1'
- version: ''
-
-
-- regex: 'Linux; |Linux (?:x86_64|zbov|i686)'
- name: 'Linux'
- version: ''
-
-
-
-##########
-# Windows Mobile
-##########
-- regex: 'Windows Phone (?:OS)?[ ]?(\d+\.\d+)'
- name: 'Windows Phone'
- version: '$1'
-
-
-- regex: 'XBLWP7|Windows Phone'
- name: 'Windows Phone'
- version: ''
-
-- regex: 'Windows CE'
- name: 'Windows CE'
- version: ''
-
-
-- regex: '(?:IEMobile|Windows Mobile)(?: (\d+\.\d+))?'
- name: 'Windows Mobile'
- version: '$1'
-
-
-- regex: 'Windows NT 6.2; ARM;'
- name: 'Windows RT'
- version: ''
-
-
-
-##########
-# Windows
-##########
-- regex: 'CYGWIN_NT-6.2|Windows NT 6.2|Windows 8'
- name: 'Windows 8'
- version: '8'
-
-
-- regex: 'CYGWIN_NT-6.1|Windows NT 6.1|Windows 7'
- name: 'Windows 7'
- version: '7'
-
-
-- regex: 'CYGWIN_NT-6.0|Windows NT 6.0|Windows Vista'
- name: 'Windows Vista'
- version: 'Vista'
-
-
-- regex: 'CYGWIN_NT-5.2|Windows NT 5.2|Windows Server 2003 / XP x64'
- name: 'Windows Server 2003'
- version: 'Server 2003'
-
-
-- regex: 'CYGWIN_NT-5.1|Windows NT 5.1|Windows XP'
- name: 'Windows XP'
- version: 'XP'
-
-
-- regex: 'CYGWIN_NT-5.0|Windows NT 5.0|Windows 2000'
- name: 'Windows 2000'
- version: '2000'
-
-
-- regex: 'CYGWIN_NT-4.0|Windows NT 4.0|WinNT|Windows NT'
- name: 'Windows NT'
- version: 'NT'
-
-
-- regex: 'CYGWIN_ME-4.90|Win 9x 4.90|Windows ME'
- name: 'Windows ME'
- version: 'ME'
-
-
-- regex: 'CYGWIN_98-4.10|Win98|Windows 98'
- name: 'Windows 98'
- version: '98'
-
-
-- regex: 'CYGWIN_95-4.0|Win32|Win95|Windows 95|Windows_95'
- name: 'Windows 95'
- version: '95'
-
-
-- regex: 'Windows 3.1'
- name: 'Windows 3.1'
- version: '3.1'
-
-
-- regex: 'Windows'
- name: 'Windows'
- version: ''
-
-
-
-##########
-# Mac
-##########
-- regex: 'Mac OS X (\d+[_.]\d+)'
- name: 'Mac'
-
- version: '$1'
-
-- regex: 'Darwin|Macintosh|Mac_PowerPC|PPC|Mac PowerPC'
- name: 'Mac'
- version: ''
-
-
-
-##########
-# iOS
-##########
-- regex: '(?:CPU OS|iPhone OS) (\d+_\d+)'
- name: 'iOS'
-
- version: '$1'
-
-- regex: '(?:iPhone|iPad|iPod)(?:.*Mac OS X.*Version/(\d+\.\d+)|; Opera)'
- name: 'iOS'
- version: '$1'
-
-
-
-##########
-# webOS
-##########
-- regex: '(?:webOS|Palm webOS)(?:/(\d+\.\d+))?'
- name: 'webOS'
- version: '$1'
-
-
-- regex: '(?:PalmOS|Palm OS)(?:/(\d+\.\d+))?'
- name: 'PalmOS'
- version: ''
-
-
-
-##########
-# ChromeOS
-##########
-- regex: 'CrOS [a-z0-9_]+ (\d+\.\d+)'
- name: 'Chrome OS'
- version: '$1'
-
-
-
-##########
-# BlackBerry
-##########
-- regex: '(?:BB10;.+Version|Black[Bb]erry[0-9a-z]+|Black[Bb]erry.+Version)/(\d+\.\d+)'
- name: 'BlackBerry OS'
- version: '$1'
-
-
-- regex: 'RIM Tablet OS (\d+\.\d+)'
- name: 'BlackBerry Tablet OS'
- version: '$1'
-
-
-- regex: 'RIM Tablet OS|QNX|Play[Bb]ook'
- name: 'BlackBerry Tablet OS'
- version: ''
-
-
-- regex: 'Black[Bb]erry'
- name: 'BlackBerry OS'
- version: ''
-
-
-
-##########
-# Symbian
-##########
-- regex: 'Symbian[Oo][Ss]/(\d+\.\d+)'
- name: 'Symbian OS'
- version: '$1'
-
-
-- regex: 'Symbian/3.+NokiaBrowser/7\.3'
- name: 'Symbian'
- version: '^3 Anna'
-
-
-- regex: 'Symbian/3.+NokiaBrowser/7\.4'
- name: 'Symbian'
- version: '^3 Belle'
-
-
-- regex: 'Symbian[/]?3'
- name: 'Symbian^3'
- version: '^3'
-
-
-- regex: '(?:Series 60|SymbOS|S60)(?:[ /]?(\d+\.\d+|V\d+))?'
- name: 'Symbian OS Series 60'
- version: '$1'
-
-
-- regex: 'Series40'
- name: 'Symbian OS Series 40'
- version: ''
-
-
-- regex: 'MeeGo|WeTab'
- name: 'MeeGo'
- version: ''
-
-
-- regex: 'Symbian [Oo][Ss]|SymbOS'
- name: 'Symbian OS'
- version: ''
-
-
-- regex: 'Nokia'
- name: 'Symbian'
- version: ''
-
-
-
-##########
-# Firefox OS
-##########
-- regex: '(?:Mobile|Tablet);.+Firefox/\d+\.\d+'
- name: 'Firefox OS'
- version: ''
-
-
-
-##########
-# Bada
-##########
-- regex: 'bada'
- name: 'Bada'
- version: ''
-
-
-
-##########
-# Brew
-##########
-- regex: '(?:Brew MP|BREW|BMP)(?:[ /](\d+\.\d+))?'
- name: 'Brew'
- version: '$1'
-
-
-
-##########
-# Web TV
-##########
-- regex: 'GoogleTV[ /](\d+\.\d+)|GoogleTV'
- name: 'Google TV'
- version: '$1'
-
-
-- regex: 'AppleTV/(\d+\.\d+)'
- name: 'Apple TV'
- version: '$1'
-
-
-- regex: 'WebTV/(\d+\.\d+)'
- name: 'WebTV'
- version: '$1'
-
-
-
-##########
-# Unix
-##########
-- regex: 'SunOS'
- name: 'Solaris'
- version: ''
-
-
-- regex: 'AIX'
- name: 'AIX'
- version: ''
-
-
-- regex: 'HP-UX'
- name: 'HP-UX'
- version: ''
-
-
-- regex: 'FreeBSD'
- name: 'FreeBSD'
- version: ''
-
-
-- regex: 'NetBSD'
- name: 'NetBSD'
- version: ''
-
-
-- regex: 'OpenBSD'
- name: 'OpenBSD'
- version: ''
-
-
-- regex: 'DragonFly'
- name: 'DragonFly'
- version: ''
-
-
-- regex: 'Syllable'
- name: 'Syllable'
- version: ''
-
-
-- regex: 'IRIX'
- name: 'IRIX'
- version: ''
-
-
-- regex: 'OSF1'
- name: 'OSF1'
- version: ''
-
-
-
-##########
-# Gaming Console
-##########
-- regex: 'Nintendo Wii'
- name: 'Nintendo'
- version: 'Wii'
-
-
-- regex: 'PlayStation 3|PlayStation3'
- name: 'PlayStation'
- version: '3'
-
-
-- regex: 'Xbox|KIN\.(?:One|Two)'
- name: 'Xbox'
- version: '360'
-
-
-
-##########
-# Mobile Gaming Console
-##########
-- regex: 'Nitro|Nintendo ([3]?DS[i]?)'
- name: 'Nintendo Mobile'
- version: '$1'
-
-
-- regex: 'PlayStation ((?:Portable|Vita))'
- name: 'PlayStation'
- version: '$1'
-
-
-
-##########
-# IBM
-##########
-- regex: 'OS/2'
- name: 'OS/2'
- version: ''
-
-
-
-##########
-# Simulators
-##########
-- regex: '(Talkatone|WinWAP)'
- name: '$1'
- version: ''
-
-
-
-##########
-# Bot
-##########
-- regex: '(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves/Teoma|ia_archiver|ScoutJet|Gulper Web Bot|EmailWolf|grub-client|Download Demon|OmniWeb|SearchExpress|Microsoft URL Control|bot|borg|yahoo|slurp|msnbot|msrbot|openbot|archiver|netresearch|transcoder|crawler|lycos|scooter|altavista|teoma|gigabot|baiduspider|blitzbot|oegp|charlotte|furlbot|http%20client|polybot|htdig|ichiro|mogimogi|larbin|pompos|scrubby|searchsight|seekbot|semanticdiscovery|silk|snappy|speedy|spider|voila|vortex|voyager|zao|zeal|fast-webcrawler|converacrawler|dataparksearch|findlinksYottaaMonitor|BrowserMob|HttpMonitor|YandexBot|Slurp|BingPreview|PagePeeker|ThumbShotsBot|WebThumb|URL2PNG|ZooShot|GomezA|Catchpoint bot|Willow Internet Crawler|Google SketchUp|Read%20Later|Minimo|Pingdom.com|facebookexternalhit|Twitterbot|RackspaceBot)'
- name: 'Bot '
- version: ''
-
+############### +# Piwik - Open source web analytics +# +# @link http://piwik.org +# @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later +# +# @category Piwik_Plugins +# @package Piwik_DevicesDetection +############### + +########## +# Tizen +########## +- regex: 'Tizen' + name: 'Tizen' + version: '' + + + +########## +# Android +########## +- regex: 'Android[ /](\d+\.\d+)' + name: 'Android' + version: '$1' + + +- regex: 'Android|Silk-Accelerated=[a-z]{4,5}' + name: 'Android' + version: '' + + + +########## +# Linux +########## +- regex: 'Linux; .*((?:Arch Linux|Debian|Knoppix|Mint|Ubuntu|Kubuntu|Xubuntu|Lubuntu|Fedora|Red Hat|Mandriva|Gentoo|Slackware|SUSE|Puppy|CentOS|BackTrack|YunOs|Presto))[ /](\d+\.\d+)' + name: '$1' + version: '$2' + + +- regex: '((?:Arch Linux|Debian|Knoppix|Mint|Ubuntu|Kubuntu|Xubuntu|Lubuntu|Fedora|Red Hat|Mandriva|Gentoo|Slackware|SUSE|Puppy|CentOS|BackTrack|YunOs|Presto));.*Linux' + name: '$1' + version: '' + + +- regex: 'Linux; |Linux (?:x86_64|zbov|i686)' + name: 'Linux' + version: '' + + + +########## +# Windows Mobile +########## +- regex: 'Windows Phone (?:OS)?[ ]?(\d+\.\d+)' + name: 'Windows Phone' + version: '$1' + + +- regex: 'XBLWP7|Windows Phone' + name: 'Windows Phone' + version: '' + +- regex: 'Windows CE' + name: 'Windows CE' + version: '' + + +- regex: '(?:IEMobile|Windows Mobile)(?: (\d+\.\d+))?' + name: 'Windows Mobile' + version: '$1' + + +- regex: 'Windows NT 6.2; ARM;' + name: 'Windows RT' + version: '' + + + +########## +# Windows +########## +- regex: 'CYGWIN_NT-6.2|Windows NT 6.2|Windows 8' + name: 'Windows 8' + version: '8' + + +- regex: 'CYGWIN_NT-6.1|Windows NT 6.1|Windows 7' + name: 'Windows 7' + version: '7' + + +- regex: 'CYGWIN_NT-6.0|Windows NT 6.0|Windows Vista' + name: 'Windows Vista' + version: 'Vista' + + +- regex: 'CYGWIN_NT-5.2|Windows NT 5.2|Windows Server 2003 / XP x64' + name: 'Windows Server 2003' + version: 'Server 2003' + + +- regex: 'CYGWIN_NT-5.1|Windows NT 5.1|Windows XP' + name: 'Windows XP' + version: 'XP' + + +- regex: 'CYGWIN_NT-5.0|Windows NT 5.0|Windows 2000' + name: 'Windows 2000' + version: '2000' + + +- regex: 'CYGWIN_NT-4.0|Windows NT 4.0|WinNT|Windows NT' + name: 'Windows NT' + version: 'NT' + + +- regex: 'CYGWIN_ME-4.90|Win 9x 4.90|Windows ME' + name: 'Windows ME' + version: 'ME' + + +- regex: 'CYGWIN_98-4.10|Win98|Windows 98' + name: 'Windows 98' + version: '98' + + +- regex: 'CYGWIN_95-4.0|Win32|Win95|Windows 95|Windows_95' + name: 'Windows 95' + version: '95' + + +- regex: 'Windows 3.1' + name: 'Windows 3.1' + version: '3.1' + + +- regex: 'Windows' + name: 'Windows' + version: '' + + + +########## +# Mac +########## +- regex: 'Mac OS X (\d+[_.]\d+)' + name: 'Mac' + + version: '$1' + +- regex: 'Darwin|Macintosh|Mac_PowerPC|PPC|Mac PowerPC' + name: 'Mac' + version: '' + + + +########## +# iOS +########## +- regex: '(?:CPU OS|iPhone OS) (\d+_\d+)' + name: 'iOS' + + version: '$1' + +- regex: '(?:iPhone|iPad|iPod)(?:.*Mac OS X.*Version/(\d+\.\d+)|; Opera)' + name: 'iOS' + version: '$1' + + + +########## +# webOS +########## +- regex: '(?:webOS|Palm webOS)(?:/(\d+\.\d+))?' + name: 'webOS' + version: '$1' + + +- regex: '(?:PalmOS|Palm OS)(?:/(\d+\.\d+))?' + name: 'PalmOS' + version: '' + + + +########## +# ChromeOS +########## +- regex: 'CrOS [a-z0-9_]+ (\d+\.\d+)' + name: 'Chrome OS' + version: '$1' + + + +########## +# BlackBerry +########## +- regex: '(?:BB10;.+Version|Black[Bb]erry[0-9a-z]+|Black[Bb]erry.+Version)/(\d+\.\d+)' + name: 'BlackBerry OS' + version: '$1' + + +- regex: 'RIM Tablet OS (\d+\.\d+)' + name: 'BlackBerry Tablet OS' + version: '$1' + + +- regex: 'RIM Tablet OS|QNX|Play[Bb]ook' + name: 'BlackBerry Tablet OS' + version: '' + + +- regex: 'Black[Bb]erry' + name: 'BlackBerry OS' + version: '' + + + +########## +# Symbian +########## +- regex: 'Symbian[Oo][Ss]/(\d+\.\d+)' + name: 'Symbian OS' + version: '$1' + + +- regex: 'Symbian/3.+NokiaBrowser/7\.3' + name: 'Symbian' + version: '^3 Anna' + + +- regex: 'Symbian/3.+NokiaBrowser/7\.4' + name: 'Symbian' + version: '^3 Belle' + + +- regex: 'Symbian[/]?3' + name: 'Symbian^3' + version: '^3' + + +- regex: '(?:Series 60|SymbOS|S60)(?:[ /]?(\d+\.\d+|V\d+))?' + name: 'Symbian OS Series 60' + version: '$1' + + +- regex: 'Series40' + name: 'Symbian OS Series 40' + version: '' + + +- regex: 'MeeGo|WeTab' + name: 'MeeGo' + version: '' + + +- regex: 'Symbian [Oo][Ss]|SymbOS' + name: 'Symbian OS' + version: '' + + +- regex: 'Nokia' + name: 'Symbian' + version: '' + + + +########## +# Firefox OS +########## +- regex: '(?:Mobile|Tablet);.+Firefox/\d+\.\d+' + name: 'Firefox OS' + version: '' + + + +########## +# Bada +########## +- regex: 'bada' + name: 'Bada' + version: '' + + + +########## +# Brew +########## +- regex: '(?:Brew MP|BREW|BMP)(?:[ /](\d+\.\d+))?' + name: 'Brew' + version: '$1' + + + +########## +# Web TV +########## +- regex: 'GoogleTV[ /](\d+\.\d+)|GoogleTV' + name: 'Google TV' + version: '$1' + + +- regex: 'AppleTV/(\d+\.\d+)' + name: 'Apple TV' + version: '$1' + + +- regex: 'WebTV/(\d+\.\d+)' + name: 'WebTV' + version: '$1' + + + +########## +# Unix +########## +- regex: 'SunOS' + name: 'Solaris' + version: '' + + +- regex: 'AIX' + name: 'AIX' + version: '' + + +- regex: 'HP-UX' + name: 'HP-UX' + version: '' + + +- regex: 'FreeBSD' + name: 'FreeBSD' + version: '' + + +- regex: 'NetBSD' + name: 'NetBSD' + version: '' + + +- regex: 'OpenBSD' + name: 'OpenBSD' + version: '' + + +- regex: 'DragonFly' + name: 'DragonFly' + version: '' + + +- regex: 'Syllable' + name: 'Syllable' + version: '' + + +- regex: 'IRIX' + name: 'IRIX' + version: '' + + +- regex: 'OSF1' + name: 'OSF1' + version: '' + + + +########## +# Gaming Console +########## +- regex: 'Nintendo Wii' + name: 'Nintendo' + version: 'Wii' + + +- regex: 'PlayStation 3|PlayStation3' + name: 'PlayStation' + version: '3' + + +- regex: 'Xbox|KIN\.(?:One|Two)' + name: 'Xbox' + version: '360' + + + +########## +# Mobile Gaming Console +########## +- regex: 'Nitro|Nintendo ([3]?DS[i]?)' + name: 'Nintendo Mobile' + version: '$1' + + +- regex: 'PlayStation ((?:Portable|Vita))' + name: 'PlayStation' + version: '$1' + + + +########## +# IBM +########## +- regex: 'OS/2' + name: 'OS/2' + version: '' + + + +########## +# Simulators +########## +- regex: '(Talkatone|WinWAP)' + name: '$1' + version: '' + + + +########## +# Bot +########## +- regex: '(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves/Teoma|ia_archiver|ScoutJet|Gulper Web Bot|EmailWolf|grub-client|Download Demon|OmniWeb|SearchExpress|Microsoft URL Control|bot|borg|yahoo|slurp|msnbot|msrbot|openbot|archiver|netresearch|transcoder|crawler|lycos|scooter|altavista|teoma|gigabot|baiduspider|blitzbot|oegp|charlotte|furlbot|http%20client|polybot|htdig|ichiro|mogimogi|larbin|pompos|scrubby|searchsight|seekbot|semanticdiscovery|silk|snappy|speedy|spider|voila|vortex|voyager|zao|zeal|fast-webcrawler|converacrawler|dataparksearch|findlinksYottaaMonitor|BrowserMob|HttpMonitor|YandexBot|Slurp|BingPreview|PagePeeker|ThumbShotsBot|WebThumb|URL2PNG|ZooShot|GomezA|Catchpoint bot|Willow Internet Crawler|Google SketchUp|Read%20Later|Minimo|Pingdom.com|facebookexternalhit|Twitterbot|RackspaceBot)' + name: 'Bot ' + version: '' +
\ No newline at end of file diff --git a/plugins/DevicesDetection/UserAgentParserEnhanced/spyc.php b/plugins/DevicesDetection/UserAgentParserEnhanced/spyc.php index ed3233ee1b..e19d562035 100644 --- a/plugins/DevicesDetection/UserAgentParserEnhanced/spyc.php +++ b/plugins/DevicesDetection/UserAgentParserEnhanced/spyc.php @@ -1,1046 +1,1046 @@ -<?php
-/**
- * Spyc -- A Simple PHP YAML Class
- * @version 0.5
- * @author Vlad Andersen <vlad.andersen@gmail.com>
- * @author Chris Wanstrath <chris@ozmm.org>
- * @link http://code.google.com/p/spyc/
- * @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2011 Vlad Andersen
- * @license http://www.opensource.org/licenses/mit-license.php MIT License
- * @package Spyc
- */
-
-if (!function_exists('spyc_load')) {
- /**
- * Parses YAML to array.
- * @param string $string YAML string.
- * @return array
- */
- function spyc_load ($string) {
- return Spyc::YAMLLoadString($string);
- }
-}
-
-if (!function_exists('spyc_load_file')) {
- /**
- * Parses YAML to array.
- * @param string $file Path to YAML file.
- * @return array
- */
- function spyc_load_file ($file) {
- return Spyc::YAMLLoad($file);
- }
-}
-
-/**
- * The Simple PHP YAML Class.
- *
- * This class can be used to read a YAML file and convert its contents
- * into a PHP array. It currently supports a very limited subsection of
- * the YAML spec.
- *
- * Usage:
- * <code>
- * $Spyc = new Spyc;
- * $array = $Spyc->load($file);
- * </code>
- * or:
- * <code>
- * $array = Spyc::YAMLLoad($file);
- * </code>
- * or:
- * <code>
- * $array = spyc_load_file($file);
- * </code>
- * @package Spyc
- */
-class Spyc {
-
- // SETTINGS
-
- const REMPTY = "\0\0\0\0\0";
-
- /**
- * Setting this to true will force YAMLDump to enclose any string value in
- * quotes. False by default.
- *
- * @var bool
- */
- public $setting_dump_force_quotes = false;
-
- /**
- * Setting this to true will forse YAMLLoad to use syck_load function when
- * possible. False by default.
- * @var bool
- */
- public $setting_use_syck_is_possible = false;
-
-
-
- /**#@+
- * @access private
- * @var mixed
- */
- private $_dumpIndent;
- private $_dumpWordWrap;
- private $_containsGroupAnchor = false;
- private $_containsGroupAlias = false;
- private $path;
- private $result;
- private $LiteralPlaceHolder = '___YAML_Literal_Block___';
- private $SavedGroups = array();
- private $indent;
- /**
- * Path modifier that should be applied after adding current element.
- * @var array
- */
- private $delayedPath = array();
-
- /**#@+
- * @access public
- * @var mixed
- */
- public $_nodeId;
-
-/**
- * Load a valid YAML string to Spyc.
- * @param string $input
- * @return array
- */
- public function load ($input) {
- return $this->__loadString($input);
- }
-
- /**
- * Load a valid YAML file to Spyc.
- * @param string $file
- * @return array
- */
- public function loadFile ($file) {
- return $this->__load($file);
- }
-
- /**
- * Load YAML into a PHP array statically
- *
- * The load method, when supplied with a YAML stream (string or file),
- * will do its best to convert YAML in a file into a PHP array. Pretty
- * simple.
- * Usage:
- * <code>
- * $array = Spyc::YAMLLoad('lucky.yaml');
- * print_r($array);
- * </code>
- * @access public
- * @return array
- * @param string $input Path of YAML file or string containing YAML
- */
- public static function YAMLLoad($input) {
- $Spyc = new Spyc;
- return $Spyc->__load($input);
- }
-
- /**
- * Load a string of YAML into a PHP array statically
- *
- * The load method, when supplied with a YAML string, will do its best
- * to convert YAML in a string into a PHP array. Pretty simple.
- *
- * Note: use this function if you don't want files from the file system
- * loaded and processed as YAML. This is of interest to people concerned
- * about security whose input is from a string.
- *
- * Usage:
- * <code>
- * $array = Spyc::YAMLLoadString("---\n0: hello world\n");
- * print_r($array);
- * </code>
- * @access public
- * @return array
- * @param string $input String containing YAML
- */
- public static function YAMLLoadString($input) {
- $Spyc = new Spyc;
- return $Spyc->__loadString($input);
- }
-
- /**
- * Dump YAML from PHP array statically
- *
- * The dump method, when supplied with an array, will do its best
- * to convert the array into friendly YAML. Pretty simple. Feel free to
- * save the returned string as nothing.yaml and pass it around.
- *
- * Oh, and you can decide how big the indent is and what the wordwrap
- * for folding is. Pretty cool -- just pass in 'false' for either if
- * you want to use the default.
- *
- * Indent's default is 2 spaces, wordwrap's default is 40 characters. And
- * you can turn off wordwrap by passing in 0.
- *
- * @access public
- * @return string
- * @param array $array PHP array
- * @param int $indent Pass in false to use the default, which is 2
- * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
- */
- public static function YAMLDump($array,$indent = false,$wordwrap = false) {
- $spyc = new Spyc;
- return $spyc->dump($array,$indent,$wordwrap);
- }
-
-
- /**
- * Dump PHP array to YAML
- *
- * The dump method, when supplied with an array, will do its best
- * to convert the array into friendly YAML. Pretty simple. Feel free to
- * save the returned string as tasteful.yaml and pass it around.
- *
- * Oh, and you can decide how big the indent is and what the wordwrap
- * for folding is. Pretty cool -- just pass in 'false' for either if
- * you want to use the default.
- *
- * Indent's default is 2 spaces, wordwrap's default is 40 characters. And
- * you can turn off wordwrap by passing in 0.
- *
- * @access public
- * @return string
- * @param array $array PHP array
- * @param int $indent Pass in false to use the default, which is 2
- * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
- */
- public function dump($array,$indent = false,$wordwrap = false) {
- // Dumps to some very clean YAML. We'll have to add some more features
- // and options soon. And better support for folding.
-
- // New features and options.
- if ($indent === false or !is_numeric($indent)) {
- $this->_dumpIndent = 2;
- } else {
- $this->_dumpIndent = $indent;
- }
-
- if ($wordwrap === false or !is_numeric($wordwrap)) {
- $this->_dumpWordWrap = 40;
- } else {
- $this->_dumpWordWrap = $wordwrap;
- }
-
- // New YAML document
- $string = "---\n";
-
- // Start at the base of the array and move through it.
- if ($array) {
- $array = (array)$array;
- $previous_key = -1;
- foreach ($array as $key => $value) {
- if (!isset($first_key)) $first_key = $key;
- $string .= $this->_yamlize($key,$value,0,$previous_key, $first_key, $array);
- $previous_key = $key;
- }
- }
- return $string;
- }
-
- /**
- * Attempts to convert a key / value array item to YAML
- * @access private
- * @return string
- * @param $key The name of the key
- * @param $value The value of the item
- * @param $indent The indent of the current node
- */
- private function _yamlize($key,$value,$indent, $previous_key = -1, $first_key = 0, $source_array = null) {
- if (is_array($value)) {
- if (empty ($value))
- return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key, $source_array);
- // It has children. What to do?
- // Make it the right kind of item
- $string = $this->_dumpNode($key, self::REMPTY, $indent, $previous_key, $first_key, $source_array);
- // Add the indent
- $indent += $this->_dumpIndent;
- // Yamlize the array
- $string .= $this->_yamlizeArray($value,$indent);
- } elseif (!is_array($value)) {
- // It doesn't have children. Yip.
- $string = $this->_dumpNode($key, $value, $indent, $previous_key, $first_key, $source_array);
- }
- return $string;
- }
-
- /**
- * Attempts to convert an array to YAML
- * @access private
- * @return string
- * @param $array The array you want to convert
- * @param $indent The indent of the current level
- */
- private function _yamlizeArray($array,$indent) {
- if (is_array($array)) {
- $string = '';
- $previous_key = -1;
- foreach ($array as $key => $value) {
- if (!isset($first_key)) $first_key = $key;
- $string .= $this->_yamlize($key, $value, $indent, $previous_key, $first_key, $array);
- $previous_key = $key;
- }
- return $string;
- } else {
- return false;
- }
- }
-
- /**
- * Returns YAML from a key and a value
- * @access private
- * @return string
- * @param $key The name of the key
- * @param $value The value of the item
- * @param $indent The indent of the current node
- */
- private function _dumpNode($key, $value, $indent, $previous_key = -1, $first_key = 0, $source_array = null) {
- // do some folding here, for blocks
- if (is_string ($value) && ((strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false ||
- strpos($value,"*") !== false || strpos($value,"#") !== false || strpos($value,"<") !== false || strpos($value,">") !== false || strpos ($value, ' ') !== false ||
- strpos($value,"[") !== false || strpos($value,"]") !== false || strpos($value,"{") !== false || strpos($value,"}") !== false) || strpos($value,"&") !== false || strpos($value, "'") !== false || strpos($value, "!") === 0 ||
- substr ($value, -1, 1) == ':')
- ) {
- $value = $this->_doLiteralBlock($value,$indent);
- } else {
- $value = $this->_doFolding($value,$indent);
- }
-
- if ($value === array()) $value = '[ ]';
- if (in_array ($value, array ('true', 'TRUE', 'false', 'FALSE', 'y', 'Y', 'n', 'N', 'null', 'NULL'), true)) {
- $value = $this->_doLiteralBlock($value,$indent);
- }
- if (trim ($value) != $value)
- $value = $this->_doLiteralBlock($value,$indent);
-
- if (is_bool($value)) {
- $value = ($value) ? "true" : "false";
- }
-
- if ($value === null) $value = 'null';
- if ($value === "'" . self::REMPTY . "'") $value = null;
-
- $spaces = str_repeat(' ',$indent);
-
- //if (is_int($key) && $key - 1 == $previous_key && $first_key===0) {
- if (is_array ($source_array) && array_keys($source_array) === range(0, count($source_array) - 1)) {
- // It's a sequence
- $string = $spaces.'- '.$value."\n";
- } else {
- // if ($first_key===0) throw new Exception('Keys are all screwy. The first one was zero, now it\'s "'. $key .'"');
- // It's mapped
- if (strpos($key, ":") !== false || strpos($key, "#") !== false) { $key = '"' . $key . '"'; }
- $string = rtrim ($spaces.$key.': '.$value)."\n";
- }
- return $string;
- }
-
- /**
- * Creates a literal block for dumping
- * @access private
- * @return string
- * @param $value
- * @param $indent int The value of the indent
- */
- private function _doLiteralBlock($value,$indent) {
- if ($value === "\n") return '\n';
- if (strpos($value, "\n") === false && strpos($value, "'") === false) {
- return sprintf ("'%s'", $value);
- }
- if (strpos($value, "\n") === false && strpos($value, '"') === false) {
- return sprintf ('"%s"', $value);
- }
- $exploded = explode("\n",$value);
- $newValue = '|';
- $indent += $this->_dumpIndent;
- $spaces = str_repeat(' ',$indent);
- foreach ($exploded as $line) {
- $newValue .= "\n" . $spaces . ($line);
- }
- return $newValue;
- }
-
- /**
- * Folds a string of text, if necessary
- * @access private
- * @return string
- * @param $value The string you wish to fold
- */
- private function _doFolding($value,$indent) {
- // Don't do anything if wordwrap is set to 0
-
- if ($this->_dumpWordWrap !== 0 && is_string ($value) && strlen($value) > $this->_dumpWordWrap) {
- $indent += $this->_dumpIndent;
- $indent = str_repeat(' ',$indent);
- $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent");
- $value = ">\n".$indent.$wrapped;
- } else {
- if ($this->setting_dump_force_quotes && is_string ($value) && $value !== self::REMPTY)
- $value = '"' . $value . '"';
- }
-
-
- return $value;
- }
-
-// LOADING FUNCTIONS
-
- private function __load($input) {
- $Source = $this->loadFromSource($input);
- return $this->loadWithSource($Source);
- }
-
- private function __loadString($input) {
- $Source = $this->loadFromString($input);
- return $this->loadWithSource($Source);
- }
-
- private function loadWithSource($Source) {
- if (empty ($Source)) return array();
- if ($this->setting_use_syck_is_possible && function_exists ('syck_load')) {
- $array = syck_load (implode ('', $Source));
- return is_array($array) ? $array : array();
- }
-
- $this->path = array();
- $this->result = array();
-
- $cnt = count($Source);
- for ($i = 0; $i < $cnt; $i++) {
- $line = $Source[$i];
-
- $this->indent = strlen($line) - strlen(ltrim($line));
- $tempPath = $this->getParentPathByIndent($this->indent);
- $line = self::stripIndent($line, $this->indent);
- if (self::isComment($line)) continue;
- if (self::isEmpty($line)) continue;
- $this->path = $tempPath;
-
- $literalBlockStyle = self::startsLiteralBlock($line);
- if ($literalBlockStyle) {
- $line = rtrim ($line, $literalBlockStyle . " \n");
- $literalBlock = '';
- $line .= $this->LiteralPlaceHolder;
- $literal_block_indent = strlen($Source[$i+1]) - strlen(ltrim($Source[$i+1]));
- while (++$i < $cnt && $this->literalBlockContinues($Source[$i], $this->indent)) {
- $literalBlock = $this->addLiteralLine($literalBlock, $Source[$i], $literalBlockStyle, $literal_block_indent);
- }
- $i--;
- }
-
- while (++$i < $cnt && self::greedilyNeedNextLine($line)) {
- $line = rtrim ($line, " \n\t\r") . ' ' . ltrim ($Source[$i], " \t");
- }
- $i--;
-
-
-
- if (strpos ($line, '#')) {
- if (strpos ($line, '"') === false && strpos ($line, "'") === false)
- $line = preg_replace('/\s+#(.+)$/','',$line);
- }
-
- $lineArray = $this->_parseLine($line);
-
- if ($literalBlockStyle)
- $lineArray = $this->revertLiteralPlaceHolder ($lineArray, $literalBlock);
-
- $this->addArray($lineArray, $this->indent);
-
- foreach ($this->delayedPath as $indent => $delayedPath)
- $this->path[$indent] = $delayedPath;
-
- $this->delayedPath = array();
-
- }
- return $this->result;
- }
-
- private function loadFromSource ($input) {
- if (!empty($input) && strpos($input, "\n") === false && file_exists($input))
- return file($input);
-
- return $this->loadFromString($input);
- }
-
- private function loadFromString ($input) {
- $lines = explode("\n",$input);
- foreach ($lines as $k => $_) {
- $lines[$k] = rtrim ($_, "\r");
- }
- return $lines;
- }
-
- /**
- * Parses YAML code and returns an array for a node
- * @access private
- * @return array
- * @param string $line A line from the YAML file
- */
- private function _parseLine($line) {
- if (!$line) return array();
- $line = trim($line);
- if (!$line) return array();
-
- $array = array();
-
- $group = $this->nodeContainsGroup($line);
- if ($group) {
- $this->addGroup($line, $group);
- $line = $this->stripGroup ($line, $group);
- }
-
- if ($this->startsMappedSequence($line))
- return $this->returnMappedSequence($line);
-
- if ($this->startsMappedValue($line))
- return $this->returnMappedValue($line);
-
- if ($this->isArrayElement($line))
- return $this->returnArrayElement($line);
-
- if ($this->isPlainArray($line))
- return $this->returnPlainArray($line);
-
-
- return $this->returnKeyValuePair($line);
-
- }
-
- /**
- * Finds the type of the passed value, returns the value as the new type.
- * @access private
- * @param string $value
- * @return mixed
- */
- private function _toType($value) {
- if ($value === '') return null;
- $first_character = $value[0];
- $last_character = substr($value, -1, 1);
-
- $is_quoted = false;
- do {
- if (!$value) break;
- if ($first_character != '"' && $first_character != "'") break;
- if ($last_character != '"' && $last_character != "'") break;
- $is_quoted = true;
- } while (0);
-
- if ($is_quoted)
- return strtr(substr ($value, 1, -1), array ('\\"' => '"', '\'\'' => '\'', '\\\'' => '\''));
-
- if (strpos($value, ' #') !== false && !$is_quoted)
- $value = preg_replace('/\s+#(.+)$/','',$value);
-
- if (!$is_quoted) $value = str_replace('\n', "\n", $value);
-
- if ($first_character == '[' && $last_character == ']') {
- // Take out strings sequences and mappings
- $innerValue = trim(substr ($value, 1, -1));
- if ($innerValue === '') return array();
- $explode = $this->_inlineEscape($innerValue);
- // Propagate value array
- $value = array();
- foreach ($explode as $v) {
- $value[] = $this->_toType($v);
- }
- return $value;
- }
-
- if (strpos($value,': ')!==false && $first_character != '{') {
- $array = explode(': ',$value);
- $key = trim($array[0]);
- array_shift($array);
- $value = trim(implode(': ',$array));
- $value = $this->_toType($value);
- return array($key => $value);
- }
-
- if ($first_character == '{' && $last_character == '}') {
- $innerValue = trim(substr ($value, 1, -1));
- if ($innerValue === '') return array();
- // Inline Mapping
- // Take out strings sequences and mappings
- $explode = $this->_inlineEscape($innerValue);
- // Propagate value array
- $array = array();
- foreach ($explode as $v) {
- $SubArr = $this->_toType($v);
- if (empty($SubArr)) continue;
- if (is_array ($SubArr)) {
- $array[key($SubArr)] = $SubArr[key($SubArr)]; continue;
- }
- $array[] = $SubArr;
- }
- return $array;
- }
-
- if ($value == 'null' || $value == 'NULL' || $value == 'Null' || $value == '' || $value == '~') {
- return null;
- }
-
- if ( is_numeric($value) && preg_match ('/^(-|)[1-9]+[0-9]*$/', $value) ){
- $intvalue = (int)$value;
- if ($intvalue != PHP_INT_MAX)
- $value = $intvalue;
- return $value;
- }
-
- if (in_array($value,
- array('true', 'on', '+', 'yes', 'y', 'True', 'TRUE', 'On', 'ON', 'YES', 'Yes', 'Y'))) {
- return true;
- }
-
- if (in_array(strtolower($value),
- array('false', 'off', '-', 'no', 'n'))) {
- return false;
- }
-
- if (is_numeric($value)) {
- if ($value === '0') return 0;
- if (rtrim ($value, 0) === $value)
- $value = (float)$value;
- return $value;
- }
-
- return $value;
- }
-
- /**
- * Used in inlines to check for more inlines or quoted strings
- * @access private
- * @return array
- */
- private function _inlineEscape($inline) {
- // There's gotta be a cleaner way to do this...
- // While pure sequences seem to be nesting just fine,
- // pure mappings and mappings with sequences inside can't go very
- // deep. This needs to be fixed.
-
- $seqs = array();
- $maps = array();
- $saved_strings = array();
-
- // Check for strings
- $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/';
- if (preg_match_all($regex,$inline,$strings)) {
- $saved_strings = $strings[0];
- $inline = preg_replace($regex,'YAMLString',$inline);
- }
- unset($regex);
-
- $i = 0;
- do {
-
- // Check for sequences
- while (preg_match('/\[([^{}\[\]]+)\]/U',$inline,$matchseqs)) {
- $seqs[] = $matchseqs[0];
- $inline = preg_replace('/\[([^{}\[\]]+)\]/U', ('YAMLSeq' . (count($seqs) - 1) . 's'), $inline, 1);
- }
-
- // Check for mappings
- while (preg_match('/{([^\[\]{}]+)}/U',$inline,$matchmaps)) {
- $maps[] = $matchmaps[0];
- $inline = preg_replace('/{([^\[\]{}]+)}/U', ('YAMLMap' . (count($maps) - 1) . 's'), $inline, 1);
- }
-
- if ($i++ >= 10) break;
-
- } while (strpos ($inline, '[') !== false || strpos ($inline, '{') !== false);
-
- $explode = explode(', ',$inline);
- $stringi = 0; $i = 0;
-
- while (1) {
-
- // Re-add the sequences
- if (!empty($seqs)) {
- foreach ($explode as $key => $value) {
- if (strpos($value,'YAMLSeq') !== false) {
- foreach ($seqs as $seqk => $seq) {
- $explode[$key] = str_replace(('YAMLSeq'.$seqk.'s'),$seq,$value);
- $value = $explode[$key];
- }
- }
- }
- }
-
- // Re-add the mappings
- if (!empty($maps)) {
- foreach ($explode as $key => $value) {
- if (strpos($value,'YAMLMap') !== false) {
- foreach ($maps as $mapk => $map) {
- $explode[$key] = str_replace(('YAMLMap'.$mapk.'s'), $map, $value);
- $value = $explode[$key];
- }
- }
- }
- }
-
-
- // Re-add the strings
- if (!empty($saved_strings)) {
- foreach ($explode as $key => $value) {
- while (strpos($value,'YAMLString') !== false) {
- $explode[$key] = preg_replace('/YAMLString/',$saved_strings[$stringi],$value, 1);
- unset($saved_strings[$stringi]);
- ++$stringi;
- $value = $explode[$key];
- }
- }
- }
-
- $finished = true;
- foreach ($explode as $key => $value) {
- if (strpos($value,'YAMLSeq') !== false) {
- $finished = false; break;
- }
- if (strpos($value,'YAMLMap') !== false) {
- $finished = false; break;
- }
- if (strpos($value,'YAMLString') !== false) {
- $finished = false; break;
- }
- }
- if ($finished) break;
-
- $i++;
- if ($i > 10)
- break; // Prevent infinite loops.
- }
-
- return $explode;
- }
-
- private function literalBlockContinues ($line, $lineIndent) {
- if (!trim($line)) return true;
- if (strlen($line) - strlen(ltrim($line)) > $lineIndent) return true;
- return false;
- }
-
- private function referenceContentsByAlias ($alias) {
- do {
- if (!isset($this->SavedGroups[$alias])) { echo "Bad group name: $alias."; break; }
- $groupPath = $this->SavedGroups[$alias];
- $value = $this->result;
- foreach ($groupPath as $k) {
- $value = $value[$k];
- }
- } while (false);
- return $value;
- }
-
- private function addArrayInline ($array, $indent) {
- $CommonGroupPath = $this->path;
- if (empty ($array)) return false;
-
- foreach ($array as $k => $_) {
- $this->addArray(array($k => $_), $indent);
- $this->path = $CommonGroupPath;
- }
- return true;
- }
-
- private function addArray ($incoming_data, $incoming_indent) {
-
- // print_r ($incoming_data);
-
- if (count ($incoming_data) > 1)
- return $this->addArrayInline ($incoming_data, $incoming_indent);
-
- $key = key ($incoming_data);
- $value = isset($incoming_data[$key]) ? $incoming_data[$key] : null;
- if ($key === '__!YAMLZero') $key = '0';
-
- if ($incoming_indent == 0 && !$this->_containsGroupAlias && !$this->_containsGroupAnchor) { // Shortcut for root-level values.
- if ($key || $key === '' || $key === '0') {
- $this->result[$key] = $value;
- } else {
- $this->result[] = $value; end ($this->result); $key = key ($this->result);
- }
- $this->path[$incoming_indent] = $key;
- return;
- }
-
-
-
- $history = array();
- // Unfolding inner array tree.
- $history[] = $_arr = $this->result;
- foreach ($this->path as $k) {
- $history[] = $_arr = $_arr[$k];
- }
-
- if ($this->_containsGroupAlias) {
- $value = $this->referenceContentsByAlias($this->_containsGroupAlias);
- $this->_containsGroupAlias = false;
- }
-
-
- // Adding string or numeric key to the innermost level or $this->arr.
- if (is_string($key) && $key == '<<') {
- if (!is_array ($_arr)) { $_arr = array (); }
-
- $_arr = array_merge ($_arr, $value);
- } else if ($key || $key === '' || $key === '0') {
- if (!is_array ($_arr))
- $_arr = array ($key=>$value);
- else
- $_arr[$key] = $value;
- } else {
- if (!is_array ($_arr)) { $_arr = array ($value); $key = 0; }
- else { $_arr[] = $value; end ($_arr); $key = key ($_arr); }
- }
-
- $reverse_path = array_reverse($this->path);
- $reverse_history = array_reverse ($history);
- $reverse_history[0] = $_arr;
- $cnt = count($reverse_history) - 1;
- for ($i = 0; $i < $cnt; $i++) {
- $reverse_history[$i+1][$reverse_path[$i]] = $reverse_history[$i];
- }
- $this->result = $reverse_history[$cnt];
-
- $this->path[$incoming_indent] = $key;
-
- if ($this->_containsGroupAnchor) {
- $this->SavedGroups[$this->_containsGroupAnchor] = $this->path;
- if (is_array ($value)) {
- $k = key ($value);
- if (!is_int ($k)) {
- $this->SavedGroups[$this->_containsGroupAnchor][$incoming_indent + 2] = $k;
- }
- }
- $this->_containsGroupAnchor = false;
- }
-
- }
-
- private static function startsLiteralBlock ($line) {
- $lastChar = substr (trim($line), -1);
- if ($lastChar != '>' && $lastChar != '|') return false;
- if ($lastChar == '|') return $lastChar;
- // HTML tags should not be counted as literal blocks.
- if (preg_match ('#<.*?>$#', $line)) return false;
- return $lastChar;
- }
-
- private static function greedilyNeedNextLine($line) {
- $line = trim ($line);
- if (!strlen($line)) return false;
- if (substr ($line, -1, 1) == ']') return false;
- if ($line[0] == '[') return true;
- if (preg_match ('#^[^:]+?:\s*\[#', $line)) return true;
- return false;
- }
-
- private function addLiteralLine ($literalBlock, $line, $literalBlockStyle, $indent = -1) {
- $line = self::stripIndent($line, $indent);
- if ($literalBlockStyle !== '|') {
- $line = self::stripIndent($line);
- }
- $line = rtrim ($line, "\r\n\t ") . "\n";
- if ($literalBlockStyle == '|') {
- return $literalBlock . $line;
- }
- if (strlen($line) == 0)
- return rtrim($literalBlock, ' ') . "\n";
- if ($line == "\n" && $literalBlockStyle == '>') {
- return rtrim ($literalBlock, " \t") . "\n";
- }
- if ($line != "\n")
- $line = trim ($line, "\r\n ") . " ";
- return $literalBlock . $line;
- }
-
- function revertLiteralPlaceHolder ($lineArray, $literalBlock) {
- foreach ($lineArray as $k => $_) {
- if (is_array($_))
- $lineArray[$k] = $this->revertLiteralPlaceHolder ($_, $literalBlock);
- else if (substr($_, -1 * strlen ($this->LiteralPlaceHolder)) == $this->LiteralPlaceHolder)
- $lineArray[$k] = rtrim ($literalBlock, " \r\n");
- }
- return $lineArray;
- }
-
- private static function stripIndent ($line, $indent = -1) {
- if ($indent == -1) $indent = strlen($line) - strlen(ltrim($line));
- return substr ($line, $indent);
- }
-
- private function getParentPathByIndent ($indent) {
- if ($indent == 0) return array();
- $linePath = $this->path;
- do {
- end($linePath); $lastIndentInParentPath = key($linePath);
- if ($indent <= $lastIndentInParentPath) array_pop ($linePath);
- } while ($indent <= $lastIndentInParentPath);
- return $linePath;
- }
-
-
- private function clearBiggerPathValues ($indent) {
-
-
- if ($indent == 0) $this->path = array();
- if (empty ($this->path)) return true;
-
- foreach ($this->path as $k => $_) {
- if ($k > $indent) unset ($this->path[$k]);
- }
-
- return true;
- }
-
-
- private static function isComment ($line) {
- if (!$line) return false;
- if ($line[0] == '#') return true;
- if (trim($line, " \r\n\t") == '---') return true;
- return false;
- }
-
- private static function isEmpty ($line) {
- return (trim ($line) === '');
- }
-
-
- private function isArrayElement ($line) {
- if (!$line) return false;
- if ($line[0] != '-') return false;
- if (strlen ($line) > 3)
- if (substr($line,0,3) == '---') return false;
-
- return true;
- }
-
- private function isHashElement ($line) {
- return strpos($line, ':');
- }
-
- private function isLiteral ($line) {
- if ($this->isArrayElement($line)) return false;
- if ($this->isHashElement($line)) return false;
- return true;
- }
-
-
- private static function unquote ($value) {
- if (!$value) return $value;
- if (!is_string($value)) return $value;
- if ($value[0] == '\'') return trim ($value, '\'');
- if ($value[0] == '"') return trim ($value, '"');
- return $value;
- }
-
- private function startsMappedSequence ($line) {
- return ($line[0] == '-' && substr ($line, -1, 1) == ':');
- }
-
- private function returnMappedSequence ($line) {
- $array = array();
- $key = self::unquote(trim(substr($line,1,-1)));
- $array[$key] = array();
- $this->delayedPath = array(strpos ($line, $key) + $this->indent => $key);
- return array($array);
- }
-
- private function returnMappedValue ($line) {
- $array = array();
- $key = self::unquote (trim(substr($line,0,-1)));
- $array[$key] = '';
- return $array;
- }
-
- private function startsMappedValue ($line) {
- return (substr ($line, -1, 1) == ':');
- }
-
- private function isPlainArray ($line) {
- return ($line[0] == '[' && substr ($line, -1, 1) == ']');
- }
-
- private function returnPlainArray ($line) {
- return $this->_toType($line);
- }
-
- private function returnKeyValuePair ($line) {
- $array = array();
- $key = '';
- if (strpos ($line, ':')) {
- // It's a key/value pair most likely
- // If the key is in double quotes pull it out
- if (($line[0] == '"' || $line[0] == "'") && preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) {
- $value = trim(str_replace($matches[1],'',$line));
- $key = $matches[2];
- } else {
- // Do some guesswork as to the key and the value
- $explode = explode(':',$line);
- $key = trim($explode[0]);
- array_shift($explode);
- $value = trim(implode(':',$explode));
- }
- // Set the type of the value. Int, string, etc
- $value = $this->_toType($value);
- if ($key === '0') $key = '__!YAMLZero';
- $array[$key] = $value;
- } else {
- $array = array ($line);
- }
- return $array;
-
- }
-
-
- private function returnArrayElement ($line) {
- if (strlen($line) <= 1) return array(array()); // Weird %)
- $array = array();
- $value = trim(substr($line,1));
- $value = $this->_toType($value);
- $array[] = $value;
- return $array;
- }
-
-
- private function nodeContainsGroup ($line) {
- $symbolsForReference = 'A-z0-9_\-';
- if (strpos($line, '&') === false && strpos($line, '*') === false) return false; // Please die fast ;-)
- if ($line[0] == '&' && preg_match('/^(&['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1];
- if ($line[0] == '*' && preg_match('/^(\*['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1];
- if (preg_match('/(&['.$symbolsForReference.']+)$/', $line, $matches)) return $matches[1];
- if (preg_match('/(\*['.$symbolsForReference.']+$)/', $line, $matches)) return $matches[1];
- if (preg_match ('#^\s*<<\s*:\s*(\*[^\s]+).*$#', $line, $matches)) return $matches[1];
- return false;
-
- }
-
- private function addGroup ($line, $group) {
- if ($group[0] == '&') $this->_containsGroupAnchor = substr ($group, 1);
- if ($group[0] == '*') $this->_containsGroupAlias = substr ($group, 1);
- //print_r ($this->path);
- }
-
- private function stripGroup ($line, $group) {
- $line = trim(str_replace($group, '', $line));
- return $line;
- }
-}
-
-// Enable use of Spyc from command line
-// The syntax is the following: php spyc.php spyc.yaml
-
-define ('SPYC_FROM_COMMAND_LINE', false);
-
-do {
- if (!SPYC_FROM_COMMAND_LINE) break;
- if (empty ($_SERVER['argc']) || $_SERVER['argc'] < 2) break;
- if (empty ($_SERVER['PHP_SELF']) || $_SERVER['PHP_SELF'] != 'spyc.php') break;
- $file = $argv[1];
- printf ("Spyc loading file: %s\n", $file);
- print_r (spyc_load_file ($file));
+<?php +/** + * Spyc -- A Simple PHP YAML Class + * @version 0.5 + * @author Vlad Andersen <vlad.andersen@gmail.com> + * @author Chris Wanstrath <chris@ozmm.org> + * @link http://code.google.com/p/spyc/ + * @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2011 Vlad Andersen + * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @package Spyc + */ + +if (!function_exists('spyc_load')) { + /** + * Parses YAML to array. + * @param string $string YAML string. + * @return array + */ + function spyc_load ($string) { + return Spyc::YAMLLoadString($string); + } +} + +if (!function_exists('spyc_load_file')) { + /** + * Parses YAML to array. + * @param string $file Path to YAML file. + * @return array + */ + function spyc_load_file ($file) { + return Spyc::YAMLLoad($file); + } +} + +/** + * The Simple PHP YAML Class. + * + * This class can be used to read a YAML file and convert its contents + * into a PHP array. It currently supports a very limited subsection of + * the YAML spec. + * + * Usage: + * <code> + * $Spyc = new Spyc; + * $array = $Spyc->load($file); + * </code> + * or: + * <code> + * $array = Spyc::YAMLLoad($file); + * </code> + * or: + * <code> + * $array = spyc_load_file($file); + * </code> + * @package Spyc + */ +class Spyc { + + // SETTINGS + + const REMPTY = "\0\0\0\0\0"; + + /** + * Setting this to true will force YAMLDump to enclose any string value in + * quotes. False by default. + * + * @var bool + */ + public $setting_dump_force_quotes = false; + + /** + * Setting this to true will forse YAMLLoad to use syck_load function when + * possible. False by default. + * @var bool + */ + public $setting_use_syck_is_possible = false; + + + + /**#@+ + * @access private + * @var mixed + */ + private $_dumpIndent; + private $_dumpWordWrap; + private $_containsGroupAnchor = false; + private $_containsGroupAlias = false; + private $path; + private $result; + private $LiteralPlaceHolder = '___YAML_Literal_Block___'; + private $SavedGroups = array(); + private $indent; + /** + * Path modifier that should be applied after adding current element. + * @var array + */ + private $delayedPath = array(); + + /**#@+ + * @access public + * @var mixed + */ + public $_nodeId; + +/** + * Load a valid YAML string to Spyc. + * @param string $input + * @return array + */ + public function load ($input) { + return $this->__loadString($input); + } + + /** + * Load a valid YAML file to Spyc. + * @param string $file + * @return array + */ + public function loadFile ($file) { + return $this->__load($file); + } + + /** + * Load YAML into a PHP array statically + * + * The load method, when supplied with a YAML stream (string or file), + * will do its best to convert YAML in a file into a PHP array. Pretty + * simple. + * Usage: + * <code> + * $array = Spyc::YAMLLoad('lucky.yaml'); + * print_r($array); + * </code> + * @access public + * @return array + * @param string $input Path of YAML file or string containing YAML + */ + public static function YAMLLoad($input) { + $Spyc = new Spyc; + return $Spyc->__load($input); + } + + /** + * Load a string of YAML into a PHP array statically + * + * The load method, when supplied with a YAML string, will do its best + * to convert YAML in a string into a PHP array. Pretty simple. + * + * Note: use this function if you don't want files from the file system + * loaded and processed as YAML. This is of interest to people concerned + * about security whose input is from a string. + * + * Usage: + * <code> + * $array = Spyc::YAMLLoadString("---\n0: hello world\n"); + * print_r($array); + * </code> + * @access public + * @return array + * @param string $input String containing YAML + */ + public static function YAMLLoadString($input) { + $Spyc = new Spyc; + return $Spyc->__loadString($input); + } + + /** + * Dump YAML from PHP array statically + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. Pretty simple. Feel free to + * save the returned string as nothing.yaml and pass it around. + * + * Oh, and you can decide how big the indent is and what the wordwrap + * for folding is. Pretty cool -- just pass in 'false' for either if + * you want to use the default. + * + * Indent's default is 2 spaces, wordwrap's default is 40 characters. And + * you can turn off wordwrap by passing in 0. + * + * @access public + * @return string + * @param array $array PHP array + * @param int $indent Pass in false to use the default, which is 2 + * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) + */ + public static function YAMLDump($array,$indent = false,$wordwrap = false) { + $spyc = new Spyc; + return $spyc->dump($array,$indent,$wordwrap); + } + + + /** + * Dump PHP array to YAML + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. Pretty simple. Feel free to + * save the returned string as tasteful.yaml and pass it around. + * + * Oh, and you can decide how big the indent is and what the wordwrap + * for folding is. Pretty cool -- just pass in 'false' for either if + * you want to use the default. + * + * Indent's default is 2 spaces, wordwrap's default is 40 characters. And + * you can turn off wordwrap by passing in 0. + * + * @access public + * @return string + * @param array $array PHP array + * @param int $indent Pass in false to use the default, which is 2 + * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) + */ + public function dump($array,$indent = false,$wordwrap = false) { + // Dumps to some very clean YAML. We'll have to add some more features + // and options soon. And better support for folding. + + // New features and options. + if ($indent === false or !is_numeric($indent)) { + $this->_dumpIndent = 2; + } else { + $this->_dumpIndent = $indent; + } + + if ($wordwrap === false or !is_numeric($wordwrap)) { + $this->_dumpWordWrap = 40; + } else { + $this->_dumpWordWrap = $wordwrap; + } + + // New YAML document + $string = "---\n"; + + // Start at the base of the array and move through it. + if ($array) { + $array = (array)$array; + $previous_key = -1; + foreach ($array as $key => $value) { + if (!isset($first_key)) $first_key = $key; + $string .= $this->_yamlize($key,$value,0,$previous_key, $first_key, $array); + $previous_key = $key; + } + } + return $string; + } + + /** + * Attempts to convert a key / value array item to YAML + * @access private + * @return string + * @param $key The name of the key + * @param $value The value of the item + * @param $indent The indent of the current node + */ + private function _yamlize($key,$value,$indent, $previous_key = -1, $first_key = 0, $source_array = null) { + if (is_array($value)) { + if (empty ($value)) + return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key, $source_array); + // It has children. What to do? + // Make it the right kind of item + $string = $this->_dumpNode($key, self::REMPTY, $indent, $previous_key, $first_key, $source_array); + // Add the indent + $indent += $this->_dumpIndent; + // Yamlize the array + $string .= $this->_yamlizeArray($value,$indent); + } elseif (!is_array($value)) { + // It doesn't have children. Yip. + $string = $this->_dumpNode($key, $value, $indent, $previous_key, $first_key, $source_array); + } + return $string; + } + + /** + * Attempts to convert an array to YAML + * @access private + * @return string + * @param $array The array you want to convert + * @param $indent The indent of the current level + */ + private function _yamlizeArray($array,$indent) { + if (is_array($array)) { + $string = ''; + $previous_key = -1; + foreach ($array as $key => $value) { + if (!isset($first_key)) $first_key = $key; + $string .= $this->_yamlize($key, $value, $indent, $previous_key, $first_key, $array); + $previous_key = $key; + } + return $string; + } else { + return false; + } + } + + /** + * Returns YAML from a key and a value + * @access private + * @return string + * @param $key The name of the key + * @param $value The value of the item + * @param $indent The indent of the current node + */ + private function _dumpNode($key, $value, $indent, $previous_key = -1, $first_key = 0, $source_array = null) { + // do some folding here, for blocks + if (is_string ($value) && ((strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false || + strpos($value,"*") !== false || strpos($value,"#") !== false || strpos($value,"<") !== false || strpos($value,">") !== false || strpos ($value, ' ') !== false || + strpos($value,"[") !== false || strpos($value,"]") !== false || strpos($value,"{") !== false || strpos($value,"}") !== false) || strpos($value,"&") !== false || strpos($value, "'") !== false || strpos($value, "!") === 0 || + substr ($value, -1, 1) == ':') + ) { + $value = $this->_doLiteralBlock($value,$indent); + } else { + $value = $this->_doFolding($value,$indent); + } + + if ($value === array()) $value = '[ ]'; + if (in_array ($value, array ('true', 'TRUE', 'false', 'FALSE', 'y', 'Y', 'n', 'N', 'null', 'NULL'), true)) { + $value = $this->_doLiteralBlock($value,$indent); + } + if (trim ($value) != $value) + $value = $this->_doLiteralBlock($value,$indent); + + if (is_bool($value)) { + $value = ($value) ? "true" : "false"; + } + + if ($value === null) $value = 'null'; + if ($value === "'" . self::REMPTY . "'") $value = null; + + $spaces = str_repeat(' ',$indent); + + //if (is_int($key) && $key - 1 == $previous_key && $first_key===0) { + if (is_array ($source_array) && array_keys($source_array) === range(0, count($source_array) - 1)) { + // It's a sequence + $string = $spaces.'- '.$value."\n"; + } else { + // if ($first_key===0) throw new Exception('Keys are all screwy. The first one was zero, now it\'s "'. $key .'"'); + // It's mapped + if (strpos($key, ":") !== false || strpos($key, "#") !== false) { $key = '"' . $key . '"'; } + $string = rtrim ($spaces.$key.': '.$value)."\n"; + } + return $string; + } + + /** + * Creates a literal block for dumping + * @access private + * @return string + * @param $value + * @param $indent int The value of the indent + */ + private function _doLiteralBlock($value,$indent) { + if ($value === "\n") return '\n'; + if (strpos($value, "\n") === false && strpos($value, "'") === false) { + return sprintf ("'%s'", $value); + } + if (strpos($value, "\n") === false && strpos($value, '"') === false) { + return sprintf ('"%s"', $value); + } + $exploded = explode("\n",$value); + $newValue = '|'; + $indent += $this->_dumpIndent; + $spaces = str_repeat(' ',$indent); + foreach ($exploded as $line) { + $newValue .= "\n" . $spaces . ($line); + } + return $newValue; + } + + /** + * Folds a string of text, if necessary + * @access private + * @return string + * @param $value The string you wish to fold + */ + private function _doFolding($value,$indent) { + // Don't do anything if wordwrap is set to 0 + + if ($this->_dumpWordWrap !== 0 && is_string ($value) && strlen($value) > $this->_dumpWordWrap) { + $indent += $this->_dumpIndent; + $indent = str_repeat(' ',$indent); + $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent"); + $value = ">\n".$indent.$wrapped; + } else { + if ($this->setting_dump_force_quotes && is_string ($value) && $value !== self::REMPTY) + $value = '"' . $value . '"'; + } + + + return $value; + } + +// LOADING FUNCTIONS + + private function __load($input) { + $Source = $this->loadFromSource($input); + return $this->loadWithSource($Source); + } + + private function __loadString($input) { + $Source = $this->loadFromString($input); + return $this->loadWithSource($Source); + } + + private function loadWithSource($Source) { + if (empty ($Source)) return array(); + if ($this->setting_use_syck_is_possible && function_exists ('syck_load')) { + $array = syck_load (implode ('', $Source)); + return is_array($array) ? $array : array(); + } + + $this->path = array(); + $this->result = array(); + + $cnt = count($Source); + for ($i = 0; $i < $cnt; $i++) { + $line = $Source[$i]; + + $this->indent = strlen($line) - strlen(ltrim($line)); + $tempPath = $this->getParentPathByIndent($this->indent); + $line = self::stripIndent($line, $this->indent); + if (self::isComment($line)) continue; + if (self::isEmpty($line)) continue; + $this->path = $tempPath; + + $literalBlockStyle = self::startsLiteralBlock($line); + if ($literalBlockStyle) { + $line = rtrim ($line, $literalBlockStyle . " \n"); + $literalBlock = ''; + $line .= $this->LiteralPlaceHolder; + $literal_block_indent = strlen($Source[$i+1]) - strlen(ltrim($Source[$i+1])); + while (++$i < $cnt && $this->literalBlockContinues($Source[$i], $this->indent)) { + $literalBlock = $this->addLiteralLine($literalBlock, $Source[$i], $literalBlockStyle, $literal_block_indent); + } + $i--; + } + + while (++$i < $cnt && self::greedilyNeedNextLine($line)) { + $line = rtrim ($line, " \n\t\r") . ' ' . ltrim ($Source[$i], " \t"); + } + $i--; + + + + if (strpos ($line, '#')) { + if (strpos ($line, '"') === false && strpos ($line, "'") === false) + $line = preg_replace('/\s+#(.+)$/','',$line); + } + + $lineArray = $this->_parseLine($line); + + if ($literalBlockStyle) + $lineArray = $this->revertLiteralPlaceHolder ($lineArray, $literalBlock); + + $this->addArray($lineArray, $this->indent); + + foreach ($this->delayedPath as $indent => $delayedPath) + $this->path[$indent] = $delayedPath; + + $this->delayedPath = array(); + + } + return $this->result; + } + + private function loadFromSource ($input) { + if (!empty($input) && strpos($input, "\n") === false && file_exists($input)) + return file($input); + + return $this->loadFromString($input); + } + + private function loadFromString ($input) { + $lines = explode("\n",$input); + foreach ($lines as $k => $_) { + $lines[$k] = rtrim ($_, "\r"); + } + return $lines; + } + + /** + * Parses YAML code and returns an array for a node + * @access private + * @return array + * @param string $line A line from the YAML file + */ + private function _parseLine($line) { + if (!$line) return array(); + $line = trim($line); + if (!$line) return array(); + + $array = array(); + + $group = $this->nodeContainsGroup($line); + if ($group) { + $this->addGroup($line, $group); + $line = $this->stripGroup ($line, $group); + } + + if ($this->startsMappedSequence($line)) + return $this->returnMappedSequence($line); + + if ($this->startsMappedValue($line)) + return $this->returnMappedValue($line); + + if ($this->isArrayElement($line)) + return $this->returnArrayElement($line); + + if ($this->isPlainArray($line)) + return $this->returnPlainArray($line); + + + return $this->returnKeyValuePair($line); + + } + + /** + * Finds the type of the passed value, returns the value as the new type. + * @access private + * @param string $value + * @return mixed + */ + private function _toType($value) { + if ($value === '') return null; + $first_character = $value[0]; + $last_character = substr($value, -1, 1); + + $is_quoted = false; + do { + if (!$value) break; + if ($first_character != '"' && $first_character != "'") break; + if ($last_character != '"' && $last_character != "'") break; + $is_quoted = true; + } while (0); + + if ($is_quoted) + return strtr(substr ($value, 1, -1), array ('\\"' => '"', '\'\'' => '\'', '\\\'' => '\'')); + + if (strpos($value, ' #') !== false && !$is_quoted) + $value = preg_replace('/\s+#(.+)$/','',$value); + + if (!$is_quoted) $value = str_replace('\n', "\n", $value); + + if ($first_character == '[' && $last_character == ']') { + // Take out strings sequences and mappings + $innerValue = trim(substr ($value, 1, -1)); + if ($innerValue === '') return array(); + $explode = $this->_inlineEscape($innerValue); + // Propagate value array + $value = array(); + foreach ($explode as $v) { + $value[] = $this->_toType($v); + } + return $value; + } + + if (strpos($value,': ')!==false && $first_character != '{') { + $array = explode(': ',$value); + $key = trim($array[0]); + array_shift($array); + $value = trim(implode(': ',$array)); + $value = $this->_toType($value); + return array($key => $value); + } + + if ($first_character == '{' && $last_character == '}') { + $innerValue = trim(substr ($value, 1, -1)); + if ($innerValue === '') return array(); + // Inline Mapping + // Take out strings sequences and mappings + $explode = $this->_inlineEscape($innerValue); + // Propagate value array + $array = array(); + foreach ($explode as $v) { + $SubArr = $this->_toType($v); + if (empty($SubArr)) continue; + if (is_array ($SubArr)) { + $array[key($SubArr)] = $SubArr[key($SubArr)]; continue; + } + $array[] = $SubArr; + } + return $array; + } + + if ($value == 'null' || $value == 'NULL' || $value == 'Null' || $value == '' || $value == '~') { + return null; + } + + if ( is_numeric($value) && preg_match ('/^(-|)[1-9]+[0-9]*$/', $value) ){ + $intvalue = (int)$value; + if ($intvalue != PHP_INT_MAX) + $value = $intvalue; + return $value; + } + + if (in_array($value, + array('true', 'on', '+', 'yes', 'y', 'True', 'TRUE', 'On', 'ON', 'YES', 'Yes', 'Y'))) { + return true; + } + + if (in_array(strtolower($value), + array('false', 'off', '-', 'no', 'n'))) { + return false; + } + + if (is_numeric($value)) { + if ($value === '0') return 0; + if (rtrim ($value, 0) === $value) + $value = (float)$value; + return $value; + } + + return $value; + } + + /** + * Used in inlines to check for more inlines or quoted strings + * @access private + * @return array + */ + private function _inlineEscape($inline) { + // There's gotta be a cleaner way to do this... + // While pure sequences seem to be nesting just fine, + // pure mappings and mappings with sequences inside can't go very + // deep. This needs to be fixed. + + $seqs = array(); + $maps = array(); + $saved_strings = array(); + + // Check for strings + $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/'; + if (preg_match_all($regex,$inline,$strings)) { + $saved_strings = $strings[0]; + $inline = preg_replace($regex,'YAMLString',$inline); + } + unset($regex); + + $i = 0; + do { + + // Check for sequences + while (preg_match('/\[([^{}\[\]]+)\]/U',$inline,$matchseqs)) { + $seqs[] = $matchseqs[0]; + $inline = preg_replace('/\[([^{}\[\]]+)\]/U', ('YAMLSeq' . (count($seqs) - 1) . 's'), $inline, 1); + } + + // Check for mappings + while (preg_match('/{([^\[\]{}]+)}/U',$inline,$matchmaps)) { + $maps[] = $matchmaps[0]; + $inline = preg_replace('/{([^\[\]{}]+)}/U', ('YAMLMap' . (count($maps) - 1) . 's'), $inline, 1); + } + + if ($i++ >= 10) break; + + } while (strpos ($inline, '[') !== false || strpos ($inline, '{') !== false); + + $explode = explode(', ',$inline); + $stringi = 0; $i = 0; + + while (1) { + + // Re-add the sequences + if (!empty($seqs)) { + foreach ($explode as $key => $value) { + if (strpos($value,'YAMLSeq') !== false) { + foreach ($seqs as $seqk => $seq) { + $explode[$key] = str_replace(('YAMLSeq'.$seqk.'s'),$seq,$value); + $value = $explode[$key]; + } + } + } + } + + // Re-add the mappings + if (!empty($maps)) { + foreach ($explode as $key => $value) { + if (strpos($value,'YAMLMap') !== false) { + foreach ($maps as $mapk => $map) { + $explode[$key] = str_replace(('YAMLMap'.$mapk.'s'), $map, $value); + $value = $explode[$key]; + } + } + } + } + + + // Re-add the strings + if (!empty($saved_strings)) { + foreach ($explode as $key => $value) { + while (strpos($value,'YAMLString') !== false) { + $explode[$key] = preg_replace('/YAMLString/',$saved_strings[$stringi],$value, 1); + unset($saved_strings[$stringi]); + ++$stringi; + $value = $explode[$key]; + } + } + } + + $finished = true; + foreach ($explode as $key => $value) { + if (strpos($value,'YAMLSeq') !== false) { + $finished = false; break; + } + if (strpos($value,'YAMLMap') !== false) { + $finished = false; break; + } + if (strpos($value,'YAMLString') !== false) { + $finished = false; break; + } + } + if ($finished) break; + + $i++; + if ($i > 10) + break; // Prevent infinite loops. + } + + return $explode; + } + + private function literalBlockContinues ($line, $lineIndent) { + if (!trim($line)) return true; + if (strlen($line) - strlen(ltrim($line)) > $lineIndent) return true; + return false; + } + + private function referenceContentsByAlias ($alias) { + do { + if (!isset($this->SavedGroups[$alias])) { echo "Bad group name: $alias."; break; } + $groupPath = $this->SavedGroups[$alias]; + $value = $this->result; + foreach ($groupPath as $k) { + $value = $value[$k]; + } + } while (false); + return $value; + } + + private function addArrayInline ($array, $indent) { + $CommonGroupPath = $this->path; + if (empty ($array)) return false; + + foreach ($array as $k => $_) { + $this->addArray(array($k => $_), $indent); + $this->path = $CommonGroupPath; + } + return true; + } + + private function addArray ($incoming_data, $incoming_indent) { + + // print_r ($incoming_data); + + if (count ($incoming_data) > 1) + return $this->addArrayInline ($incoming_data, $incoming_indent); + + $key = key ($incoming_data); + $value = isset($incoming_data[$key]) ? $incoming_data[$key] : null; + if ($key === '__!YAMLZero') $key = '0'; + + if ($incoming_indent == 0 && !$this->_containsGroupAlias && !$this->_containsGroupAnchor) { // Shortcut for root-level values. + if ($key || $key === '' || $key === '0') { + $this->result[$key] = $value; + } else { + $this->result[] = $value; end ($this->result); $key = key ($this->result); + } + $this->path[$incoming_indent] = $key; + return; + } + + + + $history = array(); + // Unfolding inner array tree. + $history[] = $_arr = $this->result; + foreach ($this->path as $k) { + $history[] = $_arr = $_arr[$k]; + } + + if ($this->_containsGroupAlias) { + $value = $this->referenceContentsByAlias($this->_containsGroupAlias); + $this->_containsGroupAlias = false; + } + + + // Adding string or numeric key to the innermost level or $this->arr. + if (is_string($key) && $key == '<<') { + if (!is_array ($_arr)) { $_arr = array (); } + + $_arr = array_merge ($_arr, $value); + } else if ($key || $key === '' || $key === '0') { + if (!is_array ($_arr)) + $_arr = array ($key=>$value); + else + $_arr[$key] = $value; + } else { + if (!is_array ($_arr)) { $_arr = array ($value); $key = 0; } + else { $_arr[] = $value; end ($_arr); $key = key ($_arr); } + } + + $reverse_path = array_reverse($this->path); + $reverse_history = array_reverse ($history); + $reverse_history[0] = $_arr; + $cnt = count($reverse_history) - 1; + for ($i = 0; $i < $cnt; $i++) { + $reverse_history[$i+1][$reverse_path[$i]] = $reverse_history[$i]; + } + $this->result = $reverse_history[$cnt]; + + $this->path[$incoming_indent] = $key; + + if ($this->_containsGroupAnchor) { + $this->SavedGroups[$this->_containsGroupAnchor] = $this->path; + if (is_array ($value)) { + $k = key ($value); + if (!is_int ($k)) { + $this->SavedGroups[$this->_containsGroupAnchor][$incoming_indent + 2] = $k; + } + } + $this->_containsGroupAnchor = false; + } + + } + + private static function startsLiteralBlock ($line) { + $lastChar = substr (trim($line), -1); + if ($lastChar != '>' && $lastChar != '|') return false; + if ($lastChar == '|') return $lastChar; + // HTML tags should not be counted as literal blocks. + if (preg_match ('#<.*?>$#', $line)) return false; + return $lastChar; + } + + private static function greedilyNeedNextLine($line) { + $line = trim ($line); + if (!strlen($line)) return false; + if (substr ($line, -1, 1) == ']') return false; + if ($line[0] == '[') return true; + if (preg_match ('#^[^:]+?:\s*\[#', $line)) return true; + return false; + } + + private function addLiteralLine ($literalBlock, $line, $literalBlockStyle, $indent = -1) { + $line = self::stripIndent($line, $indent); + if ($literalBlockStyle !== '|') { + $line = self::stripIndent($line); + } + $line = rtrim ($line, "\r\n\t ") . "\n"; + if ($literalBlockStyle == '|') { + return $literalBlock . $line; + } + if (strlen($line) == 0) + return rtrim($literalBlock, ' ') . "\n"; + if ($line == "\n" && $literalBlockStyle == '>') { + return rtrim ($literalBlock, " \t") . "\n"; + } + if ($line != "\n") + $line = trim ($line, "\r\n ") . " "; + return $literalBlock . $line; + } + + function revertLiteralPlaceHolder ($lineArray, $literalBlock) { + foreach ($lineArray as $k => $_) { + if (is_array($_)) + $lineArray[$k] = $this->revertLiteralPlaceHolder ($_, $literalBlock); + else if (substr($_, -1 * strlen ($this->LiteralPlaceHolder)) == $this->LiteralPlaceHolder) + $lineArray[$k] = rtrim ($literalBlock, " \r\n"); + } + return $lineArray; + } + + private static function stripIndent ($line, $indent = -1) { + if ($indent == -1) $indent = strlen($line) - strlen(ltrim($line)); + return substr ($line, $indent); + } + + private function getParentPathByIndent ($indent) { + if ($indent == 0) return array(); + $linePath = $this->path; + do { + end($linePath); $lastIndentInParentPath = key($linePath); + if ($indent <= $lastIndentInParentPath) array_pop ($linePath); + } while ($indent <= $lastIndentInParentPath); + return $linePath; + } + + + private function clearBiggerPathValues ($indent) { + + + if ($indent == 0) $this->path = array(); + if (empty ($this->path)) return true; + + foreach ($this->path as $k => $_) { + if ($k > $indent) unset ($this->path[$k]); + } + + return true; + } + + + private static function isComment ($line) { + if (!$line) return false; + if ($line[0] == '#') return true; + if (trim($line, " \r\n\t") == '---') return true; + return false; + } + + private static function isEmpty ($line) { + return (trim ($line) === ''); + } + + + private function isArrayElement ($line) { + if (!$line) return false; + if ($line[0] != '-') return false; + if (strlen ($line) > 3) + if (substr($line,0,3) == '---') return false; + + return true; + } + + private function isHashElement ($line) { + return strpos($line, ':'); + } + + private function isLiteral ($line) { + if ($this->isArrayElement($line)) return false; + if ($this->isHashElement($line)) return false; + return true; + } + + + private static function unquote ($value) { + if (!$value) return $value; + if (!is_string($value)) return $value; + if ($value[0] == '\'') return trim ($value, '\''); + if ($value[0] == '"') return trim ($value, '"'); + return $value; + } + + private function startsMappedSequence ($line) { + return ($line[0] == '-' && substr ($line, -1, 1) == ':'); + } + + private function returnMappedSequence ($line) { + $array = array(); + $key = self::unquote(trim(substr($line,1,-1))); + $array[$key] = array(); + $this->delayedPath = array(strpos ($line, $key) + $this->indent => $key); + return array($array); + } + + private function returnMappedValue ($line) { + $array = array(); + $key = self::unquote (trim(substr($line,0,-1))); + $array[$key] = ''; + return $array; + } + + private function startsMappedValue ($line) { + return (substr ($line, -1, 1) == ':'); + } + + private function isPlainArray ($line) { + return ($line[0] == '[' && substr ($line, -1, 1) == ']'); + } + + private function returnPlainArray ($line) { + return $this->_toType($line); + } + + private function returnKeyValuePair ($line) { + $array = array(); + $key = ''; + if (strpos ($line, ':')) { + // It's a key/value pair most likely + // If the key is in double quotes pull it out + if (($line[0] == '"' || $line[0] == "'") && preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) { + $value = trim(str_replace($matches[1],'',$line)); + $key = $matches[2]; + } else { + // Do some guesswork as to the key and the value + $explode = explode(':',$line); + $key = trim($explode[0]); + array_shift($explode); + $value = trim(implode(':',$explode)); + } + // Set the type of the value. Int, string, etc + $value = $this->_toType($value); + if ($key === '0') $key = '__!YAMLZero'; + $array[$key] = $value; + } else { + $array = array ($line); + } + return $array; + + } + + + private function returnArrayElement ($line) { + if (strlen($line) <= 1) return array(array()); // Weird %) + $array = array(); + $value = trim(substr($line,1)); + $value = $this->_toType($value); + $array[] = $value; + return $array; + } + + + private function nodeContainsGroup ($line) { + $symbolsForReference = 'A-z0-9_\-'; + if (strpos($line, '&') === false && strpos($line, '*') === false) return false; // Please die fast ;-) + if ($line[0] == '&' && preg_match('/^(&['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1]; + if ($line[0] == '*' && preg_match('/^(\*['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1]; + if (preg_match('/(&['.$symbolsForReference.']+)$/', $line, $matches)) return $matches[1]; + if (preg_match('/(\*['.$symbolsForReference.']+$)/', $line, $matches)) return $matches[1]; + if (preg_match ('#^\s*<<\s*:\s*(\*[^\s]+).*$#', $line, $matches)) return $matches[1]; + return false; + + } + + private function addGroup ($line, $group) { + if ($group[0] == '&') $this->_containsGroupAnchor = substr ($group, 1); + if ($group[0] == '*') $this->_containsGroupAlias = substr ($group, 1); + //print_r ($this->path); + } + + private function stripGroup ($line, $group) { + $line = trim(str_replace($group, '', $line)); + return $line; + } +} + +// Enable use of Spyc from command line +// The syntax is the following: php spyc.php spyc.yaml + +define ('SPYC_FROM_COMMAND_LINE', false); + +do { + if (!SPYC_FROM_COMMAND_LINE) break; + if (empty ($_SERVER['argc']) || $_SERVER['argc'] < 2) break; + if (empty ($_SERVER['PHP_SELF']) || $_SERVER['PHP_SELF'] != 'spyc.php') break; + $file = $argv[1]; + printf ("Spyc loading file: %s\n", $file); + print_r (spyc_load_file ($file)); } while (0);
\ No newline at end of file diff --git a/plugins/DevicesDetection/functions.php b/plugins/DevicesDetection/functions.php index 34f8ed8690..0812741aec 100644 --- a/plugins/DevicesDetection/functions.php +++ b/plugins/DevicesDetection/functions.php @@ -130,18 +130,16 @@ function Piwik_getOsFullNameExtended($label) if (!empty($label) && $label != ";") { $os = substr($label, 0, 3); $ver = substr($label, 4, 15); - $osFullName = array_search($os, UserAgentParserEnhanced::$osShorts); - if ($osFullName) { - if (in_array($os, UserAgentParserEnhanced::$osFamilies['Windows'])) { - return $osFullName; - } else { - return trim($osFullName . " " . $ver); - } + $name = UserAgentParserEnhanced::getOsNameFromId($os, $ver); + if(!empty($name)) { + return $name; } } return Piwik_Translate('General_Unknown'); } + + function Piwik_getOsLogoExtended($label) { $short = substr($label, 0, 3); diff --git a/plugins/DevicesDetection/lang/en.php b/plugins/DevicesDetection/lang/en.php index 3df87d9fd5..d6470a95fe 100644 --- a/plugins/DevicesDetection/lang/en.php +++ b/plugins/DevicesDetection/lang/en.php @@ -1,7 +1,7 @@ <?php $translations = array( - "DevicesDetection_description" => "Plugin providing extended information about mobile devices visiting page. Also new, more specific reports are available.", + "DevicesDetection_description" => "This plugin provides extended information about mobile devices, such as Brand (manufacturer), Model (device version), better Device type detection (tv, consoles, smart phones, desktop, etc) and more. This plugin adds a new report in 'Visitors > Devices'.", "DevicesDetection_submenu" => "Devices", 'DevicesDetection_DevicesDetection' => "Visitor devices", // DataTable label translations for reports diff --git a/tests/LocalTracker.php b/tests/LocalTracker.php index 961fa17fe3..52d46b4c2b 100755 --- a/tests/LocalTracker.php +++ b/tests/LocalTracker.php @@ -47,6 +47,7 @@ class Piwik_LocalTracker extends PiwikTracker // save some values $plugins = Piwik_Config::getInstance()->Plugins['Plugins']; + $plugins[] = 'DevicesDetection'; $pluginsTracker = Piwik_Config::getInstance()->Plugins_Tracker['Plugins_Tracker']; $oldTrackerConfig = Piwik_Config::getInstance()->Tracker; diff --git a/tests/PHPUnit/Core/PluginsFunctions/WidgetsListTest.php b/tests/PHPUnit/Core/PluginsFunctions/WidgetsListTest.php index 7c2c0e598c..f5861b94ca 100644 --- a/tests/PHPUnit/Core/PluginsFunctions/WidgetsListTest.php +++ b/tests/PHPUnit/Core/PluginsFunctions/WidgetsListTest.php @@ -70,9 +70,7 @@ class WidgetsListTest extends DatabaseTestCase $_GET['idSite'] = 1; - $pluginsManager = Piwik_PluginsManager::getInstance(); - $pluginsToLoad = Piwik_Config::getInstance()->Plugins['Plugins']; - $pluginsManager->loadPlugins($pluginsToLoad); + IntegrationTestCase::loadAllPlugins(); Piwik_WidgetsList::_reset(); $widgets = Piwik_GetWidgetsList(); @@ -109,9 +107,7 @@ class WidgetsListTest extends DatabaseTestCase $_GET['idSite'] = 1; - $pluginsManager = Piwik_PluginsManager::getInstance(); - $pluginsToLoad = Piwik_Config::getInstance()->Plugins['Plugins']; - $pluginsManager->loadPlugins($pluginsToLoad); + IntegrationTestCase::loadAllPlugins(); Piwik_WidgetsList::_reset(); $widgets = Piwik_GetWidgetsList(); diff --git a/tests/PHPUnit/Core/SegmentTest.php b/tests/PHPUnit/Core/SegmentTest.php index c007cc9d20..2a00a0a9b9 100644 --- a/tests/PHPUnit/Core/SegmentTest.php +++ b/tests/PHPUnit/Core/SegmentTest.php @@ -17,14 +17,13 @@ class SegmentTest extends PHPUnit_Framework_TestCase Zend_Registry::set('access', $pseudoMockAccess); // Load and install plugins - $pluginsManager = Piwik_PluginsManager::getInstance(); - $pluginsManager->loadPlugins(Piwik_Config::getInstance()->Plugins['Plugins']); + IntegrationTestCase::loadAllPlugins(); } public function tearDown() { parent::tearDown(); - Piwik_PluginsManager::getInstance()->unloadPlugins(); + IntegrationTestCase::unloadAllPlugins(); } protected function _filterWhitsSpaces($valueToFilter) diff --git a/tests/PHPUnit/IntegrationTestCase.php b/tests/PHPUnit/IntegrationTestCase.php index 5dae1def65..a1a5c9948d 100755 --- a/tests/PHPUnit/IntegrationTestCase.php +++ b/tests/PHPUnit/IntegrationTestCase.php @@ -69,11 +69,11 @@ abstract class IntegrationTestCase extends PHPUnit_Framework_TestCase } } - public static function loadAllPlugins() { $pluginsManager = Piwik_PluginsManager::getInstance(); $pluginsToLoad = Piwik_Config::getInstance()->Plugins['Plugins']; + $pluginsToLoad[] = 'DevicesDetection'; $pluginsManager->loadPlugins($pluginsToLoad); } diff --git a/tests/PHPUnit/proxy/piwik.php b/tests/PHPUnit/proxy/piwik.php index f70183ed16..0be50af23b 100755 --- a/tests/PHPUnit/proxy/piwik.php +++ b/tests/PHPUnit/proxy/piwik.php @@ -25,6 +25,13 @@ require_once PIWIK_INCLUDE_PATH . '/core/Loader.php'; Piwik::createConfigObject(); Piwik_Config::getInstance()->setTestEnvironment(); Piwik_Config::getInstance()->PluginsInstalled['PluginsInstalled'] = array(); +try { + $trackerPlugins = Piwik_Config::getInstance()->Plugins_Tracker['Plugins_Tracker']; +}catch(Exception $e) { + $trackerPlugins = array(); +} +$trackerPlugins[] = 'DevicesDetection'; +Piwik_Config::getInstance()->Plugins_Tracker['Plugins_Tracker'] = $trackerPlugins; Piwik_UserCountry_LocationProvider_GeoIp::$geoIPDatabaseDir = 'tests/lib/geoip-files'; Piwik_Tracker::setTestEnvironment(); |