@param string $userAgent

@return string
355851
public function applyRecoveryMatch($userAgent)
    {
        if (Utils::checkIfContains($userAgent, 'MSIE 10.0') && Utils::checkIfContains(
            $userAgent,
            'Xbox One'
        )
        ) {
            return 'microsoft_xboxone_ver1';
        }

        if (Utils::checkIfContains($userAgent, 'MSIE 10.0')) {
            return 'microsoft_xbox360_ver1_subie10';
        }

        return 'microsoft_xbox360_ver1';
    }
1255637
public function applyRecoveryMatch($userAgent)
    {
        if (Utils::checkIfContainsAll(
            $userAgent,
            array('Windows NT 5', 'POLARIS')
        )
        ) {
            return 'generic_lguplus_rexos_facebook_browser';
        }

        if (Utils::checkIfContains($userAgent, 'Windows NT 5')) {
            return 'generic_lguplus_rexos_webviewer_browser';
        }

        if (Utils::checkIfContainsAll(
            $userAgent,
            array('Windows CE', 'POLARIS')
        )
        ) {
            return 'generic_lguplus_winmo_facebook_browser';
        }

        if (Utils::checkIfContainsAll(
            $userAgent,
            array('Android', 'AppleWebKit')
        )
        ) {
            return 'generic_lguplus_android_webkit_browser';
        }

        return WurflConstants::NO_MATCH;
    }
1304018
public function applyRecoveryCatchAllMatch($userAgent)
    {
        if (WURFL_Handlers_Utils::isDesktopBrowserHeavyDutyAnalysis($userAgent)) {
            return WURFL_Constants::GENERIC_WEB_BROWSER;
        }

        if (WURFL_Handlers_Utils::checkIfContains($userAgent, 'CoreMedia')) {
            return 'apple_iphone_coremedia_ver1';
        }
        if (WURFL_Handlers_Utils::checkIfContains($userAgent, 'Windows CE')) {
            return 'generic_ms_mobile';
        }
        if (WURFL_Handlers_Utils::checkIfContains($userAgent, 'UP.Browser/7.2')) {
            return 'opwv_v72_generic';
        }
        if (WURFL_Handlers_Utils::checkIfContains($userAgent, 'UP.Browser/7')) {
            return 'opwv_v7_generic';
        }
        if (WURFL_Handlers_Utils::checkIfContains($userAgent, 'UP.Browser/6.2')) {
            return 'opwv_v62_generic';
        }
        if (WURFL_Handlers_Utils::checkIfContains($userAgent, 'UP.Browser/6')) {
            return 'opwv_v6_generic';
        }
        if (WURFL_Handlers_Utils::checkIfContains($userAgent, 'UP.Browser/5')) {
            return 'upgui_generic';
        }
        if (WURFL_Handlers_Utils::checkIfContains($userAgent, 'UP.Browser/4')) {
            return 'uptext_generic';
        }
        if (WURFL_Handlers_Utils::checkIfContains($userAgent, 'UP.Browser/3')) {
            return 'uptext_generic';
        }
        // Series 60
        if (WURFL_Handlers_Utils::checkIfContains($userAgent, 'Series60')) {
            return 'nokia_generic_series60';
        }
        // Access/Net Front
        if (WURFL_Handlers_Utils::checkIfContainsAnyOf($userAgent, array('NetFront/3.0', 'ACS-NF/3.0'))) {
            return 'generic_netfront_ver3';
        }
        if (WURFL_Handlers_Utils::checkIfContainsAnyOf($userAgent, array('NetFront/3.1', 'ACS-NF/3.1'))) {
            return 'generic_netfront_ver3_1';
        }
        if (WURFL_Handlers_Utils::checkIfContainsAnyOf($userAgent, array('NetFront/3.2', 'ACS-NF/3.2'))) {
            return 'generic_netfront_ver3_2';
        }
        if (WURFL_Handlers_Utils::checkIfContainsAnyOf($userAgent, array('NetFront/3.3', 'ACS-NF/3.3'))) {
            return 'generic_netfront_ver3_3';
        }
        if (WURFL_Handlers_Utils::checkIfContains($userAgent, 'NetFront/3.4')) {
            return 'generic_netfront_ver3_4';
        }
        if (WURFL_Handlers_Utils::checkIfContains($userAgent, 'NetFront/3.5')) {
            return 'generic_netfront_ver3_5';
        }
        if (WURFL_Handlers_Utils::checkIfContains($userAgent, 'NetFront/4.0')) {
            return 'generic_netfront_ver4_0';
        }
        // Contains Mozilla/, but not at the beginning of the UA
        // ie: MOTORAZR V8/R601_G_80.41.17R Mozilla/4.0 (compatible; MSIE 6.0 Linux; MOTORAZR V88.50) Profile/MIDP-2.0 Configuration/CLDC-1.1 Opera 8.50[zh]
        if (strpos($userAgent, 'Mozilla/') > 0) {
            return WURFL_Constants::GENERIC_XHTML;
        }
        if (WURFL_Handlers_Utils::checkIfContainsAnyOf($userAgent, array('Obigo', 'AU-MIC/2', 'AU-MIC-', 'AU-OBIGO/', 'Teleca Q03B1'))) {
            return WURFL_Constants::GENERIC_XHTML;
        }
        // DoCoMo
        if (WURFL_Handlers_Utils::checkIfStartsWithAnyOf($userAgent, array('DoCoMo', 'KDDI'))) {
            return 'docomo_generic_jap_ver1';
        }

        if (WURFL_Handlers_Utils::isMobileBrowser($userAgent)) {
            return WURFL_Constants::GENERIC_MOBILE;
        }
        return WURFL_Constants::GENERIC;
    }
302623
public function parse(string $useragent): array
    {
        if (preg_match('/new-sogou-spider|zollard|socialradarbot|microsoft office protocol discovery|powermarks|archivebot|marketwirebot|microsoft-cryptoapi|pad-bot|james bot|winhttp|jobboerse|<|>|online-versicherungsportal\.info|versicherungssuchmaschine\.net|microsearch|microsoft data access|microsoft url control|infegyatlas|msie or firefox mutant|semantic-visions\.com crawler|labs\.topsy\.com\/butterfly|dolphin http client|google wireless transcoder|commoncrawler|ipodder|tripadvisor|nokia wap gateway|outclicksbot/i', $useragent)) {
            return $this->load('unknown', 'unknown', $useragent);
        }

        if (!preg_match('/freebsd|raspbian/i', $useragent)
            && preg_match('/darwin|cfnetwork/i', $useragent)
        ) {
            return $this->darwinParser->parse($useragent);
        }

        if ($this->mobileDevice->isMobile($useragent)) {
            return $this->mobileParser->parse($useragent);
        }

        if ($this->tvDevice->isTvDevice($useragent)) {
            return $this->tvParser->parse($useragent);
        }

        if ($this->desktopDevice->isDesktopDevice($useragent)) {
            return $this->desktopParser->parse($useragent);
        }

        return $this->load('unknown', 'unknown', $useragent);
    }
528926
public function setUserAgent($userAgent) {
		$this->userAgent = $userAgent;
		$this->removeHeader(self::HEADER_KEY_USER_AGENT);
		$this->addHeader(self::HEADER_KEY_USER_AGENT, $userAgent);
		return $this;
	}
1009658
public function normalize($userAgent)
    {
        $userAgent = str_ireplace('blackberry', 'BlackBerry', $userAgent);
        $pos       = strpos($userAgent, 'BlackBerry');

        if ($pos !== false && $pos > 0) {
            $userAgent = substr($userAgent, $pos);
        }

        return $userAgent;
    }
251742
public function browser($userAgent = null)
    {
        // Get browser rules
        $rules = $this->mergeRules(
            static::$additionalBrowsers, // NEW
            static::$browsers
        );

        return $this->findDetectionRulesAgainstUA($rules, $userAgent);
    }
519044
public function applyRecoveryCatchAllMatch($userAgent) {
		if (WURFL_Handlers_Utils::isDesktopBrowserHeavyDutyAnalysis($userAgent)) {
			return WURFL_Constants::GENERIC_WEB_BROWSER;
		}
		$mobile = WURFL_Handlers_Utils::isMobileBrowser($userAgent);
		$desktop = WURFL_Handlers_Utils::isDesktopBrowser($userAgent);
		
		if (!$desktop) {
			$deviceId = WURFL_Handlers_Utils::getMobileCatchAllId($userAgent);
			if ($deviceId !== WURFL_Constants::NO_MATCH) {
				return $deviceId;
			}
		}
		
		if ($mobile) return WURFL_Constants::GENERIC_MOBILE;
		if ($desktop) return WURFL_Constants::GENERIC_WEB_BROWSER;
		return WURFL_Constants::GENERIC;
	}
621181
public function applyRecoveryMatch($userAgent)
    {
        if (Utils::checkIfContains($userAgent, 'Froyo')) {
            return 'generic_android_ver2_2';
        }

        $androidVersion = self::getAndroidVersion($userAgent);
        $versionString  = str_replace('.', '_', $androidVersion);
        $deviceID       = 'generic_android_ver' . $versionString;

        if ($deviceID === 'generic_android_ver2_0') {
            $deviceID = 'generic_android_ver2';
        }

        if ($deviceID === 'generic_android_ver4_0') {
            $deviceID = 'generic_android_ver4';
        }

        if (($androidVersion < 3.0 || $androidVersion >= 4.0) && Utils::checkIfContains(
            $userAgent,
            'Safari'
        ) && !Utils::checkIfContains($userAgent, 'Mobile')
        ) {
            // This is probably a tablet (Android 3.x is always a tablet, so it doesn't have a '_tablet' ID)
            if (in_array($deviceID . '_tablet', self::$constantIDs)) {
                return $deviceID . '_tablet';
            }

            return 'generic_android_ver1_5_tablet';
        }

        if (in_array($deviceID, self::$constantIDs)) {
            return $deviceID;
        }

        return 'generic_android';
    }
164770
public static function getSafariVersion($userAgent)
    {
        $search = 'Version/';
        $idx    = strpos($userAgent, $search);

        if ($idx === false) {
            return null;
        }

        $idx += strlen($search);
        $endIdx = strpos($userAgent, '.', $idx);

        if ($endIdx === false) {
            return null;
        }

        return substr($userAgent, $idx, $endIdx - $idx);
    }
127303
public function platform($userAgent = null)
    {
        // Get platform rules
        $rules = $this->mergeRules(
            static::$operatingSystems,
            static::$additionalOperatingSystems // NEW
        );

        return $this->findDetectionRulesAgainstUA($rules, $userAgent);
    }
853757
public static function extractFromUserAgent($userAgent)
    {
        $userAgent = trim($userAgent);

        /**
         * @see http://www.texsoft.it/index.php?c=software&m=sw.php.useragent&l=it
         */
        $pattern =  "(([^/\s]*)(/(\S*))?)(\s*\[[a-zA-Z][a-zA-Z]\])?\s*(\\((([^()]|(\\([^()]*\\)))*)\\))?\s*";
        preg_match("#^$pattern#", $userAgent, $match);

        $comment = array();
        if (isset($match[7])) {
            $comment = explode(';', $match[7]);
        }

        // second part if exists
        $end = substr($userAgent, strlen($match[0]));
        if (!empty($end)) {
            $result['others']['full'] = $end;
        }

        $match2 = array();
        if (isset($result['others'])) {
            preg_match_all('/(([^\/\s]*)(\/)?([^\/\(\)\s]*)?)(\s\((([^\)]*)*)\))?/i', $result['others']['full'], $match2);
        }
        $result['user_agent']   = trim($match[1]);
        $result['product_name'] = isset($match[2]) ? trim($match[2]) : '';
        $result['browser_name'] = $result['product_name'];
        if (isset($match[4]) && trim($match[4])) {
            $result['product_version'] = trim($match[4]);
            $result['browser_version'] = trim($match[4]);
        }
        if (count($comment) && !empty($comment[0])) {
            $result['comment']['full']     = trim($match[7]);
            $result['comment']['detail']   = $comment;
            $result['compatibility_flag']  = trim($comment[0]);
            if (isset($comment[1])) {
                $result['browser_token']   = trim($comment[1]);
            }
            if (isset($comment[2])) {
                $result['device_os_token'] = trim($comment[2]);
            }
        }
        if (empty($result['device_os_token']) && !empty($result['compatibility_flag'])) {
            // some browsers do not have a platform token
            $result['device_os_token'] = $result['compatibility_flag'];
        }
        if ($match2) {
            $i = 0;
            $max = count($match2[0]);
            for ($i = 0; $i < $max; $i ++) {
                if (!empty($match2[0][$i])) {
                    $result['others']['detail'][] = array(
                        $match2[0][$i],
                        $match2[2][$i],
                        $match2[4][$i],
                    );
                }
            }
        }

        /** Security level */
        $security = array(
            'N' => 'no security',
            'U' => 'strong security',
            'I' => 'weak security',
        );
        if (!empty($result['browser_token'])) {
            if (isset($security[$result['browser_token']])) {
                $result['security_level'] = $security[$result['browser_token']];
                unset($result['browser_token']);
            }
        }

        $product = strtolower($result['browser_name']);

        // Mozilla : true && false
        $compatibleOrIe = false;
        if (isset($result['compatibility_flag']) && isset($result['comment'])) {
            $compatibleOrIe = ($result['compatibility_flag'] == 'compatible' || strpos($result['comment']['full'], "MSIE") !== false);
        }
        if ($product == 'mozilla' && $compatibleOrIe) {
            if (!empty($result['browser_token'])) {
                // Classic Mozilla chain
                preg_match_all('/([^\/\s].*)(\/|\s)(.*)/i', $result['browser_token'], $real);
            } else {
                // MSIE specific chain with 'Windows' compatibility flag
                foreach ($result['comment']['detail'] as $v) {
                    if (strpos($v, 'MSIE') !== false) {
                        $real[0][1]               = trim($v);
                        $result['browser_engine'] = "MSIE";
                        $real[1][0]               = "Internet Explorer";
                        $temp                     = explode(' ', trim($v));
                        $real[3][0]               = $temp[1];

                    }
                    if (strpos($v, 'Win') !== false) {
                        $result['device_os_token'] = trim($v);
                    }
                }
            }

            if (!empty($real[0])) {
                $result['browser_name']    = $real[1][0];
                $result['browser_version'] = $real[3][0];
            } else {
                if(isset($result['browser_token'])) {
                    $result['browser_name']    = $result['browser_token'];
                }
                $result['browser_version'] = '??';
            }
        } elseif ($product == 'mozilla' && $result['browser_version'] < 5.0) {
            // handles the real Mozilla (or old Netscape if version < 5.0)
            $result['browser_name'] = 'Netscape';
        }

        /** windows */
        if ($result['browser_name'] == 'MSIE') {
            $result['browser_engine'] = 'MSIE';
            $result['browser_name']   = 'Internet Explorer';
        }
        if (isset($result['device_os_token'])) {
            if (strpos($result['device_os_token'], 'Win') !== false) {

                $windows = array(
                    'Windows NT 6.1'          => 'Windows 7',
                    'Windows NT 6.0'          => 'Windows Vista',
                    'Windows NT 5.2'          => 'Windows Server 2003',
                    'Windows NT 5.1'          => 'Windows XP',
                    'Windows NT 5.01'         => 'Windows 2000 SP1',
                    'Windows NT 5.0'          => 'Windows 2000',
                    'Windows NT 4.0'          => 'Microsoft Windows NT 4.0',
                    'WinNT'                   => 'Microsoft Windows NT 4.0',
                    'Windows 98; Win 9x 4.90' => 'Windows Me',
                    'Windows 98'              => 'Windows 98',
                    'Win98'                   => 'Windows 98',
                    'Windows 95'              => 'Windows 95',
                    'Win95'                   => 'Windows 95',
                    'Windows CE'              => 'Windows CE',
                );
                if (isset($windows[$result['device_os_token']])) {
                    $result['device_os_name'] = $windows[$result['device_os_token']];
                } else {
                    $result['device_os_name'] = $result['device_os_token'];
                }
            }
        }

        // iphone
        $apple_device = array(
            'iPhone',
            'iPod',
            'iPad',
        );
        if (isset($result['compatibility_flag'])) {
            if (in_array($result['compatibility_flag'], $apple_device)) {
                $result['device']           = strtolower($result['compatibility_flag']);
                $result['device_os_token']  = 'iPhone OS';
                if (isset($comment[3])) {
                    $result['browser_language'] = trim($comment[3]);
                }
                if (isset($result['others']['detail'][1])) {
                    $result['browser_version']  = $result['others']['detail'][1][2];
                } elseif (isset($result['others']['detail']) && count($result['others']['detail'])) {
                    $result['browser_version']  = $result['others']['detail'][0][2];
                }
                if (!empty($result['others']['detail'][2])) {
                    $result['firmware'] = $result['others']['detail'][2][2];
                }
                if (!empty($result['others']['detail'][3])) {
                    $result['browser_name']  = $result['others']['detail'][3][1];
                    $result['browser_build'] = $result['others']['detail'][3][2];
                }
            }
        }

        // Safari
        if (isset($result['others'])) {
            if ($result['others']['detail'][0][1] == 'AppleWebKit') {
                $result['browser_engine'] = 'AppleWebKit';
                if (isset($result['others']['detail'][1]) && $result['others']['detail'][1][1] == 'Version') {
                    $result['browser_version'] = $result['others']['detail'][1][2];
                } else {
                    $result['browser_version'] = $result['others']['detail'][count($result['others']['detail']) - 1][2];
                }
                if (isset($comment[3])) {
                     $result['browser_language'] = trim($comment[3]);
                }

                $last = $result['others']['detail'][count($result['others']['detail']) - 1][1];

                if (empty($result['others']['detail'][2][1]) || $result['others']['detail'][2][1] == 'Safari') {
                    if (isset($result['others']['detail'][1])) {
                        $result['browser_name']    = ($result['others']['detail'][1][1] && $result['others']['detail'][1][1] != 'Version' ? $result['others']['detail'][1][1] : 'Safari');
                        $result['browser_version'] = ($result['others']['detail'][1][2] ? $result['others']['detail'][1][2] : $result['others']['detail'][0][2]);
                    } else {
                        $result['browser_name']    = ($result['others']['detail'][0][1] && $result['others']['detail'][0][1] != 'Version' ? $result['others']['detail'][0][1] : 'Safari');
                        $result['browser_version'] = $result['others']['detail'][0][2];
                    }
                } else {
                    $result['browser_name']    = $result['others']['detail'][2][1];
                    $result['browser_version'] = $result['others']['detail'][2][2];

                    // mobile version
                    if ($result['browser_name'] == 'Mobile') {
                        $result['browser_name'] = 'Safari ' . $result['browser_name'];
                        if ($result['others']['detail'][1][1] == 'Version') {
                            $result['browser_version'] = $result['others']['detail'][1][2];
                        }
                    }
                }

                // For Safari < 2.2, AppleWebKit version gives the Safari version
                if (strpos($result['browser_version'], '.') > 2 || (int) $result['browser_version'] > 20) {
                    $temp = explode('.', $result['browser_version']);
                    $build = (int) $temp[0];
                    $awkVersion = array(
                        48  => '0.8',
                        73  => '0.9',
                        85  => '1.0',
                        103 => '1.1',
                        124 => '1.2',
                        300 => '1.3',
                        400 => '2.0',
                    );
                    foreach ($awkVersion as $k => $v) {
                        if ($build >= $k) {
                            $result['browser_version'] = $v;
                        }
                    }
                }
            }

            // Gecko (Firefox or compatible)
            if ($result['others']['detail'][0][1] == 'Gecko') {
                $searchRV = true;
                if (!empty($result['others']['detail'][1][1]) && !empty($result['others']['detail'][count($result['others']['detail']) - 1][2]) || strpos(strtolower($result['others']['full']), 'opera') !== false) {
                    $searchRV = false;
                    $result['browser_engine'] = $result['others']['detail'][0][1];

                    // the name of the application is at the end indepenently
                    // of quantity of information in $result['others']['detail']
                    $last = count($result['others']['detail']) - 1;

                    // exception : if the version of the last information is
                    // empty we take the previous one
                    if (empty($result['others']['detail'][$last][2])) {
                        $last --;
                    }

                    // exception : if the last one is 'Red Hat' or 'Debian' =>
                    // use rv: to find browser_version */
                    if (in_array($result['others']['detail'][$last][1], array(
                        'Debian',
                        'Hat',
                    ))) {
                        $searchRV = true;
                    }
                    $result['browser_name']    = $result['others']['detail'][$last][1];
                    $result['browser_version'] = $result['others']['detail'][$last][2];
                    if (isset($comment[4])) {
                        $result['browser_build'] = trim($comment[4]);
                    }
                    if (isset($comment[3])) {
                        $result['browser_language'] = trim($comment[3]);
                    }

                    // Netscape
                    if ($result['browser_name'] == 'Navigator' || $result['browser_name'] == 'Netscape6') {
                        $result['browser_name'] = 'Netscape';
                    }
                }
                if ($searchRV) {
                    // Mozilla alone : the version is identified by rv:
                    $result['browser_name'] = 'Mozilla';
                    if (isset($result['comment']['detail'])) {
                        foreach ($result['comment']['detail'] as $rv) {
                            if (strpos($rv, 'rv:') !== false) {
                                $result['browser_version'] = trim(str_replace('rv:', '', $rv));
                            }
                        }
                    }
                }
            }

            // Netscape
            if ($result['others']['detail'][0][1] == 'Netscape') {
                $result['browser_name']    = 'Netscape';
                $result['browser_version'] = $result['others']['detail'][0][2];
            }

            // Opera
            // Opera: engine Presto
            if ($result['others']['detail'][0][1] == 'Presto') {
                $result['browser_engine'] = 'Presto';
                if (!empty($result['others']['detail'][1][2])) {
                    $result['browser_version'] = $result['others']['detail'][1][2];
                }
            }

            // UA ends with 'Opera X.XX' or 'Opera/X.XX'
            if ($result['others']['detail'][0][1] == 'Opera') {
                $result['browser_name']    = $result['others']['detail'][0][1];
                // Opera X.XX
                if (isset($result['others']['detail'][1][1])) {
                    $result['browser_version'] = $result['others']['detail'][1][1];
                // Opera/X.XX
                } elseif (isset($result['others']['detail'][0][2])) {
                    $result['browser_version'] = $result['others']['detail'][0][2];
                }
            }

            // Opera Mini
            if (isset($result["browser_token"])) {
                if (strpos($result["browser_token"], 'Opera Mini') !== false) {
                    $result['browser_name'] = 'Opera Mini';
                }
            }

            // Symbian
            if ($result['others']['detail'][0][1] == 'SymbianOS') {
                $result['device_os_token'] = 'SymbianOS';
            }
        }

        // UA ends with 'Opera X.XX'
        if (isset($result['browser_name']) && isset($result['browser_engine'])) {
            if ($result['browser_name'] == 'Opera' && $result['browser_engine'] == 'Gecko' && empty($result['browser_version'])) {
                $result['browser_version'] = $result['others']['detail'][count($result['others']['detail']) - 1][1];
            }
        }

        // cleanup
        if (isset($result['browser_version']) && isset($result['browser_build'])) {
            if ($result['browser_version'] == $result['browser_build']) {
                unset($result['browser_build']);
            }
        }

        // compatibility
        $compatibility['AppleWebKit'] = 'Safari';
        $compatibility['Gecko']       = 'Firefox';
        $compatibility['MSIE']        = 'Internet Explorer';
        $compatibility['Presto']      = 'Opera';
        if (!empty($result['browser_engine'])) {
            if (isset($compatibility[$result['browser_engine']])) {
                $result['browser_compatibility'] = $compatibility[$result['browser_engine']];
            }
        }

        ksort($result);
        return $result;
    }
191085
public function normalize($userAgent)
    {
        $model     = WebOSHandler::getWebOSModelVersion($userAgent);
        $osVersion = WebOSHandler::getWebOSVersion($userAgent);

        if ($model !== null && $osVersion !== null) {
            $prefix = $model . ' ' . $osVersion . WurflConstants::RIS_DELIMITER;

            return $prefix . $userAgent;
        }

        return $userAgent;
    }
1197156
public function applyConclusiveMatch($userAgent)
    {
        $find      = 'NetFrontLifeBrowser/2.2';
        $tolerance = strpos($userAgent, $find) + strlen($find);

        if ($tolerance > strlen($userAgent)) {
            $tolerance = strlen($userAgent);
        }

        return $this->getDeviceIDFromRIS($userAgent, $tolerance);
    }
313882
public function userAgent($useragent) {

		if(false === is_string($useragent)) {
            return trigger_error(sprintf('Argument 1 passed to %s() must be of the type string, "%s" given', __METHOD__, gettype($useragent)), E_USER_ERROR);
        }

		$this -> options[CURLOPT_USERAGENT] = $useragent;

		return $this;
	}
787851
public function setUserAgent($userAgent = '')
    {
        $this->userAgent = $userAgent;
        $this->debug->info(__FUNCTION__, 'setUserAgent: ', $this->userAgent);

        return $this;
    }
947669
public function getBrowser(string $userAgent) : ?FormatterInterface
    {
        $userAgent = strtolower($userAgent);
        $formatter = null;

        foreach ($this->patternHelper->getPatterns($userAgent) as $patterns) {
            $patternToMatch = '/^(?:' . str_replace("\t", ')|(?:', $patterns) . ')$/i';

            if (! preg_match($patternToMatch, $userAgent)) {
                continue;
            }

            // strtok() requires less memory than explode()
            $pattern = strtok($patterns, "\t");

            while (false !== $pattern) {
                $pattern = str_replace('[\d]', '(\d)', $pattern);
                $quotedPattern = '/^' . $pattern . '$/i';
                $matches = [];

                if (preg_match($quotedPattern, $userAgent, $matches)) {
                    // Insert the digits back into the pattern, so that we can search the settings for it
                    if (1 < count($matches)) {
                        array_shift($matches);
                        foreach ($matches as $oneMatch) {
                            $numPos = strpos($pattern, '(\d)');
                            $pattern = substr_replace($pattern, $oneMatch, $numPos, 4);
                        }
                    }

                    // Try to get settings - as digits have been replaced to speed up the pattern search (up to 90 faster),
                    // we won't always find the data in the first step - so check if settings have been found and if not,
                    // search for the next pattern.
                    $settings = $this->dataHelper->getSettings($pattern);

                    if (0 < count($settings)) {
                        $formatter = $this->formatter;
                        $formatter->setData($settings);

                        break 2;
                    }
                }

                $pattern = strtok("\t");
            }
        }

        return $formatter;
    }