first commit

This commit is contained in:
root
2020-02-19 16:42:35 +01:00
commit d668d90f82
2224 changed files with 334338 additions and 0 deletions

View File

@ -0,0 +1 @@
custom: https://www.paypal.me/donatj/5

View File

@ -0,0 +1,18 @@
# How to Contribute
## Reporting Issues
Issues can be reported via the [Github Issues](https://github.com/donatj/PhpUserAgent/issues) page.
- **Detail is key**: If a browser is being misidentified, one or more sample user agent strings are key to getting it resolved.
- **Missing Browser**: Is it modern? What is it being misidentified as? There are a lot of dead browsers out there that there is no reason to support.
Please do not file any requests for OS version identification. It is not a desired feature.
## Pull Requests
Pull requests are truly appreciated. While I try my best to stay on top of browsers hitting the market it is still a difficult task.
- **Formatting**: Indentation **must** use tabs. Please try to match internal formatting and spacing to existing code.
- **Tests**: If you're adding support for a new browser be sure to add test user agents for if at all possible ***every platform*** the browser is available on. Untested code will take much longer to be merged.
- **Terseness**: Try to be terse. Be clever. Take up as little space as possible. The point of this project initially was to be smaller than the other guys.

View File

@ -0,0 +1,22 @@
The MIT License
===============
Copyright (c) 2013 Jesse G. Donat
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,127 @@
# PHP User Agent Parser
[![Join the chat at https://gitter.im/PhpUserAgentParser/Lobby](https://badges.gitter.im/PhpUserAgentParser/Lobby.svg)](https://gitter.im/PhpUserAgentParser/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Latest Stable Version](https://poser.pugx.org/donatj/phpuseragentparser/v/stable.svg)](https://packagist.org/packages/donatj/phpuseragentparser) [![Total Downloads](https://poser.pugx.org/donatj/phpuseragentparser/downloads.svg)](https://packagist.org/packages/donatj/phpuseragentparser) [![Latest Unstable Version](https://poser.pugx.org/donatj/phpuseragentparser/v/unstable.svg)](https://packagist.org/packages/donatj/phpuseragentparser) [![License](https://poser.pugx.org/donatj/phpuseragentparser/license.svg)](https://packagist.org/packages/donatj/phpuseragentparser)
[![Build Status](https://travis-ci.org/donatj/PhpUserAgent.svg?branch=master)](https://travis-ci.org/donatj/PhpUserAgent)
## What It Is
A simple, streamlined PHP user-agent parser!
Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
## Why Use This
You have your choice in user-agent parsers. This one detects **all modern browsers** in a very light, quick, understandable fashion.
It is less than 200 lines of code, and consists of just three regular expressions!
It can also correctly identify exotic versions of IE others fail on.
It offers 100% unit test coverage, is installable via Composer, and is very easy to use.
## What It Does Not Do
This is not meant as a browser "knowledge engine" but rather a simple parser. Anything not adequately provided directly by the user agent string itself will simply not be provided by this.
### OS Versions
User-agent strings **are not** a reliable source of OS Version!
- Many agents simply don't send the information.
- Others provide varying levels of accuracy.
- Parsing Windows versions alone almost nearly doubles the size of the code.
I'm much more interested in keeping this thing *tiny* and accurate than adding niché features and would rather focus on things that can be **done well**.
All that said, there is the start of a [branch to do it](https://github.com/donatj/PhpUserAgent/tree/os_version_detection) I created for a client if you want to poke it, I update it from time to time, but frankly if you need to *reliably detect OS Version*, using user-agent isn't the way to do it. I'd go with JavaScript.
### Undetectable Browsers
- **Brave** - Brave is simply not differentiable from Chrome. This was a design descision on their part.
## Requirements
- PHP 5.3.0+
## Installing
PHP User Agent is available through Packagist via Composer.
```json
{
"require": {
"donatj/phpuseragentparser": "*"
}
}
```
## Sample Usage
```php
$ua_info = parse_user_agent();
/*
array(
'platform' => '[Detected Platform]',
'browser' => '[Detected Browser]',
'version' => '[Detected Browser Version]',
);
*/
```
## Currently Detected Platforms
- Desktop
- Windows
- Linux
- Macintosh
- Chrome OS
- Mobile
- Android
- iPhone
- iPad / iPod Touch
- Windows Phone OS
- Kindle
- Kindle Fire
- BlackBerry
- Playbook
- Tizen
- Console
- Oculus
- Nintendo 3DS
- New Nintendo 3DS
- Nintendo Wii
- Nintendo WiiU
- PlayStation 3
- PlayStation 4
- PlayStation Vita
- Xbox 360
- Xbox One
## Currently Detected Browsers
- Android Browser
- BlackBerry Browser
- Camino
- Kindle / Silk
- Firefox / IceWeasel / IceCat
- Safari
- Internet Explorer / Edge
- IEMobile
- Chrome / HeadlessChrome
- Yandex Browser
- Opera
- Midori
- Vivaldi
- TizenBrowser
- OculusBrowser
- SamsungBrowser
- UC Browser
- Lynx
- Wget
- Curl
- Puffin
More information is available at [Donat Studios](http://donatstudios.com/PHP-Parser-HTTP_USER_AGENT).

View File

@ -0,0 +1,24 @@
<?php
require __DIR__ . '/../src/UserAgentParser.php';
$time = microtime(true);
$uas = json_decode(file_get_contents(__DIR__ . '/../tests/user_agents.json'), true);
foreach( $uas as $ua => $junk ) {
$uatime = microtime(true);
for( $i = 0; $i <= 1000; $i++ ) {
\parse_user_agent($ua);
}
echo microtime(true) - $uatime;
echo " : $ua\n";
}
echo microtime(true) - $time;
echo " : TOTAL\n";

View File

@ -0,0 +1,13 @@
<?php
require(__DIR__ . '/../vendor/autoload.php');
$jsonfile = __DIR__ . '/../Tests/user_agents.json';
$uas = json_decode(file_get_contents($jsonfile), true);
foreach( $uas as $key => &$val ) {
$val = parse_user_agent($key);
}
echo json_encode($uas);

View File

@ -0,0 +1,91 @@
<?php
require(__DIR__ . '/../vendor/autoload.php');
$jsonfile = __DIR__ . '/../Tests/user_agents.json';
$uas = json_decode(file_get_contents($jsonfile), true);
foreach( $uas as $key => &$val ) {
$val['key'] = $key;
}
uasort($uas, function ( $a, $b ) {
if($a['platform'] === null && $b['platform'] !== null) return 1;
if($b['platform'] === null && $a['platform'] !== null) return -1;
$desktop = array( 'Windows', 'Linux', 'Macintosh', 'Chrome OS' );
$ad = in_array($a['platform'], $desktop);
$bd = in_array($b['platform'], $desktop);
if( !$ad && $bd ) return 1;
if( $ad && !$bd ) return -1;
if( $ad ) {
$result = strnatcasecmp($a['browser'], $b['browser']);
if( $result == 0 ) {
$result = strnatcasecmp($a['platform'], $b['platform']);
if( $result == 0 ) {
$result = compare_version($a['version'], $b['version']);
}
}
} else {
$result = strnatcasecmp($a['platform'], $b['platform']);
if( $result == 0 ) {
$result = strnatcasecmp($a['browser'], $b['browser']);
if( $result == 0 ) {
$result = compare_version($a['version'], $b['version']);
}
}
}
if( $result == 0 ) {
$result = strnatcasecmp($a['key'], $b['key']);
}
return $result;
});
foreach( $uas as &$val ) {
unset($val['key']);
}
$jsonPretty = new Camspiers\JsonPretty\JsonPretty;
$json = $jsonPretty->prettify($uas) . "\n";
echo $json;
file_put_contents($jsonfile, $json);
function compare_version( $a, $b ) {
$cmp_a = explode('.', $a);
$cmp_b = explode('.', $b);
$max = max(count($cmp_a), count($cmp_b));
$value = 0;
for( $i = 0; $i < $max; $i++ ) {
$aa = strtolower(isset($cmp_a[$i]) ? $cmp_a[$i] : '0');
$bb = strtolower(isset($cmp_b[$i]) ? $cmp_b[$i] : '0');
if( is_numeric($aa) && is_numeric($bb) ) {
if( $aa != $bb ) {
$value = ($aa > $bb ? 1 : -1);
break;
}
} else if( $cmp = strcmp($aa, $bb) ) {
$value = $cmp / abs($cmp);
break;
}
}
return $value;
}

View File

@ -0,0 +1,181 @@
<?php
/**
* Parses a user agent string into its important parts
*
* @param string|null $u_agent User agent string to parse or null. Uses $_SERVER['HTTP_USER_AGENT'] on NULL
* @return string[] an array with browser, version and platform keys
* @throws \InvalidArgumentException on not having a proper user agent to parse.
*
* @author Jesse G. Donat <donatj@gmail.com>
*
* @link https://donatstudios.com/PHP-Parser-HTTP_USER_AGENT
* @link https://github.com/donatj/PhpUserAgent
*
* @license MIT
*/
function parse_user_agent( $u_agent = null ) {
if( $u_agent === null && isset($_SERVER['HTTP_USER_AGENT']) ) {
$u_agent = $_SERVER['HTTP_USER_AGENT'];
}
if( $u_agent === null ) {
throw new \InvalidArgumentException('parse_user_agent requires a user agent');
}
$platform = null;
$browser = null;
$version = null;
$empty = array( 'platform' => $platform, 'browser' => $browser, 'version' => $version );
if( !$u_agent ) {
return $empty;
}
if( preg_match('/\((.*?)\)/m', $u_agent, $parent_matches) ) {
preg_match_all('/(?P<platform>BB\d+;|Android|CrOS|Tizen|iPhone|iPad|iPod|Linux|(Open|Net|Free)BSD|Macintosh|Windows(\ Phone)?|Silk|linux-gnu|BlackBerry|PlayBook|X11|(New\ )?Nintendo\ (WiiU?|3?DS|Switch)|Xbox(\ One)?)
(?:\ [^;]*)?
(?:;|$)/imx', $parent_matches[1], $result);
$priority = array( 'Xbox One', 'Xbox', 'Windows Phone', 'Tizen', 'Android', 'FreeBSD', 'NetBSD', 'OpenBSD', 'CrOS', 'X11' );
$result['platform'] = array_unique($result['platform']);
if( count($result['platform']) > 1 ) {
if( $keys = array_intersect($priority, $result['platform']) ) {
$platform = reset($keys);
} else {
$platform = $result['platform'][0];
}
} elseif( isset($result['platform'][0]) ) {
$platform = $result['platform'][0];
}
}
if( $platform == 'linux-gnu' || $platform == 'X11' ) {
$platform = 'Linux';
} elseif( $platform == 'CrOS' ) {
$platform = 'Chrome OS';
}
preg_match_all('%(?P<browser>Camino|Kindle(\ Fire)?|Firefox|Iceweasel|IceCat|Safari|MSIE|Trident|AppleWebKit|
TizenBrowser|(?:Headless)?Chrome|YaBrowser|Vivaldi|IEMobile|Opera|OPR|Silk|Midori|Edge|Edg|CriOS|UCBrowser|Puffin|OculusBrowser|SamsungBrowser|
Baiduspider|Googlebot|YandexBot|bingbot|Lynx|Version|Wget|curl|
Valve\ Steam\ Tenfoot|
NintendoBrowser|PLAYSTATION\ (\d|Vita)+)
(?:\)?;?)
(?:(?:[:/ ])(?P<version>[0-9A-Z.]+)|/(?:[A-Z]*))%ix',
$u_agent, $result);
// If nothing matched, return null (to avoid undefined index errors)
if( !isset($result['browser'][0]) || !isset($result['version'][0]) ) {
if( preg_match('%^(?!Mozilla)(?P<browser>[A-Z0-9\-]+)(/(?P<version>[0-9A-Z.]+))?%ix', $u_agent, $result) ) {
return array( 'platform' => $platform ?: null, 'browser' => $result['browser'], 'version' => isset($result['version']) ? $result['version'] ?: null : null );
}
return $empty;
}
if( preg_match('/rv:(?P<version>[0-9A-Z.]+)/i', $u_agent, $rv_result) ) {
$rv_result = $rv_result['version'];
}
$browser = $result['browser'][0];
$version = $result['version'][0];
$lowerBrowser = array_map('strtolower', $result['browser']);
$find = function ( $search, &$key, &$value = null ) use ( $lowerBrowser ) {
$search = (array)$search;
foreach( $search as $val ) {
$xkey = array_search(strtolower($val), $lowerBrowser);
if( $xkey !== false ) {
$value = $val;
$key = $xkey;
return true;
}
}
return false;
};
$key = 0;
$val = '';
if( $browser == 'Iceweasel' || strtolower($browser) == 'icecat' ) {
$browser = 'Firefox';
} elseif( $find('Playstation Vita', $key) ) {
$platform = 'PlayStation Vita';
$browser = 'Browser';
} elseif( $find(array( 'Kindle Fire', 'Silk' ), $key, $val) ) {
$browser = $val == 'Silk' ? 'Silk' : 'Kindle';
$platform = 'Kindle Fire';
if( !($version = $result['version'][$key]) || !is_numeric($version[0]) ) {
$version = $result['version'][array_search('Version', $result['browser'])];
}
} elseif( $find('NintendoBrowser', $key) || $platform == 'Nintendo 3DS' ) {
$browser = 'NintendoBrowser';
$version = $result['version'][$key];
} elseif( $find('Kindle', $key, $platform) ) {
$browser = $result['browser'][$key];
$version = $result['version'][$key];
} elseif( $find('OPR', $key) ) {
$browser = 'Opera';
$version = $result['version'][$key];
} elseif( $find('Opera', $key, $browser) ) {
$find('Version', $key);
$version = $result['version'][$key];
} elseif( $find('Puffin', $key, $browser) ) {
$version = $result['version'][$key];
if( strlen($version) > 3 ) {
$part = substr($version, -2);
if( ctype_upper($part) ) {
$version = substr($version, 0, -2);
$flags = array( 'IP' => 'iPhone', 'IT' => 'iPad', 'AP' => 'Android', 'AT' => 'Android', 'WP' => 'Windows Phone', 'WT' => 'Windows' );
if( isset($flags[$part]) ) {
$platform = $flags[$part];
}
}
}
} elseif( $find('YaBrowser', $key, $browser) ) {
$browser = 'Yandex';
$version = $result['version'][$key];
} elseif( $find(array( 'Edge', 'Edg' ), $key, $browser) ) {
$browser = 'Edge';
$version = $result['version'][$key];
} elseif( $find(array( 'IEMobile', 'Midori', 'Vivaldi', 'OculusBrowser', 'SamsungBrowser', 'Valve Steam Tenfoot', 'Chrome', 'HeadlessChrome' ), $key, $browser) ) {
$version = $result['version'][$key];
} elseif( $rv_result && $find('Trident', $key) ) {
$browser = 'MSIE';
$version = $rv_result;
} elseif( $find('UCBrowser', $key) ) {
$browser = 'UC Browser';
$version = $result['version'][$key];
} elseif( $find('CriOS', $key) ) {
$browser = 'Chrome';
$version = $result['version'][$key];
} elseif( $browser == 'AppleWebKit' ) {
if( $platform == 'Android' ) {
$browser = 'Android Browser';
} elseif( strpos($platform, 'BB') === 0 ) {
$browser = 'BlackBerry Browser';
$platform = 'BlackBerry';
} elseif( $platform == 'BlackBerry' || $platform == 'PlayBook' ) {
$browser = 'BlackBerry Browser';
} else {
$find('Safari', $key, $browser) || $find('TizenBrowser', $key, $browser);
}
$find('Version', $key);
$version = $result['version'][$key];
} elseif( $pKey = preg_grep('/playstation \d/i', $result['browser']) ) {
$pKey = reset($pKey);
$platform = 'PlayStation ' . preg_replace('/\D/', '', $pKey);
$browser = 'NetFront';
}
return array( 'platform' => $platform ?: null, 'browser' => $browser ?: null, 'version' => $version ?: null );
}

View File

@ -0,0 +1,50 @@
<?php
class UserAgentParserTest extends \PHPUnit_Framework_TestCase {
/**
* @dataProvider userAgentDataProvider
*/
public function test_parse_user_agent( $string, $expected ) {
$result = parse_user_agent($string);
$this->assertSame($expected, $result, $string . " test failed!");
}
public function userAgentDataProvider() {
$out = array();
$uas = json_decode(file_get_contents(__DIR__ . '/user_agents.json'), true);
foreach( $uas as $string => $parts ) {
$out[] = array( $string, $parts );
}
return $out;
}
public function test_parse_user_agent_empty() {
$expected = array(
'platform' => null,
'browser' => null,
'version' => null,
);
$result = parse_user_agent('');
$this->assertSame($result, $expected);
$result = parse_user_agent('Mozilla (asdjkakljasdkljasdlkj) BlahBlah');
$this->assertSame($result, $expected);
}
/**
* @expectedException \InvalidArgumentException
*/
public function test_no_user_agent_exception() {
unset($_SERVER['HTTP_USER_AGENT']);
parse_user_agent();
}
public function test_global_user_agent() {
$_SERVER['HTTP_USER_AGENT'] = 'Test/1.0';
$this->assertSame(array( 'platform' => null, 'browser' => 'Test', 'version' => '1.0' ), parse_user_agent());
}
}

File diff suppressed because it is too large Load Diff