First commit

This commit is contained in:
Pierre Hubert
2016-11-19 12:08:12 +01:00
commit 990540b2b9
4706 changed files with 931207 additions and 0 deletions

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,115 @@
# PHP User Agent Parser
[![Latest Stable Version](https://poser.pugx.org/donatj/phpuseragentparser/v/stable.png)](https://packagist.org/packages/donatj/phpuseragentparser) [![Total Downloads](https://poser.pugx.org/donatj/phpuseragentparser/downloads.png)](https://packagist.org/packages/donatj/phpuseragentparser) [![Latest Unstable Version](https://poser.pugx.org/donatj/phpuseragentparser/v/unstable.png)](https://packagist.org/packages/donatj/phpuseragentparser) [![License](https://poser.pugx.org/donatj/phpuseragentparser/license.png)](https://packagist.org/packages/donatj/phpuseragentparser)
[![Build Status](https://travis-ci.org/donatj/PhpUserAgent.png?branch=master)](https://travis-ci.org/donatj/PhpUserAgent)
[![HHVM Status](http://hhvm.h4cc.de/badge/donatj/phpuseragentparser.png?style=flat)](http://hhvm.h4cc.de/package/donatj/phpuseragentparser)
## 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
### 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.
## 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
- 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
- Safari
- Internet Explorer
- IEMobile
- Chrome
- Opera
- Midori
- Vivaldi
- TizenBrowser
- UC Browser
- Lynx
- Wget
- Curl
More information is available at [Donat Studios](http://donatstudios.com/PHP-Parser-HTTP_USER_AGENT).

View File

@ -0,0 +1,156 @@
<?php
/**
* Parses a user agent string into its important parts
*
* @author Jesse G. Donat <donatj@gmail.com>
* @link https://github.com/donatj/PhpUserAgent
* @link http://donatstudios.com/PHP-Parser-HTTP_USER_AGENT
* @param string|null $u_agent User agent string to parse or null. Uses $_SERVER['HTTP_USER_AGENT'] on NULL
* @throws InvalidArgumentException on not having a proper user agent to parse.
* @return string[] an array with browser, version and platform keys
*/
function parse_user_agent( $u_agent = null ) {
if( is_null($u_agent) ) {
if( isset($_SERVER['HTTP_USER_AGENT']) ) {
$u_agent = $_SERVER['HTTP_USER_AGENT'];
} else {
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('/\((.*?)\)/im', $u_agent, $parent_matches) ) {
preg_match_all('/(?P<platform>BB\d+;|Android|CrOS|Tizen|iPhone|iPad|iPod|Linux|Macintosh|Windows(\ Phone)?|Silk|linux-gnu|BlackBerry|PlayBook|X11|(New\ )?Nintendo\ (WiiU?|3?DS)|Xbox(\ One)?)
(?:\ [^;]*)?
(?:;|$)/imx', $parent_matches[1], $result, PREG_PATTERN_ORDER);
$priority = array( 'Xbox One', 'Xbox', 'Windows Phone', 'Tizen', 'Android', '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|Safari|MSIE|Trident|AppleWebKit|TizenBrowser|Chrome|
Vivaldi|IEMobile|Opera|OPR|Silk|Midori|Edge|CriOS|UCBrowser|
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, PREG_PATTERN_ORDER);
// 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.]+)/si', $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' ) {
$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 Next';
$version = $result['version'][$key];
} elseif( $find('Opera', $key, $browser) ) {
$find('Version', $key);
$version = $result['version'][$key];
} elseif( $find(array( 'IEMobile', 'Edge', 'Midori', 'Vivaldi', 'Valve Steam Tenfoot', 'Chrome' ), $key, $browser) ) {
$version = $result['version'][$key];
} elseif( $browser == 'MSIE' || ($rv_result && $find('Trident', $key)) ) {
$browser = 'MSIE';
$version = $rv_result ?: $result['version'][$key];
} 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' && !($key = 0) ) {
$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', array_map('strtolower', $result['browser'])) ) {
$pKey = reset($pKey);
$platform = 'PlayStation ' . preg_replace('/[^\d]/i', '', $pKey);
$browser = 'NetFront';
}
return array( 'platform' => $platform ?: null, 'browser' => $browser ?: null, 'version' => $version ?: null );
}