Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authormattab <matthieu.aubry@gmail.com>2013-03-28 03:42:39 +0400
committermattab <matthieu.aubry@gmail.com>2013-03-28 03:42:40 +0400
commitae4b03163792f0b6e933933e5d37df87dc3fd566 (patch)
treed1d7510a9728f587d3d63ebd03e4ecf3d904838b /libs
parent158c2150f5f2e13ece459b8d131244c11b763997 (diff)
Mass conversion of all files to the newly agreed coding standard: PSR 1/2
Converting Piwik core source files, PHP, JS, TPL, CSS More info: http://piwik.org/participate/coding-standards/
Diffstat (limited to 'libs')
-rw-r--r--libs/PiwikTracker/PiwikTracker.php1618
-rw-r--r--libs/UserAgentParser/UserAgentParser.php1234
-rw-r--r--libs/UserAgentParser/UserAgentParser.test.php70
3 files changed, 1428 insertions, 1494 deletions
diff --git a/libs/PiwikTracker/PiwikTracker.php b/libs/PiwikTracker/PiwikTracker.php
index 7810fb196f..97e5acbc82 100644
--- a/libs/PiwikTracker/PiwikTracker.php
+++ b/libs/PiwikTracker/PiwikTracker.php
@@ -24,160 +24,158 @@
*/
class PiwikTracker
{
- /**
- * Piwik base URL, for example http://example.org/piwik/
- * Must be set before using the class by calling
- * PiwikTracker::$URL = 'http://yourwebsite.org/piwik/';
- *
- * @var string
- */
- static public $URL = '';
-
- /**
- * API Version
- *
- * @ignore
- * @var int
- */
- const VERSION = 1;
-
- /**
- * @ignore
- */
- public $DEBUG_APPEND_URL = '';
-
- /**
- * Visitor ID length
- *
- * @ignore
- */
- const LENGTH_VISITOR_ID = 16;
-
- /**
- * Charset
- * @see setPageCharset
- * @ignore
- */
- const DEFAULT_CHARSET_PARAMETER_VALUES = 'utf-8';
-
- /**
- * Builds a PiwikTracker object, used to track visits, pages and Goal conversions
- * for a specific website, by using the Piwik Tracking API.
- *
- * @param int $idSite Id site to be tracked
- * @param string $apiUrl "http://example.org/piwik/" or "http://piwik.example.org/"
- * If set, will overwrite PiwikTracker::$URL
- */
- function __construct( $idSite, $apiUrl = '' )
+ /**
+ * Piwik base URL, for example http://example.org/piwik/
+ * Must be set before using the class by calling
+ * PiwikTracker::$URL = 'http://yourwebsite.org/piwik/';
+ *
+ * @var string
+ */
+ static public $URL = '';
+
+ /**
+ * API Version
+ *
+ * @ignore
+ * @var int
+ */
+ const VERSION = 1;
+
+ /**
+ * @ignore
+ */
+ public $DEBUG_APPEND_URL = '';
+
+ /**
+ * Visitor ID length
+ *
+ * @ignore
+ */
+ const LENGTH_VISITOR_ID = 16;
+
+ /**
+ * Charset
+ * @see setPageCharset
+ * @ignore
+ */
+ const DEFAULT_CHARSET_PARAMETER_VALUES = 'utf-8';
+
+ /**
+ * Builds a PiwikTracker object, used to track visits, pages and Goal conversions
+ * for a specific website, by using the Piwik Tracking API.
+ *
+ * @param int $idSite Id site to be tracked
+ * @param string $apiUrl "http://example.org/piwik/" or "http://piwik.example.org/"
+ * If set, will overwrite PiwikTracker::$URL
+ */
+ function __construct($idSite, $apiUrl = '')
{
- $this->cookieSupport = true;
- $this->userAgent = false;
- $this->localHour = false;
- $this->localMinute = false;
- $this->localSecond = false;
- $this->hasCookies = false;
- $this->plugins = false;
- $this->visitorCustomVar = false;
- $this->pageCustomVar = false;
- $this->customData = false;
- $this->forcedDatetime = false;
- $this->token_auth = false;
- $this->attributionInfo = false;
- $this->ecommerceLastOrderTimestamp = false;
- $this->ecommerceItems = array();
- $this->generationTime = false;
-
- $this->requestCookie = '';
- $this->idSite = $idSite;
- $this->urlReferrer = @$_SERVER['HTTP_REFERER'];
- $this->pageCharset = self::DEFAULT_CHARSET_PARAMETER_VALUES;
- $this->pageUrl = self::getCurrentUrl();
- $this->ip = @$_SERVER['REMOTE_ADDR'];
- $this->acceptLanguage = @$_SERVER['HTTP_ACCEPT_LANGUAGE'];
- $this->userAgent = @$_SERVER['HTTP_USER_AGENT'];
- if(!empty($apiUrl))
- {
- self::$URL = $apiUrl;
- }
- $this->setNewVisitorId();
-
- // Allow debug while blocking the request
- $this->requestTimeout = 600;
- $this->doBulkRequests = false;
- $this->storedTrackingActions = array();
+ $this->cookieSupport = true;
+ $this->userAgent = false;
+ $this->localHour = false;
+ $this->localMinute = false;
+ $this->localSecond = false;
+ $this->hasCookies = false;
+ $this->plugins = false;
+ $this->visitorCustomVar = false;
+ $this->pageCustomVar = false;
+ $this->customData = false;
+ $this->forcedDatetime = false;
+ $this->token_auth = false;
+ $this->attributionInfo = false;
+ $this->ecommerceLastOrderTimestamp = false;
+ $this->ecommerceItems = array();
+ $this->generationTime = false;
+
+ $this->requestCookie = '';
+ $this->idSite = $idSite;
+ $this->urlReferrer = @$_SERVER['HTTP_REFERER'];
+ $this->pageCharset = self::DEFAULT_CHARSET_PARAMETER_VALUES;
+ $this->pageUrl = self::getCurrentUrl();
+ $this->ip = @$_SERVER['REMOTE_ADDR'];
+ $this->acceptLanguage = @$_SERVER['HTTP_ACCEPT_LANGUAGE'];
+ $this->userAgent = @$_SERVER['HTTP_USER_AGENT'];
+ if (!empty($apiUrl)) {
+ self::$URL = $apiUrl;
+ }
+ $this->setNewVisitorId();
+
+ // Allow debug while blocking the request
+ $this->requestTimeout = 600;
+ $this->doBulkRequests = false;
+ $this->storedTrackingActions = array();
}
- /**
- * By default, Piwik expects utf-8 encoded values, for example
- * for the page URL parameter values, Page Title, etc.
- * It is recommended to only send UTF-8 data to Piwik.
- * If required though, you can also specify another charset using this function.
- *
- * @param string $charset
- */
- public function setPageCharset( $charset = '' )
- {
- $this->pageCharset = $charset;
- }
+ /**
+ * By default, Piwik expects utf-8 encoded values, for example
+ * for the page URL parameter values, Page Title, etc.
+ * It is recommended to only send UTF-8 data to Piwik.
+ * If required though, you can also specify another charset using this function.
+ *
+ * @param string $charset
+ */
+ public function setPageCharset($charset = '')
+ {
+ $this->pageCharset = $charset;
+ }
/**
* Sets the current URL being tracked
- *
+ *
* @param string $url Raw URL (not URL encoded)
*/
- public function setUrl( $url )
+ public function setUrl($url)
{
- $this->pageUrl = $url;
+ $this->pageUrl = $url;
}
/**
* Sets the URL referrer used to track Referrers details for new visits.
- *
+ *
* @param string $url Raw URL (not URL encoded)
*/
- public function setUrlReferrer( $url )
+ public function setUrlReferrer($url)
{
- $this->urlReferrer = $url;
+ $this->urlReferrer = $url;
}
- /**
- * Sets the time that generating the document on the server side took.
- *
- * @param int $timeMs Generation time in ms
- */
- public function setGenerationTime( $timeMs )
- {
- $this->generationTime = $timeMs;
- }
-
- /**
- * @deprecated
+ /**
+ * Sets the time that generating the document on the server side took.
+ *
+ * @param int $timeMs Generation time in ms
+ */
+ public function setGenerationTime($timeMs)
+ {
+ $this->generationTime = $timeMs;
+ }
+
+ /**
+ * @deprecated
* @ignore
*/
- public function setUrlReferer( $url )
+ public function setUrlReferer($url)
{
- $this->setUrlReferrer($url);
+ $this->setUrlReferrer($url);
}
-
+
/**
- * Sets the attribution information to the visit, so that subsequent Goal conversions are
+ * Sets the attribution information to the visit, so that subsequent Goal conversions are
* properly attributed to the right Referrer URL, timestamp, Campaign Name & Keyword.
- *
- * This must be a JSON encoded string that would typically be fetched from the JS API:
- * piwikTracker.getAttributionInfo() and that you have JSON encoded via JSON2.stringify()
+ *
+ * This must be a JSON encoded string that would typically be fetched from the JS API:
+ * piwikTracker.getAttributionInfo() and that you have JSON encoded via JSON2.stringify()
*
* @param string $jsonEncoded JSON encoded array containing Attribution info
- * @throws Exception
+ * @throws Exception
* @see function getAttributionInfo() in https://github.com/piwik/piwik/blob/master/js/piwik.js
*/
- public function setAttributionInfo( $jsonEncoded )
+ public function setAttributionInfo($jsonEncoded)
{
- $decoded = json_decode($jsonEncoded, $assoc = true);
- if(!is_array($decoded))
- {
- throw new Exception("setAttributionInfo() is expecting a JSON encoded string, $jsonEncoded given");
- }
- $this->attributionInfo = $decoded;
+ $decoded = json_decode($jsonEncoded, $assoc = true);
+ if (!is_array($decoded)) {
+ throw new Exception("setAttributionInfo() is expecting a JSON encoded string, $jsonEncoded given");
+ }
+ $this->attributionInfo = $decoded;
}
/**
@@ -188,115 +186,103 @@ class PiwikTracker
* @param string $name Custom variable name
* @param string $value Custom variable value
* @param string $scope Custom variable scope. Possible values: visit, page
- * @throws Exception
+ * @throws Exception
*/
public function setCustomVariable($id, $name, $value, $scope = 'visit')
{
- if(!is_int($id))
- {
- throw new Exception("Parameter id to setCustomVariable should be an integer");
- }
- if($scope == 'page')
- {
- $this->pageCustomVar[$id] = array($name, $value);
- }
- elseif($scope == 'visit')
- {
- $this->visitorCustomVar[$id] = array($name, $value);
- }
- else
- {
- throw new Exception("Invalid 'scope' parameter value");
- }
+ if (!is_int($id)) {
+ throw new Exception("Parameter id to setCustomVariable should be an integer");
+ }
+ if ($scope == 'page') {
+ $this->pageCustomVar[$id] = array($name, $value);
+ } elseif ($scope == 'visit') {
+ $this->visitorCustomVar[$id] = array($name, $value);
+ } else {
+ throw new Exception("Invalid 'scope' parameter value");
+ }
}
-
+
/**
* Returns the currently assigned Custom Variable stored in a first party cookie.
- *
+ *
* This function will only work if the user is initiating the current request, and his cookies
* can be read by PHP from the $_COOKIE array.
- *
+ *
* @param int $id Custom Variable integer index to fetch from cookie. Should be a value from 1 to 5
* @param string $scope Custom variable scope. Possible values: visit, page
*
- * @throws Exception
+ * @throws Exception
* @return mixed An array with this format: array( 0 => CustomVariableName, 1 => CustomVariableValue ) or false
* @see Piwik.js getCustomVariable()
*/
public function getCustomVariable($id, $scope = 'visit')
{
- if($scope == 'page')
- {
- return isset($this->pageCustomVar[$id]) ? $this->pageCustomVar[$id] : false;
- }
- else if($scope != 'visit')
- {
- throw new Exception("Invalid 'scope' parameter value");
- }
- if(!empty($this->visitorCustomVar[$id]))
- {
- return $this->visitorCustomVar[$id];
- }
- $customVariablesCookie = 'cvar.'.$this->idSite.'.';
- $cookie = $this->getCookieMatchingName($customVariablesCookie);
- if(!$cookie)
- {
- return false;
- }
- if(!is_int($id))
- {
- throw new Exception("Parameter to getCustomVariable should be an integer");
- }
- $cookieDecoded = json_decode($cookie, $assoc = true);
- if(!is_array($cookieDecoded)
- || !isset($cookieDecoded[$id])
- || !is_array($cookieDecoded[$id])
- || count($cookieDecoded[$id]) != 2)
- {
- return false;
- }
- return $cookieDecoded[$id];
+ if ($scope == 'page') {
+ return isset($this->pageCustomVar[$id]) ? $this->pageCustomVar[$id] : false;
+ } else if ($scope != 'visit') {
+ throw new Exception("Invalid 'scope' parameter value");
+ }
+ if (!empty($this->visitorCustomVar[$id])) {
+ return $this->visitorCustomVar[$id];
+ }
+ $customVariablesCookie = 'cvar.' . $this->idSite . '.';
+ $cookie = $this->getCookieMatchingName($customVariablesCookie);
+ if (!$cookie) {
+ return false;
+ }
+ if (!is_int($id)) {
+ throw new Exception("Parameter to getCustomVariable should be an integer");
+ }
+ $cookieDecoded = json_decode($cookie, $assoc = true);
+ if (!is_array($cookieDecoded)
+ || !isset($cookieDecoded[$id])
+ || !is_array($cookieDecoded[$id])
+ || count($cookieDecoded[$id]) != 2
+ ) {
+ return false;
+ }
+ return $cookieDecoded[$id];
}
-
+
/**
* Sets the current visitor ID to a random new one.
*/
public function setNewVisitorId()
{
- $this->visitorId = substr(md5(uniqid(rand(), true)), 0, self::LENGTH_VISITOR_ID);
+ $this->visitorId = substr(md5(uniqid(rand(), true)), 0, self::LENGTH_VISITOR_ID);
}
-
+
/**
* Sets the current site ID.
- *
+ *
* @param int $idSite
*/
- public function setIdSite( $idSite )
+ public function setIdSite($idSite)
{
- $this->idSite = $idSite;
+ $this->idSite = $idSite;
}
-
+
/**
* Sets the Browser language. Used to guess visitor countries when GeoIP is not enabled
- *
+ *
* @param string $acceptLanguage For example "fr-fr"
*/
- public function setBrowserLanguage( $acceptLanguage )
+ public function setBrowserLanguage($acceptLanguage)
{
- $this->acceptLanguage = $acceptLanguage;
+ $this->acceptLanguage = $acceptLanguage;
}
/**
* Sets the user agent, used to detect OS and browser.
* If this function is not called, the User Agent will default to the current user agent.
- *
+ *
* @param string $userAgent
*/
public function setUserAgent($userAgent)
{
- $this->userAgent = $userAgent;
+ $this->userAgent = $userAgent;
}
-
+
/**
* Sets the country of the visitor. If not used, Piwik will try to find the country
* using either the visitor's IP address or language.
@@ -306,9 +292,9 @@ class PiwikTracker
*/
public function setCountry($country)
{
- $this->country = $country;
+ $this->country = $country;
}
-
+
/**
* Sets the region of the visitor. If not used, Piwik may try to find the region
* using the visitor's IP address (if configured to do so).
@@ -318,9 +304,9 @@ class PiwikTracker
*/
public function setRegion($region)
{
- $this->region = $region;
+ $this->region = $region;
}
-
+
/**
* Sets the city of the visitor. If not used, Piwik may try to find the city
* using the visitor's IP address (if configured to do so).
@@ -330,9 +316,9 @@ class PiwikTracker
*/
public function setCity($city)
{
- $this->city = $city;
+ $this->city = $city;
}
-
+
/**
* Sets the latitude of the visitor. If not used, Piwik may try to find the visitor's
* latitude using the visitor's IP address (if configured to do so).
@@ -342,9 +328,9 @@ class PiwikTracker
*/
public function setLatitude($lat)
{
- $this->lat = $lat;
+ $this->lat = $lat;
}
-
+
/**
* Sets the longitude of the visitor. If not used, Piwik may try to find the visitor's
* longitude using the visitor's IP address (if configured to do so).
@@ -354,62 +340,62 @@ class PiwikTracker
*/
public function setLongitude($long)
{
- $this->long = $long;
+ $this->long = $long;
}
-
- /**
- * Enables the bulk request feature. When used, each tracking action is stored until the
- * doBulkTrack method is called. This method will send all tracking data at once.
- */
- public function enableBulkTracking()
- {
- $this->doBulkRequests = true;
- }
-
+
+ /**
+ * Enables the bulk request feature. When used, each tracking action is stored until the
+ * doBulkTrack method is called. This method will send all tracking data at once.
+ */
+ public function enableBulkTracking()
+ {
+ $this->doBulkRequests = true;
+ }
+
/**
* Tracks a page view
- *
+ *
* @param string $documentTitle Page title as it will appear in the Actions > Page titles report
* @return mixed Response string or true if using bulk requests.
*/
- public function doTrackPageView( $documentTitle )
+ public function doTrackPageView($documentTitle)
{
- $url = $this->getUrlTrackPageView($documentTitle);
- return $this->sendRequest($url);
+ $url = $this->getUrlTrackPageView($documentTitle);
+ return $this->sendRequest($url);
}
- /**
- * Tracks an internal Site Search query, and optionally tracks the Search Category, and Search results Count.
- * These are used to populate reports in Actions > Site Search.
- *
- * @param string $keyword Searched query on the site
- * @param string $category Optional, Search engine category if applicable
- * @param int $countResults results displayed on the search result page. Used to track "zero result" keywords.
- *
- * @return mixed Response or true if using bulk requests.
- */
- public function doTrackSiteSearch( $keyword, $category = '', $countResults = false )
- {
- $url = $this->getUrlTrackSiteSearch($keyword, $category, $countResults);
- return $this->sendRequest($url);
- }
+ /**
+ * Tracks an internal Site Search query, and optionally tracks the Search Category, and Search results Count.
+ * These are used to populate reports in Actions > Site Search.
+ *
+ * @param string $keyword Searched query on the site
+ * @param string $category Optional, Search engine category if applicable
+ * @param int $countResults results displayed on the search result page. Used to track "zero result" keywords.
+ *
+ * @return mixed Response or true if using bulk requests.
+ */
+ public function doTrackSiteSearch($keyword, $category = '', $countResults = false)
+ {
+ $url = $this->getUrlTrackSiteSearch($keyword, $category, $countResults);
+ return $this->sendRequest($url);
+ }
/**
* Records a Goal conversion
- *
+ *
* @param int $idGoal Id Goal to record a conversion
* @param float $revenue Revenue for this conversion
* @return mixed Response or true if using bulk request
*/
public function doTrackGoal($idGoal, $revenue = 0.0)
{
- $url = $this->getUrlTrackGoal($idGoal, $revenue);
- return $this->sendRequest($url);
+ $url = $this->getUrlTrackGoal($idGoal, $revenue);
+ return $this->sendRequest($url);
}
-
+
/**
* Tracks a download or outlink
- *
+ *
* @param string $actionUrl URL of the download or outlink
* @param string $actionType Type of the action: 'download' or 'link'
* @return mixed Response or true if using bulk request
@@ -417,270 +403,257 @@ class PiwikTracker
public function doTrackAction($actionUrl, $actionType)
{
// Referrer could be udpated to be the current URL temporarily (to mimic JS behavior)
- $url = $this->getUrlTrackAction($actionUrl, $actionType);
- return $this->sendRequest($url);
+ $url = $this->getUrlTrackAction($actionUrl, $actionType);
+ return $this->sendRequest($url);
}
/**
* Adds an item in the Ecommerce order.
- *
+ *
* This should be called before doTrackEcommerceOrder(), or before doTrackEcommerceCartUpdate().
* This function can be called for all individual products in the cart (or order).
* SKU parameter is mandatory. Other parameters are optional (set to false if value not known).
* Ecommerce items added via this function are automatically cleared when doTrackEcommerceOrder() or getUrlTrackEcommerceOrder() is called.
- *
- * @param string $sku (required) SKU, Product identifier
+ *
+ * @param string $sku (required) SKU, Product identifier
* @param string $name (optional) Product name
* @param string|array $category (optional) Product category, or array of product categories (up to 5 categories can be specified for a given product)
* @param float|int $price (optional) Individual product price (supports integer and decimal prices)
* @param int $quantity (optional) Product quantity. If not specified, will default to 1 in the Reports
- * @throws Exception
+ * @throws Exception
*/
public function addEcommerceItem($sku, $name = '', $category = '', $price = 0.0, $quantity = 1)
{
- if(empty($sku))
- {
- throw new Exception("You must specify a SKU for the Ecommerce item");
- }
- $this->ecommerceItems[$sku] = array( $sku, $name, $category, $price, $quantity );
+ if (empty($sku)) {
+ throw new Exception("You must specify a SKU for the Ecommerce item");
+ }
+ $this->ecommerceItems[$sku] = array($sku, $name, $category, $price, $quantity);
}
-
- /**
- * Tracks a Cart Update (add item, remove item, update item).
- *
- * On every Cart update, you must call addEcommerceItem() for each item (product) in the cart,
- * including the items that haven't been updated since the last cart update.
- * Items which were in the previous cart and are not sent in later Cart updates will be deleted from the cart (in the database).
- *
- * @param float $grandTotal Cart grandTotal (typically the sum of all items' prices)
- * @return mixed Response or true if using bulk request
- */
+
+ /**
+ * Tracks a Cart Update (add item, remove item, update item).
+ *
+ * On every Cart update, you must call addEcommerceItem() for each item (product) in the cart,
+ * including the items that haven't been updated since the last cart update.
+ * Items which were in the previous cart and are not sent in later Cart updates will be deleted from the cart (in the database).
+ *
+ * @param float $grandTotal Cart grandTotal (typically the sum of all items' prices)
+ * @return mixed Response or true if using bulk request
+ */
public function doTrackEcommerceCartUpdate($grandTotal)
{
- $url = $this->getUrlTrackEcommerceCartUpdate($grandTotal);
- return $this->sendRequest($url);
+ $url = $this->getUrlTrackEcommerceCartUpdate($grandTotal);
+ return $this->sendRequest($url);
}
-
+
/**
* Sends all stored tracking actions at once. Only has an effect if bulk tracking is enabled.
- *
+ *
* To enable bulk tracking, call enableBulkTracking().
*
- * @throws Exception
+ * @throws Exception
* @return string Response
*/
public function doBulkTrack()
{
- if (empty($this->token_auth))
- {
- throw new Exception("Token auth is required for bulk tracking.");
- }
-
- if (empty($this->storedTrackingActions))
- {
- throw new Exception("Error: you must call the function doTrackPageView or doTrackGoal from this class, before calling this method doBulkTrack()");
- }
-
- $data = array('requests' => $this->storedTrackingActions, 'token_auth' => $this->token_auth);
-
- $postData = json_encode($data);
- $response = $this->sendRequest($this->getBaseUrl(), 'POST', $postData, $force = true);
-
- $this->storedTrackingActions = array();
-
- return $response;
+ if (empty($this->token_auth)) {
+ throw new Exception("Token auth is required for bulk tracking.");
+ }
+
+ if (empty($this->storedTrackingActions)) {
+ throw new Exception("Error: you must call the function doTrackPageView or doTrackGoal from this class, before calling this method doBulkTrack()");
+ }
+
+ $data = array('requests' => $this->storedTrackingActions, 'token_auth' => $this->token_auth);
+
+ $postData = json_encode($data);
+ $response = $this->sendRequest($this->getBaseUrl(), 'POST', $postData, $force = true);
+
+ $this->storedTrackingActions = array();
+
+ return $response;
}
-
- /**
- * Tracks an Ecommerce order.
- *
- * If the Ecommerce order contains items (products), you must call first the addEcommerceItem() for each item in the order.
- * All revenues (grandTotal, subTotal, tax, shipping, discount) will be individually summed and reported in Piwik reports.
- * Only the parameters $orderId and $grandTotal are required.
- *
- * @param string|int $orderId (required) Unique Order ID.
- * This will be used to count this order only once in the event the order page is reloaded several times.
- * orderId must be unique for each transaction, even on different days, or the transaction will not be recorded by Piwik.
- * @param float $grandTotal (required) Grand Total revenue of the transaction (including tax, shipping, etc.)
- * @param float $subTotal (optional) Sub total amount, typically the sum of items prices for all items in this order (before Tax and Shipping costs are applied)
- * @param float $tax (optional) Tax amount for this order
- * @param float $shipping (optional) Shipping amount for this order
- * @param float $discount (optional) Discounted amount in this order
- * @return mixed Response or true if using bulk request
+
+ /**
+ * Tracks an Ecommerce order.
+ *
+ * If the Ecommerce order contains items (products), you must call first the addEcommerceItem() for each item in the order.
+ * All revenues (grandTotal, subTotal, tax, shipping, discount) will be individually summed and reported in Piwik reports.
+ * Only the parameters $orderId and $grandTotal are required.
+ *
+ * @param string|int $orderId (required) Unique Order ID.
+ * This will be used to count this order only once in the event the order page is reloaded several times.
+ * orderId must be unique for each transaction, even on different days, or the transaction will not be recorded by Piwik.
+ * @param float $grandTotal (required) Grand Total revenue of the transaction (including tax, shipping, etc.)
+ * @param float $subTotal (optional) Sub total amount, typically the sum of items prices for all items in this order (before Tax and Shipping costs are applied)
+ * @param float $tax (optional) Tax amount for this order
+ * @param float $shipping (optional) Shipping amount for this order
+ * @param float $discount (optional) Discounted amount in this order
+ * @return mixed Response or true if using bulk request
*/
public function doTrackEcommerceOrder($orderId, $grandTotal, $subTotal = 0.0, $tax = 0.0, $shipping = 0.0, $discount = 0.0)
{
- $url = $this->getUrlTrackEcommerceOrder($orderId, $grandTotal, $subTotal, $tax, $shipping, $discount);
- return $this->sendRequest($url);
+ $url = $this->getUrlTrackEcommerceOrder($orderId, $grandTotal, $subTotal, $tax, $shipping, $discount);
+ return $this->sendRequest($url);
}
-
+
/**
* Sets the current page view as an item (product) page view, or an Ecommerce Category page view.
- *
- * This must be called before doTrackPageView() on this product/category page.
+ *
+ * This must be called before doTrackPageView() on this product/category page.
* It will set 3 custom variables of scope "page" with the SKU, Name and Category for this page view.
* Note: Custom Variables of scope "page" slots 3, 4 and 5 will be used.
- *
+ *
* On a category page, you may set the parameter $category only and set the other parameters to false.
- *
- * Tracking Product/Category page views will allow Piwik to report on Product & Categories
+ *
+ * Tracking Product/Category page views will allow Piwik to report on Product & Categories
* conversion rates (Conversion rate = Ecommerce orders containing this product or category / Visits to the product or category)
- *
+ *
* @param string $sku Product SKU being viewed
* @param string $name Product Name being viewed
- * @param string|array $category Category being viewed. On a Product page, this is the product's category.
- * You can also specify an array of up to 5 categories for a given page view.
+ * @param string|array $category Category being viewed. On a Product page, this is the product's category.
+ * You can also specify an array of up to 5 categories for a given page view.
* @param float $price Specify the price at which the item was displayed
*/
public function setEcommerceView($sku = '', $name = '', $category = '', $price = 0.0)
{
- if(!empty($category)) {
- if(is_array($category)) {
- $category = json_encode($category);
- }
- } else {
- $category = "";
- }
- $this->pageCustomVar[5] = array('_pkc', $category);
-
- if(!empty($price)) {
- $this->pageCustomVar[2] = array('_pkp', (float)$price);
- }
-
- // On a category page, do not record "Product name not defined"
- if(empty($sku) && empty($name))
- {
- return;
- }
- if(!empty($sku)) {
- $this->pageCustomVar[3] = array('_pks', $sku);
- }
- if(empty($name)) {
- $name = "";
- }
- $this->pageCustomVar[4] = array('_pkn', $name);
+ if (!empty($category)) {
+ if (is_array($category)) {
+ $category = json_encode($category);
+ }
+ } else {
+ $category = "";
+ }
+ $this->pageCustomVar[5] = array('_pkc', $category);
+
+ if (!empty($price)) {
+ $this->pageCustomVar[2] = array('_pkp', (float)$price);
+ }
+
+ // On a category page, do not record "Product name not defined"
+ if (empty($sku) && empty($name)) {
+ return;
+ }
+ if (!empty($sku)) {
+ $this->pageCustomVar[3] = array('_pks', $sku);
+ }
+ if (empty($name)) {
+ $name = "";
+ }
+ $this->pageCustomVar[4] = array('_pkn', $name);
}
-
+
/**
* Returns URL used to track Ecommerce Cart updates
- * Calling this function will reinitializes the property ecommerceItems to empty array
- * so items will have to be added again via addEcommerceItem()
+ * Calling this function will reinitializes the property ecommerceItems to empty array
+ * so items will have to be added again via addEcommerceItem()
* @ignore
*/
public function getUrlTrackEcommerceCartUpdate($grandTotal)
{
- $url = $this->getUrlTrackEcommerce($grandTotal);
- return $url;
+ $url = $this->getUrlTrackEcommerce($grandTotal);
+ return $url;
}
-
+
/**
* Returns URL used to track Ecommerce Orders
- * Calling this function will reinitializes the property ecommerceItems to empty array
- * so items will have to be added again via addEcommerceItem()
+ * Calling this function will reinitializes the property ecommerceItems to empty array
+ * so items will have to be added again via addEcommerceItem()
* @ignore
*/
public function getUrlTrackEcommerceOrder($orderId, $grandTotal, $subTotal = 0.0, $tax = 0.0, $shipping = 0.0, $discount = 0.0)
{
- if(empty($orderId))
- {
- throw new Exception("You must specifiy an orderId for the Ecommerce order");
- }
- $url = $this->getUrlTrackEcommerce($grandTotal, $subTotal, $tax, $shipping, $discount);
- $url .= '&ec_id=' . urlencode($orderId);
- $this->ecommerceLastOrderTimestamp = $this->getTimestamp();
- return $url;
+ if (empty($orderId)) {
+ throw new Exception("You must specifiy an orderId for the Ecommerce order");
+ }
+ $url = $this->getUrlTrackEcommerce($grandTotal, $subTotal, $tax, $shipping, $discount);
+ $url .= '&ec_id=' . urlencode($orderId);
+ $this->ecommerceLastOrderTimestamp = $this->getTimestamp();
+ return $url;
}
-
+
/**
* Returns URL used to track Ecommerce orders
- * Calling this function will reinitializes the property ecommerceItems to empty array
- * so items will have to be added again via addEcommerceItem()
+ * Calling this function will reinitializes the property ecommerceItems to empty array
+ * so items will have to be added again via addEcommerceItem()
* @ignore
*/
protected function getUrlTrackEcommerce($grandTotal, $subTotal = 0.0, $tax = 0.0, $shipping = 0.0, $discount = 0.0)
{
- if(!is_numeric($grandTotal))
- {
- throw new Exception("You must specifiy a grandTotal for the Ecommerce order (or Cart update)");
- }
-
- $url = $this->getRequest( $this->idSite );
- $url .= '&idgoal=0';
- if(!empty($grandTotal))
- {
- $url .= '&revenue='.$grandTotal;
- }
- if(!empty($subTotal))
- {
- $url .= '&ec_st='.$subTotal;
- }
- if(!empty($tax))
- {
- $url .= '&ec_tx='.$tax;
- }
- if(!empty($shipping))
- {
- $url .= '&ec_sh='.$shipping;
- }
- if(!empty($discount))
- {
- $url .= '&ec_dt='.$discount;
- }
- if(!empty($this->ecommerceItems))
- {
- // Removing the SKU index in the array before JSON encoding
- $items = array();
- foreach($this->ecommerceItems as $item)
- {
- $items[] = $item;
- }
- $url .= '&ec_items='. urlencode(json_encode($items));
- }
- $this->ecommerceItems = array();
- return $url;
+ if (!is_numeric($grandTotal)) {
+ throw new Exception("You must specifiy a grandTotal for the Ecommerce order (or Cart update)");
+ }
+
+ $url = $this->getRequest($this->idSite);
+ $url .= '&idgoal=0';
+ if (!empty($grandTotal)) {
+ $url .= '&revenue=' . $grandTotal;
+ }
+ if (!empty($subTotal)) {
+ $url .= '&ec_st=' . $subTotal;
+ }
+ if (!empty($tax)) {
+ $url .= '&ec_tx=' . $tax;
+ }
+ if (!empty($shipping)) {
+ $url .= '&ec_sh=' . $shipping;
+ }
+ if (!empty($discount)) {
+ $url .= '&ec_dt=' . $discount;
+ }
+ if (!empty($this->ecommerceItems)) {
+ // Removing the SKU index in the array before JSON encoding
+ $items = array();
+ foreach ($this->ecommerceItems as $item) {
+ $items[] = $item;
+ }
+ $url .= '&ec_items=' . urlencode(json_encode($items));
+ }
+ $this->ecommerceItems = array();
+ return $url;
}
-
+
/**
- * Builds URL to track a page view.
- *
+ * Builds URL to track a page view.
+ *
* @see doTrackPageView()
* @param string $documentTitle Page view name as it will appear in Piwik reports
* @return string URL to piwik.php with all parameters set to track the pageview
*/
- public function getUrlTrackPageView( $documentTitle = '' )
+ public function getUrlTrackPageView($documentTitle = '')
{
- $url = $this->getRequest( $this->idSite );
- if(strlen($documentTitle) > 0) {
- $url .= '&action_name=' . urlencode($documentTitle);
- }
- return $url;
+ $url = $this->getRequest($this->idSite);
+ if (strlen($documentTitle) > 0) {
+ $url .= '&action_name=' . urlencode($documentTitle);
+ }
+ return $url;
}
- /**
- * Builds URL to track a site search.
- *
- * @see doTrackSiteSearch()
- * @param string $keyword
- * @param string $category
- * @param int $countResults
- * @return string
- */
- public function getUrlTrackSiteSearch($keyword, $category, $countResults)
- {
- $url = $this->getRequest( $this->idSite );
- $url .= '&search=' . urlencode($keyword);
- if(strlen($category) > 0) {
- $url .= '&search_cat=' . urlencode($category);
- }
- if(!empty($countResults) || $countResults === 0) {
- $url .= '&search_count=' . (int)$countResults;
- }
- return $url;
- }
-
- /**
- * Builds URL to track a goal with idGoal and revenue.
- *
+ /**
+ * Builds URL to track a site search.
+ *
+ * @see doTrackSiteSearch()
+ * @param string $keyword
+ * @param string $category
+ * @param int $countResults
+ * @return string
+ */
+ public function getUrlTrackSiteSearch($keyword, $category, $countResults)
+ {
+ $url = $this->getRequest($this->idSite);
+ $url .= '&search=' . urlencode($keyword);
+ if (strlen($category) > 0) {
+ $url .= '&search_cat=' . urlencode($category);
+ }
+ if (!empty($countResults) || $countResults === 0) {
+ $url .= '&search_count=' . (int)$countResults;
+ }
+ return $url;
+ }
+
+ /**
+ * Builds URL to track a goal with idGoal and revenue.
+ *
* @see doTrackGoal()
* @param int $idGoal Id Goal to record a conversion
* @param float $revenue Revenue for this conversion
@@ -688,17 +661,17 @@ class PiwikTracker
*/
public function getUrlTrackGoal($idGoal, $revenue = 0.0)
{
- $url = $this->getRequest( $this->idSite );
- $url .= '&idgoal=' . $idGoal;
- if(!empty($revenue)) {
- $url .= '&revenue=' . $revenue;
- }
- return $url;
+ $url = $this->getRequest($this->idSite);
+ $url .= '&idgoal=' . $idGoal;
+ if (!empty($revenue)) {
+ $url .= '&revenue=' . $revenue;
+ }
+ return $url;
}
-
+
/**
- * Builds URL to track a new action.
- *
+ * Builds URL to track a new action.
+ *
* @see doTrackAction()
* @param string $actionUrl URL of the download or outlink
* @param string $actionType Type of the action: 'download' or 'link'
@@ -706,140 +679,137 @@ class PiwikTracker
*/
public function getUrlTrackAction($actionUrl, $actionType)
{
- $url = $this->getRequest( $this->idSite );
- $url .= '&'.$actionType.'=' . $actionUrl;
- return $url;
+ $url = $this->getRequest($this->idSite);
+ $url .= '&' . $actionType . '=' . $actionUrl;
+ return $url;
}
/**
- * Overrides server date and time for the tracking requests.
- * By default Piwik will track requests for the "current datetime" but this function allows you
+ * Overrides server date and time for the tracking requests.
+ * By default Piwik will track requests for the "current datetime" but this function allows you
* to track visits in the past. All times are in UTC.
- *
+ *
* Allowed only for Super User, must be used along with setTokenAuth()
* @see setTokenAuth()
* @param string $dateTime Date with the format 'Y-m-d H:i:s', or a UNIX timestamp
*/
public function setForceVisitDateTime($dateTime)
{
- $this->forcedDatetime = $dateTime;
+ $this->forcedDatetime = $dateTime;
}
-
+
/**
* Overrides IP address
- *
+ *
* Allowed only for Super User, must be used along with setTokenAuth()
* @see setTokenAuth()
* @param string $ip IP string, eg. 130.54.2.1
*/
public function setIp($ip)
{
- $this->ip = $ip;
+ $this->ip = $ip;
}
-
+
/**
* Forces the requests to be recorded for the specified Visitor ID
* rather than using the heuristics based on IP and other attributes.
- *
+ *
* This is typically used with the Javascript getVisitorId() function.
- *
+ *
* Allowed only for Admin/Super User, must be used along with setTokenAuth().
* @see setTokenAuth()
* @param string $visitorId 16 hexadecimal characters visitor ID, eg. "33c31e01394bdc63"
- * @throws Exception
+ * @throws Exception
*/
public function setVisitorId($visitorId)
{
$hexChars = '01234567890abcdefABCDEF';
- if(strlen($visitorId) != self::LENGTH_VISITOR_ID
- || strspn($visitorId, $hexChars) !== strlen($visitorId))
- {
- throw new Exception("setVisitorId() expects a "
- .self::LENGTH_VISITOR_ID
- ." characters hexadecimal string (containing only the following: "
- .$hexChars
- .")");
- }
- $this->forcedVisitorId = $visitorId;
+ if (strlen($visitorId) != self::LENGTH_VISITOR_ID
+ || strspn($visitorId, $hexChars) !== strlen($visitorId)
+ ) {
+ throw new Exception("setVisitorId() expects a "
+ . self::LENGTH_VISITOR_ID
+ . " characters hexadecimal string (containing only the following: "
+ . $hexChars
+ . ")");
+ }
+ $this->forcedVisitorId = $visitorId;
}
-
+
/**
- * If the user initiating the request has the Piwik first party cookie,
+ * If the user initiating the request has the Piwik first party cookie,
* this function will try and return the ID parsed from this first party cookie (found in $_COOKIE).
- *
+ *
* If you call this function from a server, where the call is triggered by a cron or script
- * not initiated by the actual visitor being tracked, then it will return
+ * not initiated by the actual visitor being tracked, then it will return
* the random Visitor ID that was assigned to this visit object.
- *
+ *
* This can be used if you wish to record more visits, actions or goals for this visitor ID later on.
- *
+ *
* @return string 16 hex chars visitor ID string
*/
public function getVisitorId()
{
- if(!empty($this->forcedVisitorId))
- {
- return $this->forcedVisitorId;
- }
-
- $idCookieName = 'id.'.$this->idSite.'.';
- $idCookie = $this->getCookieMatchingName($idCookieName);
- if($idCookie !== false)
- {
- $visitorId = substr($idCookie, 0, strpos($idCookie, '.'));
- if(strlen($visitorId) == self::LENGTH_VISITOR_ID)
- {
- return $visitorId;
- }
- }
- return $this->visitorId;
+ if (!empty($this->forcedVisitorId)) {
+ return $this->forcedVisitorId;
+ }
+
+ $idCookieName = 'id.' . $this->idSite . '.';
+ $idCookie = $this->getCookieMatchingName($idCookieName);
+ if ($idCookie !== false) {
+ $visitorId = substr($idCookie, 0, strpos($idCookie, '.'));
+ if (strlen($visitorId) == self::LENGTH_VISITOR_ID) {
+ return $visitorId;
+ }
+ }
+ return $this->visitorId;
}
/**
* Returns the currently assigned Attribution Information stored in a first party cookie.
- *
+ *
* This function will only work if the user is initiating the current request, and his cookies
* can be read by PHP from the $_COOKIE array.
- *
+ *
* @return string JSON Encoded string containing the Referer information for Goal conversion attribution.
* Will return false if the cookie could not be found
* @see Piwik.js getAttributionInfo()
*/
public function getAttributionInfo()
{
- $attributionCookieName = 'ref.'.$this->idSite.'.';
- return $this->getCookieMatchingName($attributionCookieName);
+ $attributionCookieName = 'ref.' . $this->idSite . '.';
+ return $this->getCookieMatchingName($attributionCookieName);
+ }
+
+ /**
+ * Some Tracking API functionnality requires express authentication, using either the
+ * Super User token_auth, or a user with 'admin' access to the website.
+ *
+ * The following features require access:
+ * - force the visitor IP
+ * - force the date & time of the tracking requests rather than track for the current datetime
+ * - force Piwik to track the requests to a specific VisitorId rather than use the standard visitor matching heuristic
+ *
+ * @param string $token_auth token_auth 32 chars token_auth string
+ */
+ public function setTokenAuth($token_auth)
+ {
+ $this->token_auth = $token_auth;
}
-
- /**
- * Some Tracking API functionnality requires express authentication, using either the
- * Super User token_auth, or a user with 'admin' access to the website.
- *
- * The following features require access:
- * - force the visitor IP
- * - force the date & time of the tracking requests rather than track for the current datetime
- * - force Piwik to track the requests to a specific VisitorId rather than use the standard visitor matching heuristic
- *
- * @param string $token_auth token_auth 32 chars token_auth string
- */
- public function setTokenAuth($token_auth)
- {
- $this->token_auth = $token_auth;
- }
/**
* Sets local visitor time
- *
+ *
* @param string $time HH:MM:SS format
*/
public function setLocalTime($time)
{
- list($hour, $minute, $second) = explode(':', $time);
- $this->localHour = (int)$hour;
- $this->localMinute = (int)$minute;
- $this->localSecond = (int)$second;
+ list($hour, $minute, $second) = explode(':', $time);
+ $this->localHour = (int)$hour;
+ $this->localMinute = (int)$minute;
+ $this->localSecond = (int)$second;
}
-
+
/**
* Sets user resolution width and height.
*
@@ -848,32 +818,32 @@ class PiwikTracker
*/
public function setResolution($width, $height)
{
- $this->width = $width;
- $this->height = $height;
+ $this->width = $width;
+ $this->height = $height;
}
-
+
/**
- * Sets if the browser supports cookies
+ * Sets if the browser supports cookies
* This is reported in "List of plugins" report in Piwik.
*
* @param bool $bool
*/
- public function setBrowserHasCookies( $bool )
+ public function setBrowserHasCookies($bool)
{
- $this->hasCookies = $bool ;
+ $this->hasCookies = $bool;
}
-
+
/**
- * Will append a custom string at the end of the Tracking request.
+ * Will append a custom string at the end of the Tracking request.
* @param string $string
*/
- public function setDebugStringAppend( $string )
+ public function setDebugStringAppend($string)
{
- $this->DEBUG_APPEND_URL = $string;
+ $this->DEBUG_APPEND_URL = $string;
}
-
+
/**
- * Sets visitor browser supported plugins
+ * Sets visitor browser supported plugins
*
* @param bool $flash
* @param bool $java
@@ -887,374 +857,352 @@ class PiwikTracker
*/
public function setPlugins($flash = false, $java = false, $director = false, $quickTime = false, $realPlayer = false, $pdf = false, $windowsMedia = false, $gears = false, $silverlight = false)
{
- $this->plugins =
- '&fla='.(int)$flash.
- '&java='.(int)$java.
- '&dir='.(int)$director.
- '&qt='.(int)$quickTime.
- '&realp='.(int)$realPlayer.
- '&pdf='.(int)$pdf.
- '&wma='.(int)$windowsMedia.
- '&gears='.(int)$gears.
- '&ag='.(int)$silverlight
- ;
+ $this->plugins =
+ '&fla=' . (int)$flash .
+ '&java=' . (int)$java .
+ '&dir=' . (int)$director .
+ '&qt=' . (int)$quickTime .
+ '&realp=' . (int)$realPlayer .
+ '&pdf=' . (int)$pdf .
+ '&wma=' . (int)$windowsMedia .
+ '&gears=' . (int)$gears .
+ '&ag=' . (int)$silverlight;
}
- /**
- * By default, PiwikTracker will read third party cookies
- * from the response and sets them in the next request.
- * This can be disabled by calling this function.
- */
+ /**
+ * By default, PiwikTracker will read third party cookies
+ * from the response and sets them in the next request.
+ * This can be disabled by calling this function.
+ */
public function disableCookieSupport()
{
- $this->cookieSupport = false;
+ $this->cookieSupport = false;
}
-
+
/**
* Returns the maximum number of seconds the tracker will spend waiting for a response
* from Piwik. Defaults to 600 seconds.
*/
public function getRequestTimeout()
{
- return $this->requestTimeout;
+ return $this->requestTimeout;
}
-
- /**
- * Sets the maximum number of seconds that the tracker will spend waiting for a response
- * from Piwik.
- *
- * @param int $timeout
- * @throws Exception
- */
- public function setRequestTimeout( $timeout )
+
+ /**
+ * Sets the maximum number of seconds that the tracker will spend waiting for a response
+ * from Piwik.
+ *
+ * @param int $timeout
+ * @throws Exception
+ */
+ public function setRequestTimeout($timeout)
{
- if (!is_int($timeout) || $timeout < 0)
- {
- throw new Exception("Invalid value supplied for request timeout: $timeout");
- }
-
- $this->requestTimeout = $timeout;
+ if (!is_int($timeout) || $timeout < 0) {
+ throw new Exception("Invalid value supplied for request timeout: $timeout");
+ }
+
+ $this->requestTimeout = $timeout;
}
-
+
/**
* @ignore
*/
- protected function sendRequest( $url, $method = 'GET', $data = null, $force = false )
+ protected function sendRequest($url, $method = 'GET', $data = null, $force = false)
{
- // if doing a bulk request, store the url
- if ($this->doBulkRequests && !$force)
- {
- $this->storedTrackingActions[]
- = $url
- . (!empty($this->userAgent) ? ('&ua='.urlencode($this->userAgent)) : '')
- . (!empty($this->acceptLanguage) ? ('&lang='.urlencode($this->acceptLanguage)) : '')
- ;
- return true;
- }
-
- $response = '';
-
- if(!$this->cookieSupport)
- {
- $this->requestCookie = '';
- }
- if(function_exists('curl_init'))
- {
- $options = array(
- CURLOPT_URL => $url,
- CURLOPT_USERAGENT => $this->userAgent,
- CURLOPT_HEADER => true,
- CURLOPT_TIMEOUT => $this->requestTimeout,
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_HTTPHEADER => array(
- 'Accept-Language: ' . $this->acceptLanguage,
- 'Cookie: '. $this->requestCookie,
- ));
-
- switch ($method)
- {
- case 'POST':
- $options[CURLOPT_POST] = TRUE;
- break;
- default:
- break;
- }
-
- // only supports JSON data
- if (!empty($data))
- {
- $options[CURLOPT_HTTPHEADER][] = 'Content-Type: application/json';
- $options[CURLOPT_HTTPHEADER][] = 'Expect:';
- $options[CURLOPT_POSTFIELDS] = $data;
- }
-
- $ch = curl_init();
- curl_setopt_array($ch, $options);
- ob_start();
- $response = @curl_exec($ch);
- ob_end_clean();
- $header = $content = '';
- if(!empty($response))
- {
- list($header,$content) = explode("\r\n\r\n", $response, $limitCount = 2);
- }
- }
- else if(function_exists('stream_context_create'))
- {
- $stream_options = array(
- 'http' => array(
- 'method' => $method,
- 'user_agent' => $this->userAgent,
- 'header' => "Accept-Language: " . $this->acceptLanguage . "\r\n" .
- "Cookie: ".$this->requestCookie. "\r\n" ,
- 'timeout' => $this->requestTimeout, // PHP 5.2.1
- )
- );
-
- // only supports JSON data
- if (!empty($data))
- {
- $stream_options['http']['header'] .= "Content-Type: application/json \r\n";
- $stream_options['http']['content'] = $data;
- }
-
- $ctx = stream_context_create($stream_options);
- $response = file_get_contents($url, 0, $ctx);
- $header = implode("\r\n", $http_response_header);
- $content = $response;
- }
- // The cookie in the response will be set in the next request
- preg_match_all('/^Set-Cookie: (.*?);/m', $header, $cookie);
- if(!empty($cookie[1]))
- {
- // in case several cookies returned, we keep only the latest one (ie. XDEBUG puts its cookie first in the list)
- if(is_array($cookie[1]))
- {
- $cookie = end($cookie[1]);
- }
- else
- {
- $cookie = $cookie[1];
- }
- // XDEBUG is a PHP Debugger
- if(strpos($cookie, 'XDEBUG') === false)
- {
- $this->requestCookie = $cookie;
- }
- }
-
- return $content;
+ // if doing a bulk request, store the url
+ if ($this->doBulkRequests && !$force) {
+ $this->storedTrackingActions[]
+ = $url
+ . (!empty($this->userAgent) ? ('&ua=' . urlencode($this->userAgent)) : '')
+ . (!empty($this->acceptLanguage) ? ('&lang=' . urlencode($this->acceptLanguage)) : '');
+ return true;
+ }
+
+ $response = '';
+
+ if (!$this->cookieSupport) {
+ $this->requestCookie = '';
+ }
+ if (function_exists('curl_init')) {
+ $options = array(
+ CURLOPT_URL => $url,
+ CURLOPT_USERAGENT => $this->userAgent,
+ CURLOPT_HEADER => true,
+ CURLOPT_TIMEOUT => $this->requestTimeout,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_HTTPHEADER => array(
+ 'Accept-Language: ' . $this->acceptLanguage,
+ 'Cookie: ' . $this->requestCookie,
+ ));
+
+ switch ($method) {
+ case 'POST':
+ $options[CURLOPT_POST] = TRUE;
+ break;
+ default:
+ break;
+ }
+
+ // only supports JSON data
+ if (!empty($data)) {
+ $options[CURLOPT_HTTPHEADER][] = 'Content-Type: application/json';
+ $options[CURLOPT_HTTPHEADER][] = 'Expect:';
+ $options[CURLOPT_POSTFIELDS] = $data;
+ }
+
+ $ch = curl_init();
+ curl_setopt_array($ch, $options);
+ ob_start();
+ $response = @curl_exec($ch);
+ ob_end_clean();
+ $header = $content = '';
+ if (!empty($response)) {
+ list($header, $content) = explode("\r\n\r\n", $response, $limitCount = 2);
+ }
+ } else if (function_exists('stream_context_create')) {
+ $stream_options = array(
+ 'http' => array(
+ 'method' => $method,
+ 'user_agent' => $this->userAgent,
+ 'header' => "Accept-Language: " . $this->acceptLanguage . "\r\n" .
+ "Cookie: " . $this->requestCookie . "\r\n",
+ 'timeout' => $this->requestTimeout, // PHP 5.2.1
+ )
+ );
+
+ // only supports JSON data
+ if (!empty($data)) {
+ $stream_options['http']['header'] .= "Content-Type: application/json \r\n";
+ $stream_options['http']['content'] = $data;
+ }
+
+ $ctx = stream_context_create($stream_options);
+ $response = file_get_contents($url, 0, $ctx);
+ $header = implode("\r\n", $http_response_header);
+ $content = $response;
+ }
+ // The cookie in the response will be set in the next request
+ preg_match_all('/^Set-Cookie: (.*?);/m', $header, $cookie);
+ if (!empty($cookie[1])) {
+ // in case several cookies returned, we keep only the latest one (ie. XDEBUG puts its cookie first in the list)
+ if (is_array($cookie[1])) {
+ $cookie = end($cookie[1]);
+ } else {
+ $cookie = $cookie[1];
+ }
+ // XDEBUG is a PHP Debugger
+ if (strpos($cookie, 'XDEBUG') === false) {
+ $this->requestCookie = $cookie;
+ }
+ }
+
+ return $content;
}
-
+
/**
* Returns current timestamp, or forced timestamp/datetime if it was set
* @return string|int
*/
protected function getTimestamp()
{
- return !empty($this->forcedDatetime)
- ? strtotime($this->forcedDatetime)
- : time();
+ return !empty($this->forcedDatetime)
+ ? strtotime($this->forcedDatetime)
+ : time();
}
-
+
/**
* Returns the base URL for the piwik server.
*/
protected function getBaseUrl()
{
- if(empty(self::$URL))
- {
- throw new Exception('You must first set the Piwik Tracker URL by calling PiwikTracker::$URL = \'http://your-website.org/piwik/\';');
- }
- if(strpos(self::$URL, '/piwik.php') === false
- && strpos(self::$URL, '/proxy-piwik.php') === false)
- {
- self::$URL .= '/piwik.php';
- }
- return self::$URL;
+ if (empty(self::$URL)) {
+ throw new Exception('You must first set the Piwik Tracker URL by calling PiwikTracker::$URL = \'http://your-website.org/piwik/\';');
+ }
+ if (strpos(self::$URL, '/piwik.php') === false
+ && strpos(self::$URL, '/proxy-piwik.php') === false
+ ) {
+ self::$URL .= '/piwik.php';
+ }
+ return self::$URL;
}
-
+
/**
* @ignore
*/
- protected function getRequest( $idSite )
+ protected function getRequest($idSite)
{
- $url = $this->getBaseUrl() .
- '?idsite=' . $idSite .
- '&rec=1' .
- '&apiv=' . self::VERSION .
- '&r=' . substr(strval(mt_rand()), 2, 6) .
-
- // XDEBUG_SESSIONS_START and KEY are related to the PHP Debugger, this can be ignored in other languages
- (!empty($_GET['XDEBUG_SESSION_START']) ? '&XDEBUG_SESSION_START=' . @urlencode($_GET['XDEBUG_SESSION_START']) : '') .
- (!empty($_GET['KEY']) ? '&KEY=' . @urlencode($_GET['KEY']) : '') .
-
- // Only allowed for Super User, token_auth required,
- (!empty($this->ip) ? '&cip=' . $this->ip : '') .
- (!empty($this->forcedVisitorId) ? '&cid=' . $this->forcedVisitorId : '&_id=' . $this->visitorId) .
- (!empty($this->forcedDatetime) ? '&cdt=' . urlencode($this->forcedDatetime) : '') .
- ((!empty($this->token_auth) && !$this->doBulkRequests) ? '&token_auth=' . urlencode($this->token_auth) : '') .
-
- // These parameters are set by the JS, but optional when using API
- (!empty($this->plugins) ? $this->plugins : '') .
- (($this->localHour !== false && $this->localMinute !== false && $this->localSecond !== false) ? '&h=' . $this->localHour . '&m=' . $this->localMinute . '&s=' . $this->localSecond : '' ).
- (!empty($this->width) && !empty($this->height) ? '&res=' . $this->width . 'x' . $this->height : '') .
- (!empty($this->hasCookies) ? '&cookie=' . $this->hasCookies : '') .
- (!empty($this->ecommerceLastOrderTimestamp) ? '&_ects=' . urlencode($this->ecommerceLastOrderTimestamp) : '') .
-
- // Various important attributes
- (!empty($this->customData) ? '&data=' . $this->customData : '') .
- (!empty($this->visitorCustomVar) ? '&_cvar=' . urlencode(json_encode($this->visitorCustomVar)) : '') .
- (!empty($this->pageCustomVar) ? '&cvar=' . urlencode(json_encode($this->pageCustomVar)) : '') .
- (!empty($this->generationTime) ? '&generation_time_ms=' . ((int)$this->generationTime) : '') .
-
- // URL parameters
- '&url=' . urlencode($this->pageUrl) .
- '&urlref=' . urlencode($this->urlReferrer) .
- ((!empty($this->pageCharset) && $this->pageCharset != self::DEFAULT_CHARSET_PARAMETER_VALUES) ? '&cs=' . $this->pageCharset : '') .
-
- // Attribution information, so that Goal conversions are attributed to the right referrer or campaign
- // Campaign name
- (!empty($this->attributionInfo[0]) ? '&_rcn=' . urlencode($this->attributionInfo[0]) : '') .
- // Campaign keyword
- (!empty($this->attributionInfo[1]) ? '&_rck=' . urlencode($this->attributionInfo[1]) : '') .
- // Timestamp at which the referrer was set
- (!empty($this->attributionInfo[2]) ? '&_refts=' . $this->attributionInfo[2] : '') .
- // Referrer URL
- (!empty($this->attributionInfo[3]) ? '&_ref=' . urlencode($this->attributionInfo[3]) : '') .
-
- // custom location info
- (!empty($this->country) ? '&country='.urlencode($this->country) : '') .
- (!empty($this->region) ? '&region='.urlencode($this->region) : '') .
- (!empty($this->city) ? '&city='.urlencode($this->city) : '') .
- (!empty($this->lat) ? '&lat='.urlencode($this->lat) : '') .
- (!empty($this->long) ? '&long='.urlencode($this->long) : '') .
-
- // DEBUG
- $this->DEBUG_APPEND_URL
- ;
- // Reset page level custom variables after this page view
- $this->pageCustomVar = false;
-
- return $url;
+ $url = $this->getBaseUrl() .
+ '?idsite=' . $idSite .
+ '&rec=1' .
+ '&apiv=' . self::VERSION .
+ '&r=' . substr(strval(mt_rand()), 2, 6) .
+
+ // XDEBUG_SESSIONS_START and KEY are related to the PHP Debugger, this can be ignored in other languages
+ (!empty($_GET['XDEBUG_SESSION_START']) ? '&XDEBUG_SESSION_START=' . @urlencode($_GET['XDEBUG_SESSION_START']) : '') .
+ (!empty($_GET['KEY']) ? '&KEY=' . @urlencode($_GET['KEY']) : '') .
+
+ // Only allowed for Super User, token_auth required,
+ (!empty($this->ip) ? '&cip=' . $this->ip : '') .
+ (!empty($this->forcedVisitorId) ? '&cid=' . $this->forcedVisitorId : '&_id=' . $this->visitorId) .
+ (!empty($this->forcedDatetime) ? '&cdt=' . urlencode($this->forcedDatetime) : '') .
+ ((!empty($this->token_auth) && !$this->doBulkRequests) ? '&token_auth=' . urlencode($this->token_auth) : '') .
+
+ // These parameters are set by the JS, but optional when using API
+ (!empty($this->plugins) ? $this->plugins : '') .
+ (($this->localHour !== false && $this->localMinute !== false && $this->localSecond !== false) ? '&h=' . $this->localHour . '&m=' . $this->localMinute . '&s=' . $this->localSecond : '') .
+ (!empty($this->width) && !empty($this->height) ? '&res=' . $this->width . 'x' . $this->height : '') .
+ (!empty($this->hasCookies) ? '&cookie=' . $this->hasCookies : '') .
+ (!empty($this->ecommerceLastOrderTimestamp) ? '&_ects=' . urlencode($this->ecommerceLastOrderTimestamp) : '') .
+
+ // Various important attributes
+ (!empty($this->customData) ? '&data=' . $this->customData : '') .
+ (!empty($this->visitorCustomVar) ? '&_cvar=' . urlencode(json_encode($this->visitorCustomVar)) : '') .
+ (!empty($this->pageCustomVar) ? '&cvar=' . urlencode(json_encode($this->pageCustomVar)) : '') .
+ (!empty($this->generationTime) ? '&generation_time_ms=' . ((int)$this->generationTime) : '') .
+
+ // URL parameters
+ '&url=' . urlencode($this->pageUrl) .
+ '&urlref=' . urlencode($this->urlReferrer) .
+ ((!empty($this->pageCharset) && $this->pageCharset != self::DEFAULT_CHARSET_PARAMETER_VALUES) ? '&cs=' . $this->pageCharset : '') .
+
+ // Attribution information, so that Goal conversions are attributed to the right referrer or campaign
+ // Campaign name
+ (!empty($this->attributionInfo[0]) ? '&_rcn=' . urlencode($this->attributionInfo[0]) : '') .
+ // Campaign keyword
+ (!empty($this->attributionInfo[1]) ? '&_rck=' . urlencode($this->attributionInfo[1]) : '') .
+ // Timestamp at which the referrer was set
+ (!empty($this->attributionInfo[2]) ? '&_refts=' . $this->attributionInfo[2] : '') .
+ // Referrer URL
+ (!empty($this->attributionInfo[3]) ? '&_ref=' . urlencode($this->attributionInfo[3]) : '') .
+
+ // custom location info
+ (!empty($this->country) ? '&country=' . urlencode($this->country) : '') .
+ (!empty($this->region) ? '&region=' . urlencode($this->region) : '') .
+ (!empty($this->city) ? '&city=' . urlencode($this->city) : '') .
+ (!empty($this->lat) ? '&lat=' . urlencode($this->lat) : '') .
+ (!empty($this->long) ? '&long=' . urlencode($this->long) : '') .
+
+ // DEBUG
+ $this->DEBUG_APPEND_URL;
+ // Reset page level custom variables after this page view
+ $this->pageCustomVar = false;
+
+ return $url;
}
-
-
+
+
/**
* Returns a first party cookie which name contains $name
- *
+ *
* @param string $name
* @return string String value of cookie, or false if not found
* @ignore
*/
protected function getCookieMatchingName($name)
{
- // Piwik cookie names use dots separators in piwik.js,
- // but PHP Replaces . with _ http://www.php.net/manual/en/language.variables.predefined.php#72571
- $name = str_replace('.', '_', $name);
- foreach($_COOKIE as $cookieName => $cookieValue)
- {
- if(strpos($cookieName, $name) !== false)
- {
- return $cookieValue;
- }
- }
- return false;
+ // Piwik cookie names use dots separators in piwik.js,
+ // but PHP Replaces . with _ http://www.php.net/manual/en/language.variables.predefined.php#72571
+ $name = str_replace('.', '_', $name);
+ foreach ($_COOKIE as $cookieName => $cookieValue) {
+ if (strpos($cookieName, $name) !== false) {
+ return $cookieValue;
+ }
+ }
+ return false;
}
- /**
- * If current URL is "http://example.org/dir1/dir2/index.php?param1=value1&param2=value2"
- * will return "/dir1/dir2/index.php"
- *
- * @return string
+ /**
+ * If current URL is "http://example.org/dir1/dir2/index.php?param1=value1&param2=value2"
+ * will return "/dir1/dir2/index.php"
+ *
+ * @return string
* @ignore
- */
- static protected function getCurrentScriptName()
- {
- $url = '';
- if( !empty($_SERVER['PATH_INFO']) ) {
- $url = $_SERVER['PATH_INFO'];
- }
- else if( !empty($_SERVER['REQUEST_URI']) ) {
- if( ($pos = strpos($_SERVER['REQUEST_URI'], '?')) !== false ) {
- $url = substr($_SERVER['REQUEST_URI'], 0, $pos);
- } else {
- $url = $_SERVER['REQUEST_URI'];
- }
- }
- if(empty($url)) {
- $url = $_SERVER['SCRIPT_NAME'];
- }
-
- if($url[0] !== '/') {
- $url = '/' . $url;
- }
- return $url;
- }
-
- /**
- * If the current URL is 'http://example.org/dir1/dir2/index.php?param1=value1&param2=value2"
- * will return 'http'
- *
- * @return string 'https' or 'http'
+ */
+ static protected function getCurrentScriptName()
+ {
+ $url = '';
+ if (!empty($_SERVER['PATH_INFO'])) {
+ $url = $_SERVER['PATH_INFO'];
+ } else if (!empty($_SERVER['REQUEST_URI'])) {
+ if (($pos = strpos($_SERVER['REQUEST_URI'], '?')) !== false) {
+ $url = substr($_SERVER['REQUEST_URI'], 0, $pos);
+ } else {
+ $url = $_SERVER['REQUEST_URI'];
+ }
+ }
+ if (empty($url)) {
+ $url = $_SERVER['SCRIPT_NAME'];
+ }
+
+ if ($url[0] !== '/') {
+ $url = '/' . $url;
+ }
+ return $url;
+ }
+
+ /**
+ * If the current URL is 'http://example.org/dir1/dir2/index.php?param1=value1&param2=value2"
+ * will return 'http'
+ *
+ * @return string 'https' or 'http'
* @ignore
- */
- static protected function getCurrentScheme()
- {
- if(isset($_SERVER['HTTPS'])
- && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] === true))
- {
- return 'https';
- }
- return 'http';
- }
-
- /**
- * If current URL is "http://example.org/dir1/dir2/index.php?param1=value1&param2=value2"
- * will return "http://example.org"
- *
- * @return string
+ */
+ static protected function getCurrentScheme()
+ {
+ if (isset($_SERVER['HTTPS'])
+ && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] === true)
+ ) {
+ return 'https';
+ }
+ return 'http';
+ }
+
+ /**
+ * If current URL is "http://example.org/dir1/dir2/index.php?param1=value1&param2=value2"
+ * will return "http://example.org"
+ *
+ * @return string
* @ignore
- */
- static protected function getCurrentHost()
- {
- if(isset($_SERVER['HTTP_HOST'])) {
- return $_SERVER['HTTP_HOST'];
- }
- return 'unknown';
- }
-
- /**
- * If current URL is "http://example.org/dir1/dir2/index.php?param1=value1&param2=value2"
- * will return "?param1=value1&param2=value2"
- *
- * @return string
+ */
+ static protected function getCurrentHost()
+ {
+ if (isset($_SERVER['HTTP_HOST'])) {
+ return $_SERVER['HTTP_HOST'];
+ }
+ return 'unknown';
+ }
+
+ /**
+ * If current URL is "http://example.org/dir1/dir2/index.php?param1=value1&param2=value2"
+ * will return "?param1=value1&param2=value2"
+ *
+ * @return string
* @ignore
- */
- static protected function getCurrentQueryString()
- {
- $url = '';
- if(isset($_SERVER['QUERY_STRING'])
- && !empty($_SERVER['QUERY_STRING']))
- {
- $url .= '?'.$_SERVER['QUERY_STRING'];
- }
- return $url;
- }
-
- /**
- * Returns the current full URL (scheme, host, path and query string.
- *
- * @return string
+ */
+ static protected function getCurrentQueryString()
+ {
+ $url = '';
+ if (isset($_SERVER['QUERY_STRING'])
+ && !empty($_SERVER['QUERY_STRING'])
+ ) {
+ $url .= '?' . $_SERVER['QUERY_STRING'];
+ }
+ return $url;
+ }
+
+ /**
+ * Returns the current full URL (scheme, host, path and query string.
+ *
+ * @return string
* @ignore
- */
+ */
static protected function getCurrentUrl()
{
- return self::getCurrentScheme() . '://'
- . self::getCurrentHost()
- . self::getCurrentScriptName()
- . self::getCurrentQueryString();
- }
+ return self::getCurrentScheme() . '://'
+ . self::getCurrentHost()
+ . self::getCurrentScriptName()
+ . self::getCurrentQueryString();
+ }
}
/**
@@ -1264,10 +1212,10 @@ class PiwikTracker
* @param string $documentTitle
* @return string
*/
-function Piwik_getUrlTrackPageView( $idSite, $documentTitle = '' )
+function Piwik_getUrlTrackPageView($idSite, $documentTitle = '')
{
- $tracker = new PiwikTracker($idSite);
- return $tracker->getUrlTrackPageView($documentTitle);
+ $tracker = new PiwikTracker($idSite);
+ return $tracker->getUrlTrackPageView($documentTitle);
}
/**
@@ -1280,7 +1228,7 @@ function Piwik_getUrlTrackPageView( $idSite, $documentTitle = '' )
*/
function Piwik_getUrlTrackGoal($idSite, $idGoal, $revenue = 0.0)
{
- $tracker = new PiwikTracker($idSite);
- return $tracker->getUrlTrackGoal($idGoal, $revenue);
+ $tracker = new PiwikTracker($idSite);
+ return $tracker->getUrlTrackGoal($idGoal, $revenue);
}
diff --git a/libs/UserAgentParser/UserAgentParser.php b/libs/UserAgentParser/UserAgentParser.php
index 03a1f695cd..bac59cea08 100644
--- a/libs/UserAgentParser/UserAgentParser.php
+++ b/libs/UserAgentParser/UserAgentParser.php
@@ -36,581 +36,571 @@
/**
* Example usage
- *
+ *
* Browser info:
* var_dump(UserAgentParser::getBrowser($_SERVER['HTTP_USER_AGENT']));
- *
+ *
* Outputs:
* array
- * 'id' => 'FF'
+ * 'id' => 'FF'
* 'name' => 'Firefox'
* 'short_name' => 'Firefox'
* 'version' => '3.0'
* 'major_number' => '3'
* 'minor_number' => '0'
- *
+ *
* Operating System info:
* var_dump(UserAgentParser::getOperatingSystem($_SERVER['HTTP_USER_AGENT']));
*
* Outputs:
* array
* 'id' => 'WXP'
- * 'name' => 'Windows XP'
- * 'short_name' => 'Win XP'
- *
+ * 'name' => 'Windows XP'
+ * 'short_name' => 'Win XP'
+ *
*/
-class UserAgentParser
+class UserAgentParser
{
- // browser regex => browser ID
- // if there are aliases, the common name should be last
- static protected $browsers = array(
- 'abrowse' => 'AB',
- 'amaya' => 'AM',
- 'amigavoyager' => 'AV',
- 'amiga-aweb' => 'AW',
- 'arora' => 'AR',
- 'beonex' => 'BE',
-
- // BlackBerry smartphones and tablets
- 'blackberry' => 'BB', // BlackBerry 6 and PlayBook adopted webkit
- 'bb10' => 'B2', // BlackBerry 10
- 'playbook' => 'BP',
-
- 'browsex' => 'BX',
-
- // Camino (and earlier incarnation)
- 'chimera' => 'CA',
- 'camino' => 'CA',
-
- 'cheshire' => 'CS',
-
- // Chrome, Chromium, and ChromePlus
- 'crmo' => 'CH',
- 'chrome' => 'CH',
-
- // Chrome Frame
- 'chromeframe' => 'CF',
-
- 'cometbird' => 'CO',
- 'dillo' => 'DI',
- 'elinks' => 'EL',
- 'epiphany' => 'EP',
- 'fennec' => 'FE',
-
- // Dolfin (or Dolphin)
- 'dolfin' => 'DF',
-
- // Firefox (in its many incarnations and rebranded versions)
- 'phoenix' => 'PX',
- 'mozilla firebird' => 'FB',
- 'firebird' => 'FB',
- 'bonecho' => 'FF',
- 'minefield' => 'FF',
- 'namoroka' => 'FF',
- 'shiretoko' => 'FF',
- 'granparadiso' => 'FF',
- 'iceweasel' => 'FF',
- 'icecat' => 'FF',
- 'firefox' => 'FF',
-
- 'thunderbird' => 'TB',
-
- 'flock' => 'FL',
- 'fluid' => 'FD',
- 'galeon' => 'GA',
- 'google earth' => 'GE',
- 'hana' => 'HA',
- 'hotjava' => 'HJ',
- 'ibrowse' => 'IB',
- 'icab' => 'IC',
-
- // IE (including shells: Acoo, AOL, Avant, Crazy Browser, Green Browser, KKMAN, Maxathon)
- 'msie' => 'IE',
- 'microsoft internet explorer' => 'IE',
- 'internet explorer' => 'IE',
-
- 'iron' => 'IR',
- 'kapiko' => 'KP',
- 'kazehakase' => 'KZ',
- 'k-meleon' => 'KM',
- 'konqueror' => 'KO',
- 'links' => 'LI',
- 'lynx' => 'LX',
- 'midori' => 'MI',
-
- // SeaMonkey (formerly Mozilla Suite) (and rebranded versions)
- 'mozilla' => 'MO',
- 'gnuzilla' => 'SM',
- 'iceape' => 'SM',
- 'seamonkey' => 'SM',
-
- // NCSA Mosaic (and incarnations)
- 'mosaic' => 'MC',
- 'ncsa mosaic' => 'MC',
-
- // Netscape Navigator
- 'navigator' => 'NS',
- 'netscape6' => 'NS',
- 'netscape' => 'NS',
-
- 'nx' => 'NF',
- 'netfront' => 'NF',
-
- 'omniweb' => 'OW',
-
- // Opera
- 'nitro) opera' => 'OP',
- 'opera' => 'OP',
-
- 'rekonq' => 'RK',
-
- // Safari
- 'safari' => 'SF',
- 'applewebkit' => 'SF',
-
- 'titanium' => 'TI',
-
- 'webos' => 'WO',
- 'webpro' => 'WP',
- );
-
- // browser family (by layout engine)
- static protected $browserType = array(
- 'ie' => array('IE'),
- 'gecko' => array('NS', 'PX', 'FF', 'FB', 'CA', 'GA', 'KM', 'MO', 'SM', 'CO', 'FE', 'KP', 'KZ', 'TB'),
- 'khtml' => array('KO'),
- 'webkit' => array('SF', 'CH', 'OW', 'AR', 'EP', 'FL', 'WO', 'AB', 'IR', 'CS', 'FD', 'HA', 'MI', 'GE', 'DF', 'BB', 'BP', 'TI', 'CF', 'RK', 'B2', 'NF'),
- 'opera' => array('OP'),
- );
-
- // WebKit version numbers to Apple Safari version numbers (if Version/X.Y.Z not present)
- static protected $safariVersions = array(
- '536.25' => array('6', '0'),
- '534.48' => array('5', '1'),
- '533.16' => array('5', '0'),
- '533.4' => array('4', '1'),
- '526.11.2' => array('4', '0'),
- '525.26' => array('3', '2'),
- '525.13' => array('3', '1'),
- '522.11' => array('3', '0'),
- '412' => array('2', '0'),
- '312' => array('1', '3'),
- '125' => array('1', '2'),
- '100' => array('1', '1'),
- '85' => array('1', '0'),
- '73' => array('0', '9'),
- '48' => array('0', '8'),
- );
-
- // OmniWeb build numbers to OmniWeb version numbers (if Version/X.Y.Z not present)
- static protected $omniWebVersions = array(
- '622.15' => array('5', '11'),
- '622.10' => array('5', '10'),
- '622.8' => array('5', '9'),
- '622.3' => array('5', '8'),
- '621' => array('5', '7'),
- '613' => array('5', '6'),
- '607' => array('5', '5'),
- '563.34' => array('5', '1'),
- '558.36' => array('5', '0'),
- '496' => array('4', '5'),
- );
-
- // OS regex => OS ID
- static protected $operatingSystems = array(
- 'Android' => 'AND',
- 'Maemo' => 'MAE',
- 'CrOS ' => 'LIN',
- 'Linux' => 'LIN',
-
- 'Xbox' => 'XBX',
-
- // workaround for vendors who changed the WinPhone 7 user agent
- 'WP7' => 'WPH',
-
- 'CYGWIN_NT-6.2' => 'WI8',
- 'Windows NT 6.2' => 'WI8',
- 'Windows 8' => 'WI8',
- 'CYGWIN_NT-6.1' => 'WI7',
- 'Windows NT 6.1' => 'WI7',
- 'Windows 7' => 'WI7',
- 'CYGWIN_NT-6.0' => 'WVI',
- 'Windows NT 6.0' => 'WVI',
- 'Windows Vista' => 'WVI',
- 'CYGWIN_NT-5.2' => 'WS3',
- 'Windows NT 5.2' => 'WS3',
- 'Windows Server 2003 / XP x64' => 'WS3',
- 'CYGWIN_NT-5.1' => 'WXP',
- 'Windows NT 5.1' => 'WXP',
- 'Windows XP' => 'WXP',
- 'CYGWIN_NT-5.0' => 'W2K',
- 'Windows NT 5.0' => 'W2K',
- 'Windows 2000' => 'W2K',
- 'CYGWIN_NT-4.0' => 'WNT',
- 'Windows NT 4.0' => 'WNT',
- 'WinNT' => 'WNT',
- 'Windows NT' => 'WNT',
- 'CYGWIN_ME-4.90' => 'WME',
- 'Win 9x 4.90' => 'WME',
- 'Windows ME' => 'WME',
- 'CYGWIN_98-4.10' => 'W98',
- 'Win98' => 'W98',
- 'Windows 98' => 'W98',
- 'CYGWIN_95-4.0' => 'W95',
- 'Win32' => 'W95',
- 'Win95' => 'W95',
- 'Windows 95' => 'W95',
-
- // Windows Phone OS 7 and above
- 'Windows Phone OS' => 'WPH',
-
- // Windows Mobile 6.x and some later versions of Windows Mobile 5
- 'IEMobile' => 'WMO', // fallback
- 'Windows Mobile' => 'WMO',
-
- // Windows CE, Pocket PC, and Windows Mobile 5 are indistinguishable without vendor/device specific detection
- 'Windows CE' => 'WCE',
-
- 'iPod' => 'IPD',
- 'iPad' => 'IPA',
- 'iPhone' => 'IPH',
+ // browser regex => browser ID
+ // if there are aliases, the common name should be last
+ static protected $browsers = array(
+ 'abrowse' => 'AB',
+ 'amaya' => 'AM',
+ 'amigavoyager' => 'AV',
+ 'amiga-aweb' => 'AW',
+ 'arora' => 'AR',
+ 'beonex' => 'BE',
+
+ // BlackBerry smartphones and tablets
+ 'blackberry' => 'BB', // BlackBerry 6 and PlayBook adopted webkit
+ 'bb10' => 'B2', // BlackBerry 10
+ 'playbook' => 'BP',
+
+ 'browsex' => 'BX',
+
+ // Camino (and earlier incarnation)
+ 'chimera' => 'CA',
+ 'camino' => 'CA',
+
+ 'cheshire' => 'CS',
+
+ // Chrome, Chromium, and ChromePlus
+ 'crmo' => 'CH',
+ 'chrome' => 'CH',
+
+ // Chrome Frame
+ 'chromeframe' => 'CF',
+
+ 'cometbird' => 'CO',
+ 'dillo' => 'DI',
+ 'elinks' => 'EL',
+ 'epiphany' => 'EP',
+ 'fennec' => 'FE',
+
+ // Dolfin (or Dolphin)
+ 'dolfin' => 'DF',
+
+ // Firefox (in its many incarnations and rebranded versions)
+ 'phoenix' => 'PX',
+ 'mozilla firebird' => 'FB',
+ 'firebird' => 'FB',
+ 'bonecho' => 'FF',
+ 'minefield' => 'FF',
+ 'namoroka' => 'FF',
+ 'shiretoko' => 'FF',
+ 'granparadiso' => 'FF',
+ 'iceweasel' => 'FF',
+ 'icecat' => 'FF',
+ 'firefox' => 'FF',
+
+ 'thunderbird' => 'TB',
+
+ 'flock' => 'FL',
+ 'fluid' => 'FD',
+ 'galeon' => 'GA',
+ 'google earth' => 'GE',
+ 'hana' => 'HA',
+ 'hotjava' => 'HJ',
+ 'ibrowse' => 'IB',
+ 'icab' => 'IC',
+
+ // IE (including shells: Acoo, AOL, Avant, Crazy Browser, Green Browser, KKMAN, Maxathon)
+ 'msie' => 'IE',
+ 'microsoft internet explorer' => 'IE',
+ 'internet explorer' => 'IE',
+
+ 'iron' => 'IR',
+ 'kapiko' => 'KP',
+ 'kazehakase' => 'KZ',
+ 'k-meleon' => 'KM',
+ 'konqueror' => 'KO',
+ 'links' => 'LI',
+ 'lynx' => 'LX',
+ 'midori' => 'MI',
+
+ // SeaMonkey (formerly Mozilla Suite) (and rebranded versions)
+ 'mozilla' => 'MO',
+ 'gnuzilla' => 'SM',
+ 'iceape' => 'SM',
+ 'seamonkey' => 'SM',
+
+ // NCSA Mosaic (and incarnations)
+ 'mosaic' => 'MC',
+ 'ncsa mosaic' => 'MC',
+
+ // Netscape Navigator
+ 'navigator' => 'NS',
+ 'netscape6' => 'NS',
+ 'netscape' => 'NS',
+
+ 'nx' => 'NF',
+ 'netfront' => 'NF',
+
+ 'omniweb' => 'OW',
+
+ // Opera
+ 'nitro) opera' => 'OP',
+ 'opera' => 'OP',
+
+ 'rekonq' => 'RK',
+
+ // Safari
+ 'safari' => 'SF',
+ 'applewebkit' => 'SF',
+
+ 'titanium' => 'TI',
+
+ 'webos' => 'WO',
+ 'webpro' => 'WP',
+ );
+
+ // browser family (by layout engine)
+ static protected $browserType = array(
+ 'ie' => array('IE'),
+ 'gecko' => array('NS', 'PX', 'FF', 'FB', 'CA', 'GA', 'KM', 'MO', 'SM', 'CO', 'FE', 'KP', 'KZ', 'TB'),
+ 'khtml' => array('KO'),
+ 'webkit' => array('SF', 'CH', 'OW', 'AR', 'EP', 'FL', 'WO', 'AB', 'IR', 'CS', 'FD', 'HA', 'MI', 'GE', 'DF', 'BB', 'BP', 'TI', 'CF', 'RK', 'B2', 'NF'),
+ 'opera' => array('OP'),
+ );
+
+ // WebKit version numbers to Apple Safari version numbers (if Version/X.Y.Z not present)
+ static protected $safariVersions = array(
+ '536.25' => array('6', '0'),
+ '534.48' => array('5', '1'),
+ '533.16' => array('5', '0'),
+ '533.4' => array('4', '1'),
+ '526.11.2' => array('4', '0'),
+ '525.26' => array('3', '2'),
+ '525.13' => array('3', '1'),
+ '522.11' => array('3', '0'),
+ '412' => array('2', '0'),
+ '312' => array('1', '3'),
+ '125' => array('1', '2'),
+ '100' => array('1', '1'),
+ '85' => array('1', '0'),
+ '73' => array('0', '9'),
+ '48' => array('0', '8'),
+ );
+
+ // OmniWeb build numbers to OmniWeb version numbers (if Version/X.Y.Z not present)
+ static protected $omniWebVersions = array(
+ '622.15' => array('5', '11'),
+ '622.10' => array('5', '10'),
+ '622.8' => array('5', '9'),
+ '622.3' => array('5', '8'),
+ '621' => array('5', '7'),
+ '613' => array('5', '6'),
+ '607' => array('5', '5'),
+ '563.34' => array('5', '1'),
+ '558.36' => array('5', '0'),
+ '496' => array('4', '5'),
+ );
+
+ // OS regex => OS ID
+ static protected $operatingSystems = array(
+ 'Android' => 'AND',
+ 'Maemo' => 'MAE',
+ 'CrOS ' => 'LIN',
+ 'Linux' => 'LIN',
+
+ 'Xbox' => 'XBX',
+
+ // workaround for vendors who changed the WinPhone 7 user agent
+ 'WP7' => 'WPH',
+
+ 'CYGWIN_NT-6.2' => 'WI8',
+ 'Windows NT 6.2' => 'WI8',
+ 'Windows 8' => 'WI8',
+ 'CYGWIN_NT-6.1' => 'WI7',
+ 'Windows NT 6.1' => 'WI7',
+ 'Windows 7' => 'WI7',
+ 'CYGWIN_NT-6.0' => 'WVI',
+ 'Windows NT 6.0' => 'WVI',
+ 'Windows Vista' => 'WVI',
+ 'CYGWIN_NT-5.2' => 'WS3',
+ 'Windows NT 5.2' => 'WS3',
+ 'Windows Server 2003 / XP x64' => 'WS3',
+ 'CYGWIN_NT-5.1' => 'WXP',
+ 'Windows NT 5.1' => 'WXP',
+ 'Windows XP' => 'WXP',
+ 'CYGWIN_NT-5.0' => 'W2K',
+ 'Windows NT 5.0' => 'W2K',
+ 'Windows 2000' => 'W2K',
+ 'CYGWIN_NT-4.0' => 'WNT',
+ 'Windows NT 4.0' => 'WNT',
+ 'WinNT' => 'WNT',
+ 'Windows NT' => 'WNT',
+ 'CYGWIN_ME-4.90' => 'WME',
+ 'Win 9x 4.90' => 'WME',
+ 'Windows ME' => 'WME',
+ 'CYGWIN_98-4.10' => 'W98',
+ 'Win98' => 'W98',
+ 'Windows 98' => 'W98',
+ 'CYGWIN_95-4.0' => 'W95',
+ 'Win32' => 'W95',
+ 'Win95' => 'W95',
+ 'Windows 95' => 'W95',
+
+ // Windows Phone OS 7 and above
+ 'Windows Phone OS' => 'WPH',
+
+ // Windows Mobile 6.x and some later versions of Windows Mobile 5
+ 'IEMobile' => 'WMO', // fallback
+ 'Windows Mobile' => 'WMO',
+
+ // Windows CE, Pocket PC, and Windows Mobile 5 are indistinguishable without vendor/device specific detection
+ 'Windows CE' => 'WCE',
+
+ 'iPod' => 'IPD',
+ 'iPad' => 'IPA',
+ 'iPhone' => 'IPH',
// 'iOS' => 'IOS',
- 'Darwin' => 'MAC',
- 'Macintosh' => 'MAC',
- 'Power Macintosh' => 'MAC',
- 'Mac_PowerPC' => 'MAC',
- 'Mac PPC' => 'MAC',
- 'PPC' => 'MAC',
- 'Mac PowerPC' => 'MAC',
- 'Mac OS' => 'MAC',
-
- 'webOS' => 'WOS',
- 'Palm webOS' => 'WOS',
- 'PalmOS' => 'POS',
- 'Palm OS' => 'POS',
-
- 'BB10' => 'BBX',
- 'BlackBerry' => 'BLB',
- 'RIM Tablet OS' => 'QNX',
- 'QNX' => 'QNX',
-
- 'SymbOS' => 'SYM',
- 'Symbian OS' => 'SYM',
- 'SymbianOS' => 'SYM',
-
- 'bada' => 'SBA',
-
- 'SunOS' => 'SOS',
- 'AIX' => 'AIX',
- 'HP-UX' => 'HPX',
- 'OpenVMS' => 'VMS',
-
- 'FreeBSD' => 'BSD',
- 'NetBSD' => 'NBS',
- 'OpenBSD' => 'OBS',
- 'DragonFly' => 'DFB',
- 'Syllable' => 'SYL',
-
- 'Nintendo WiiU' => 'WIU',
- 'Nintendo Wii' => 'WII',
- 'Nitro' => 'NDS',
- 'Nintendo DSi' => 'DSI',
- 'Nintendo DS' => 'NDS',
- 'Nintendo 3DS' => '3DS',
-
- 'PlayStation Vita' => 'PSV',
- 'PlayStation Portable' => 'PSP',
- 'PlayStation 3' => 'PS3',
-
- 'IRIX' => 'IRI',
- 'OSF1' => 'T64',
- 'OS/2' => 'OS2',
- 'BEOS' => 'BEO',
- 'Amiga' => 'AMI',
- 'AmigaOS' => 'AMI',
- );
-
- // os family
- // NOTE: The keys in this array are used by plugins/UserSettings/functions.php . Any changes
- // made here should also be made in that file.
- static protected $osType = array(
- 'Windows' => array('WI8', 'WI7', 'WVI', 'WS3', 'WXP', 'W2K', 'WNT', 'WME', 'W98', 'W95'),
- 'Linux' => array('LIN'),
- 'Mac' => array('MAC'),
- 'iOS' => array('IPD', 'IPA', 'IPH'),
- 'Android' => array('AND'),
- 'Windows Mobile' => array('WPH', 'WMO', 'WCE'),
- 'Gaming Console' => array('WII', 'WIU', 'PS3', 'XBX'),
- 'Mobile Gaming Console' => array('PSP', 'PSV', 'NDS', 'DSI', '3DS'),
- 'Unix' => array('SOS', 'AIX', 'HP-UX', 'BSD', 'NBS', 'OBS', 'DFB', 'SYL', 'IRI', 'T64'),
- 'Other Mobile' => array('MAE', 'WOS', 'POS', 'BLB', 'QNX', 'SYM', 'SBA'),
- 'Other' => array('VMS', 'OS2', 'BEOS', 'AMI')
- );
-
- static protected $browserIdToName;
- static protected $browserIdToShortName;
- static protected $operatingSystemsIdToName;
- static protected $operatingSystemsIdToShortName;
- static private $init = false;
-
- /**
- * Returns an array of the OS for the submitted user agent
- * 'id' => '',
- * 'name' => '',
- * 'short_name' => '',
- *
- * @param string $userAgent
- * @return string false if OS couldn't be identified, or 3 letters ID (eg. WXP)
- * @see UserAgentParser/OperatingSystems.php for the list of OS (also available in self::$operatingSystems)
- */
- static public function getOperatingSystem($userAgent)
- {
- $userAgent = self::cleanupUserAgent($userAgent);
- self::init();
- $info = array(
- 'id' => '',
- 'name' => '',
- 'short_name' => '',
- );
- foreach(self::$operatingSystems as $key => $value) {
- if (stristr($userAgent, $key) !== false) {
- $info['id'] = $value;
- break;
- }
- }
- if(empty($info['id'])) {
- return false;
- }
- $info['name'] = self::getOperatingSystemNameFromId($info['id']);
- $info['short_name'] = self::getOperatingSystemShortNameFromId($info['id']);
- return $info;
- }
-
- static protected function cleanupUserAgent($userAgent)
- {
- // in case value is URL encoded
- return urldecode($userAgent);
- }
-
- /**
- * Returns the browser information array, given a user agent string.
- *
- * @param string $userAgent
- * @return array false if the browser is "unknown", or
- * array( 'id' => '', // 2 letters ID, eg. FF
- * 'name' => '', // 2 letters ID, eg. FF
- * 'short_name' => '', // 2 letters ID, eg. FF
- * 'major_number' => '', // 2 in firefox 2.0.12
- * 'minor_number' => '', // 0 in firefox 2.0.12
- * 'version' => '', // major_number.minor_number
- * );
- * @see self::$browsers for the list of OS
- */
- static public function getBrowser($userAgent)
- {
- $userAgent = self::cleanupUserAgent($userAgent);
-
- self::init();
-
- $info = array(
- 'id' => '',
- 'name' => '',
- 'short_name' => '',
- 'major_number' => '',
- 'minor_number' => '',
- 'version' => '',
- );
-
- $browsers = self::$browsers;
-
- // derivative browsers often clone the base browser's useragent
- unset($browsers['firefox']);
- unset($browsers['mozilla']);
- unset($browsers['safari']);
- unset($browsers['applewebkit']);
-
- $browsersPattern = str_replace(')', '\)', implode('|', array_keys($browsers)));
-
- $results = array();
-
- // Misbehaving IE add-ons
- $userAgent = preg_replace('/[; ]Mozilla\/[0-9.]+ \([^)]+\)/', '', $userAgent);
-
- // Clean-up BlackBerry device UAs
- $userAgent = preg_replace('~^BlackBerry\d+/~', 'BlackBerry/', $userAgent);
-
- if (preg_match_all("/($browsersPattern)[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?/i", $userAgent, $results)
- || (strpos($userAgent, 'Shiira') === false && preg_match_all("/(firefox|thunderbird|safari)[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?/i", $userAgent, $results))
- || preg_match_all("/(applewebkit)[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?/i", $userAgent, $results)
- || preg_match_all("/^(mozilla)\/([0-9]+)([\.0-9a-z-]+)?(?: \[[a-z]{2}\])? (?:\([^)]*\))$/i", $userAgent, $results)
- || preg_match_all("/^(mozilla)\/[0-9]+(?:[\.0-9a-z-]+)?\s\(.* rv:([0-9]+)([.0-9a-z]+)\) gecko(\/[0-9]{8}|$)(?:.*)/i", $userAgent, $results)
+ 'Darwin' => 'MAC',
+ 'Macintosh' => 'MAC',
+ 'Power Macintosh' => 'MAC',
+ 'Mac_PowerPC' => 'MAC',
+ 'Mac PPC' => 'MAC',
+ 'PPC' => 'MAC',
+ 'Mac PowerPC' => 'MAC',
+ 'Mac OS' => 'MAC',
+
+ 'webOS' => 'WOS',
+ 'Palm webOS' => 'WOS',
+ 'PalmOS' => 'POS',
+ 'Palm OS' => 'POS',
+
+ 'BB10' => 'BBX',
+ 'BlackBerry' => 'BLB',
+ 'RIM Tablet OS' => 'QNX',
+ 'QNX' => 'QNX',
+
+ 'SymbOS' => 'SYM',
+ 'Symbian OS' => 'SYM',
+ 'SymbianOS' => 'SYM',
+
+ 'bada' => 'SBA',
+
+ 'SunOS' => 'SOS',
+ 'AIX' => 'AIX',
+ 'HP-UX' => 'HPX',
+ 'OpenVMS' => 'VMS',
+
+ 'FreeBSD' => 'BSD',
+ 'NetBSD' => 'NBS',
+ 'OpenBSD' => 'OBS',
+ 'DragonFly' => 'DFB',
+ 'Syllable' => 'SYL',
+
+ 'Nintendo WiiU' => 'WIU',
+ 'Nintendo Wii' => 'WII',
+ 'Nitro' => 'NDS',
+ 'Nintendo DSi' => 'DSI',
+ 'Nintendo DS' => 'NDS',
+ 'Nintendo 3DS' => '3DS',
+
+ 'PlayStation Vita' => 'PSV',
+ 'PlayStation Portable' => 'PSP',
+ 'PlayStation 3' => 'PS3',
+
+ 'IRIX' => 'IRI',
+ 'OSF1' => 'T64',
+ 'OS/2' => 'OS2',
+ 'BEOS' => 'BEO',
+ 'Amiga' => 'AMI',
+ 'AmigaOS' => 'AMI',
+ );
+
+ // os family
+ // NOTE: The keys in this array are used by plugins/UserSettings/functions.php . Any changes
+ // made here should also be made in that file.
+ static protected $osType = array(
+ 'Windows' => array('WI8', 'WI7', 'WVI', 'WS3', 'WXP', 'W2K', 'WNT', 'WME', 'W98', 'W95'),
+ 'Linux' => array('LIN'),
+ 'Mac' => array('MAC'),
+ 'iOS' => array('IPD', 'IPA', 'IPH'),
+ 'Android' => array('AND'),
+ 'Windows Mobile' => array('WPH', 'WMO', 'WCE'),
+ 'Gaming Console' => array('WII', 'WIU', 'PS3', 'XBX'),
+ 'Mobile Gaming Console' => array('PSP', 'PSV', 'NDS', 'DSI', '3DS'),
+ 'Unix' => array('SOS', 'AIX', 'HP-UX', 'BSD', 'NBS', 'OBS', 'DFB', 'SYL', 'IRI', 'T64'),
+ 'Other Mobile' => array('MAE', 'WOS', 'POS', 'BLB', 'QNX', 'SYM', 'SBA'),
+ 'Other' => array('VMS', 'OS2', 'BEOS', 'AMI')
+ );
+
+ static protected $browserIdToName;
+ static protected $browserIdToShortName;
+ static protected $operatingSystemsIdToName;
+ static protected $operatingSystemsIdToShortName;
+ static private $init = false;
+
+ /**
+ * Returns an array of the OS for the submitted user agent
+ * 'id' => '',
+ * 'name' => '',
+ * 'short_name' => '',
+ *
+ * @param string $userAgent
+ * @return string false if OS couldn't be identified, or 3 letters ID (eg. WXP)
+ * @see UserAgentParser/OperatingSystems.php for the list of OS (also available in self::$operatingSystems)
+ */
+ static public function getOperatingSystem($userAgent)
+ {
+ $userAgent = self::cleanupUserAgent($userAgent);
+ self::init();
+ $info = array(
+ 'id' => '',
+ 'name' => '',
+ 'short_name' => '',
+ );
+ foreach (self::$operatingSystems as $key => $value) {
+ if (stristr($userAgent, $key) !== false) {
+ $info['id'] = $value;
+ break;
+ }
+ }
+ if (empty($info['id'])) {
+ return false;
+ }
+ $info['name'] = self::getOperatingSystemNameFromId($info['id']);
+ $info['short_name'] = self::getOperatingSystemShortNameFromId($info['id']);
+ return $info;
+ }
+
+ static protected function cleanupUserAgent($userAgent)
+ {
+ // in case value is URL encoded
+ return urldecode($userAgent);
+ }
+
+ /**
+ * Returns the browser information array, given a user agent string.
+ *
+ * @param string $userAgent
+ * @return array false if the browser is "unknown", or
+ * array( 'id' => '', // 2 letters ID, eg. FF
+ * 'name' => '', // 2 letters ID, eg. FF
+ * 'short_name' => '', // 2 letters ID, eg. FF
+ * 'major_number' => '', // 2 in firefox 2.0.12
+ * 'minor_number' => '', // 0 in firefox 2.0.12
+ * 'version' => '', // major_number.minor_number
+ * );
+ * @see self::$browsers for the list of OS
+ */
+ static public function getBrowser($userAgent)
+ {
+ $userAgent = self::cleanupUserAgent($userAgent);
+
+ self::init();
+
+ $info = array(
+ 'id' => '',
+ 'name' => '',
+ 'short_name' => '',
+ 'major_number' => '',
+ 'minor_number' => '',
+ 'version' => '',
+ );
+
+ $browsers = self::$browsers;
+
+ // derivative browsers often clone the base browser's useragent
+ unset($browsers['firefox']);
+ unset($browsers['mozilla']);
+ unset($browsers['safari']);
+ unset($browsers['applewebkit']);
+
+ $browsersPattern = str_replace(')', '\)', implode('|', array_keys($browsers)));
+
+ $results = array();
+
+ // Misbehaving IE add-ons
+ $userAgent = preg_replace('/[; ]Mozilla\/[0-9.]+ \([^)]+\)/', '', $userAgent);
+
+ // Clean-up BlackBerry device UAs
+ $userAgent = preg_replace('~^BlackBerry\d+/~', 'BlackBerry/', $userAgent);
+
+ if (preg_match_all("/($browsersPattern)[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?/i", $userAgent, $results)
+ || (strpos($userAgent, 'Shiira') === false && preg_match_all("/(firefox|thunderbird|safari)[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?/i", $userAgent, $results))
+ || preg_match_all("/(applewebkit)[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?/i", $userAgent, $results)
+ || preg_match_all("/^(mozilla)\/([0-9]+)([\.0-9a-z-]+)?(?: \[[a-z]{2}\])? (?:\([^)]*\))$/i", $userAgent, $results)
+ || preg_match_all("/^(mozilla)\/[0-9]+(?:[\.0-9a-z-]+)?\s\(.* rv:([0-9]+)([.0-9a-z]+)\) gecko(\/[0-9]{8}|$)(?:.*)/i", $userAgent, $results)
|| (strpos($userAgent, 'Nintendo 3DS') !== false && preg_match_all("/^(mozilla).*version\/([0-9]+)([.0-9a-z]+)?/i", $userAgent, $results))
- )
- {
- // browser code (usually the first match)
- $count = 0;
- $info['id'] = self::$browsers[strtolower($results[1][0])];
-
- // sometimes there's a better match at the end
- if(strpos($userAgent, 'chromeframe') !== false) {
- $count = count($results[0]) - 1;
- $info['id'] = 'CF';
- }
- elseif(($info['id'] == 'IE' || $info['id'] == 'LX') && (count($results[0]) > 1)) {
- $count = count($results[0]) - 1;
- $info['id'] = self::$browsers[strtolower($results[1][$count])];
- }
-
- // Netscape fix
- if($info['id'] == 'MO' && $count == 0) {
- if(stripos($userAgent, 'PlayStation') !== false) {
- return false;
- }
- if(strpos($userAgent, 'Nintendo 3DS') !== false) {
+ ) {
+ // browser code (usually the first match)
+ $count = 0;
+ $info['id'] = self::$browsers[strtolower($results[1][0])];
+
+ // sometimes there's a better match at the end
+ if (strpos($userAgent, 'chromeframe') !== false) {
+ $count = count($results[0]) - 1;
+ $info['id'] = 'CF';
+ } elseif (($info['id'] == 'IE' || $info['id'] == 'LX') && (count($results[0]) > 1)) {
+ $count = count($results[0]) - 1;
+ $info['id'] = self::$browsers[strtolower($results[1][$count])];
+ }
+
+ // Netscape fix
+ if ($info['id'] == 'MO' && $count == 0) {
+ if (stripos($userAgent, 'PlayStation') !== false) {
+ return false;
+ }
+ if (strpos($userAgent, 'Nintendo 3DS') !== false) {
$info['id'] = 'NF';
+ } elseif (count($results) == 4) {
+ $info['id'] = 'NS';
+ }
+ } // BlackBerry devices
+ elseif (strpos($userAgent, 'BlackBerry') !== false) {
+ $info['id'] = 'BB';
+ } elseif (strpos($userAgent, 'RIM Tablet OS') !== false) {
+ $info['id'] = 'BP';
+ } elseif (strpos($userAgent, 'BB10') !== false) {
+ $info['id'] = 'B2';
+ } elseif (strpos($userAgent, 'Playstation Vita') !== false) {
+ $info['id'] = 'NF';
+
+ if (preg_match_all("/(silk)[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?/i", $userAgent, $newResults)) {
+ $results = $newResults;
+ $count = count($results[0]) - 1;
+ }
+ }
+
+ // Version/X.Y.Z override
+ if (preg_match_all("/(version)[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?/i", $userAgent, $newResults)) {
+ $results = $newResults;
+ $count = count($results[0]) - 1;
+ }
+
+ // major version number (1 in mozilla 1.7)
+ $info['major_number'] = $results[2][$count];
+
+ // is an minor version number ? If not, 0
+ $match = array();
+
+ preg_match('/([.\0-9]+)?([\.a-z0-9]+)?/i', $results[3][$count], $match);
+
+ if (isset($match[1])) {
+ // find minor version number (7 in mozilla 1.7, 9 in firefox 0.9.3)
+ $dot = strpos(substr($match[1], 1), '.');
+ if ($dot !== false) {
+ $info['minor_number'] = substr($match[1], 1, $dot);
+ } else {
+ $info['minor_number'] = substr($match[1], 1);
+ }
+ } else {
+ $info['minor_number'] = '0';
+ }
+ $info['version'] = $info['major_number'] . '.' . $info['minor_number'];
+
+ // IE compatibility mode
+ if ($info['id'] == 'IE'
+ && strncmp($userAgent, 'Mozilla/4.0', 11) == 0
+ && preg_match('~ Trident/([0-9]+)\.[0-9]+~', $userAgent, $tridentVersion)
+ ) {
+ $info['major_number'] = $tridentVersion[1] + 4;
+ $info['minor_number'] = '0';
+ $info['version'] = $info['major_number'] . '.' . $info['minor_number'];
+ }
+
+ // Safari fix
+ if ($info['id'] == 'SF') {
+ foreach (self::$safariVersions as $buildVersion => $productVersion) {
+ if (version_compare($info['version'], $buildVersion) >= 0) {
+ $info['major_number'] = $productVersion[0];
+ $info['minor_number'] = $productVersion[1];
+ $info['version'] = $info['major_number'] . '.' . $info['minor_number'];
+ break;
+ }
+ }
+ }
+
+ // OmniWeb fix
+ if ($info['id'] == 'OW') {
+ foreach (self::$omniWebVersions as $buildVersion => $productVersion) {
+ if (version_compare($info['version'], $buildVersion) >= 0) {
+ $info['major_number'] = $productVersion[0];
+ $info['minor_number'] = $productVersion[1];
+ $info['version'] = $info['major_number'] . '.' . $info['minor_number'];
+ break;
+ }
}
- elseif(count($results) == 4) {
- $info['id'] = 'NS';
- }
- }
- // BlackBerry devices
- elseif(strpos($userAgent, 'BlackBerry') !== false) {
- $info['id'] = 'BB';
- }
- elseif(strpos($userAgent, 'RIM Tablet OS') !== false) {
- $info['id'] = 'BP';
- }
- elseif(strpos($userAgent, 'BB10') !== false) {
- $info['id'] = 'B2';
- }
- elseif(strpos($userAgent, 'Playstation Vita') !== false) {
- $info['id'] = 'NF';
-
- if(preg_match_all("/(silk)[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?/i", $userAgent, $newResults))
- {
- $results = $newResults;
- $count = count($results[0])-1;
- }
- }
-
- // Version/X.Y.Z override
- if(preg_match_all("/(version)[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?/i", $userAgent, $newResults))
- {
- $results = $newResults;
- $count = count($results[0])-1;
- }
-
- // major version number (1 in mozilla 1.7)
- $info['major_number'] = $results[2][$count];
-
- // is an minor version number ? If not, 0
- $match = array();
-
- preg_match('/([.\0-9]+)?([\.a-z0-9]+)?/i', $results[3][$count], $match);
-
- if(isset($match[1])) {
- // find minor version number (7 in mozilla 1.7, 9 in firefox 0.9.3)
- $dot = strpos(substr($match[1], 1), '.');
- if($dot !== false) {
- $info['minor_number'] = substr($match[1], 1, $dot);
- }
- else {
- $info['minor_number'] = substr($match[1], 1);
- }
- }
- else {
- $info['minor_number'] = '0';
- }
- $info['version'] = $info['major_number'] . '.' . $info['minor_number'];
-
- // IE compatibility mode
- if($info['id'] == 'IE'
- && strncmp($userAgent, 'Mozilla/4.0', 11) == 0
- && preg_match('~ Trident/([0-9]+)\.[0-9]+~', $userAgent, $tridentVersion))
- {
- $info['major_number'] = $tridentVersion[1] + 4;
- $info['minor_number'] = '0';
- $info['version'] = $info['major_number'] . '.' .$info['minor_number'];
- }
-
- // Safari fix
- if($info['id'] == 'SF') {
- foreach(self::$safariVersions as $buildVersion => $productVersion) {
- if(version_compare($info['version'], $buildVersion) >= 0) {
- $info['major_number'] = $productVersion[0];
- $info['minor_number'] = $productVersion[1];
- $info['version'] = $info['major_number'] . '.' . $info['minor_number'];
- break;
- }
- }
- }
-
- // OmniWeb fix
- if($info['id'] == 'OW') {
- foreach(self::$omniWebVersions as $buildVersion => $productVersion) {
- if(version_compare($info['version'], $buildVersion) >= 0) {
- $info['major_number'] = $productVersion[0];
- $info['minor_number'] = $productVersion[1];
- $info['version'] = $info['major_number'] . '.' . $info['minor_number'];
- break;
- }
- }
- }
-
- // SeaMonkey fix
- if($info['id'] == 'MO' && $info['version'] == '1.9') {
- $info['id'] = 'SM';
- }
-
- $info['name'] = self::getBrowserNameFromId($info['id']);
- $info['short_name'] = self::getBrowserShortNameFromId($info['id']);
-
- return $info;
- }
-
- return false;
- }
-
- static protected function init() {
- if(self::$init) {
- return;
- }
- self::$init = true;
-
- // init browser names and short names
- self::$browserIdToName = array_map('ucwords',array_flip(self::$browsers));
- self::$browserIdToName['AB'] = 'ABrowse';
- self::$browserIdToName['AV'] = 'AmigaVoyager';
- self::$browserIdToName['AW'] = 'Amiga AWeb';
- self::$browserIdToName['BB'] = 'BlackBerry';
- self::$browserIdToName['BP'] = 'PlayBook';
- self::$browserIdToName['B2'] = 'BlackBerry';
- self::$browserIdToName['BX'] = 'BrowseX';
- self::$browserIdToName['CF'] = 'Chrome Frame';
- self::$browserIdToName['CO'] = 'CometBird';
- self::$browserIdToName['EL'] = 'ELinks';
- self::$browserIdToName['FF'] = 'Firefox';
- self::$browserIdToName['HJ'] = 'HotJava';
- self::$browserIdToName['IB'] = 'IBrowse';
- self::$browserIdToName['IC'] = 'iCab';
- self::$browserIdToName['KM'] = 'K-Meleon';
- self::$browserIdToName['MC'] = 'NCSA Mosaic';
- self::$browserIdToName['NF'] = 'NetFront';
- self::$browserIdToName['OW'] = 'OmniWeb';
- self::$browserIdToName['SF'] = 'Safari';
- self::$browserIdToName['SM'] = 'SeaMonkey';
- self::$browserIdToName['WO'] = 'Palm webOS';
- self::$browserIdToName['WP'] = 'WebPro';
-
- self::$browserIdToShortName = self::$browserIdToName;
- self::$browserIdToShortName['AW'] = 'AWeb';
- self::$browserIdToShortName['FB'] = 'Firebird';
- self::$browserIdToShortName['IE'] = 'IE';
- self::$browserIdToShortName['MC'] = 'Mosaic';
- self::$browserIdToShortName['BP'] = 'PlayBook';
- self::$browserIdToShortName['WO'] = 'webOS';
-
- // init OS names and short names
+ }
+
+ // SeaMonkey fix
+ if ($info['id'] == 'MO' && $info['version'] == '1.9') {
+ $info['id'] = 'SM';
+ }
+
+ $info['name'] = self::getBrowserNameFromId($info['id']);
+ $info['short_name'] = self::getBrowserShortNameFromId($info['id']);
+
+ return $info;
+ }
+
+ return false;
+ }
+
+ static protected function init()
+ {
+ if (self::$init) {
+ return;
+ }
+ self::$init = true;
+
+ // init browser names and short names
+ self::$browserIdToName = array_map('ucwords', array_flip(self::$browsers));
+ self::$browserIdToName['AB'] = 'ABrowse';
+ self::$browserIdToName['AV'] = 'AmigaVoyager';
+ self::$browserIdToName['AW'] = 'Amiga AWeb';
+ self::$browserIdToName['BB'] = 'BlackBerry';
+ self::$browserIdToName['BP'] = 'PlayBook';
+ self::$browserIdToName['B2'] = 'BlackBerry';
+ self::$browserIdToName['BX'] = 'BrowseX';
+ self::$browserIdToName['CF'] = 'Chrome Frame';
+ self::$browserIdToName['CO'] = 'CometBird';
+ self::$browserIdToName['EL'] = 'ELinks';
+ self::$browserIdToName['FF'] = 'Firefox';
+ self::$browserIdToName['HJ'] = 'HotJava';
+ self::$browserIdToName['IB'] = 'IBrowse';
+ self::$browserIdToName['IC'] = 'iCab';
+ self::$browserIdToName['KM'] = 'K-Meleon';
+ self::$browserIdToName['MC'] = 'NCSA Mosaic';
+ self::$browserIdToName['NF'] = 'NetFront';
+ self::$browserIdToName['OW'] = 'OmniWeb';
+ self::$browserIdToName['SF'] = 'Safari';
+ self::$browserIdToName['SM'] = 'SeaMonkey';
+ self::$browserIdToName['WO'] = 'Palm webOS';
+ self::$browserIdToName['WP'] = 'WebPro';
+
+ self::$browserIdToShortName = self::$browserIdToName;
+ self::$browserIdToShortName['AW'] = 'AWeb';
+ self::$browserIdToShortName['FB'] = 'Firebird';
+ self::$browserIdToShortName['IE'] = 'IE';
+ self::$browserIdToShortName['MC'] = 'Mosaic';
+ self::$browserIdToShortName['BP'] = 'PlayBook';
+ self::$browserIdToShortName['WO'] = 'webOS';
+
+ // init OS names and short names
$operatingSystemsIdToName = array(
'IPD' => 'iPod',
'IPA' => 'iPad',
@@ -655,74 +645,70 @@ class UserAgentParser
'UNK' => 'Unknown',
);
self::$operatingSystemsIdToShortName = array_merge(self::$operatingSystemsIdToName, $operatingSystemsIdToShortName);
- }
-
- static public function getBrowserNameFromId($browserId)
- {
- self::init();
- if(isset(self::$browserIdToName[$browserId])) {
- return self::$browserIdToName[$browserId];
- }
- return false;
- }
-
- static public function getBrowserShortNameFromId($browserId)
- {
- self::init();
- if(isset(self::$browserIdToShortName[$browserId])) {
- return self::$browserIdToShortName[$browserId];
- }
- return false;
- }
-
- static public function getBrowserFamilyFromId($browserId)
- {
- self::init();
- $familyNameToUse = 'unknown';
- foreach(self::$browserType as $familyName => $aBrowsers)
- {
- if(in_array($browserId, $aBrowsers))
- {
- $familyNameToUse = $familyName;
- break;
- }
- }
- return $familyNameToUse;
- }
-
- static public function getOperatingSystemNameFromId($osId)
- {
- self::init();
- if(isset(self::$operatingSystemsIdToName[$osId])) {
- return self::$operatingSystemsIdToName[$osId];
- }
- return false;
- }
-
- static public function getOperatingSystemShortNameFromId($osId)
- {
- self::init();
- if(isset(self::$operatingSystemsIdToShortName[$osId])) {
- return self::$operatingSystemsIdToShortName[$osId];
- }
- return false;
- }
-
- static public function getOperatingSystemIdFromName($osName)
- {
- return isset(self::$operatingSystems[$osName]) ? self::$operatingSystems[$osName] : false;
- }
-
- static public function getOperatingSystemFamilyFromId($osId)
- {
- self::init();
- foreach (self::$osType as $familyName => $aSystems)
- {
- if (in_array($osId, $aSystems))
- {
- return $familyName;
- }
- }
- return 'unknown';
- }
+ }
+
+ static public function getBrowserNameFromId($browserId)
+ {
+ self::init();
+ if (isset(self::$browserIdToName[$browserId])) {
+ return self::$browserIdToName[$browserId];
+ }
+ return false;
+ }
+
+ static public function getBrowserShortNameFromId($browserId)
+ {
+ self::init();
+ if (isset(self::$browserIdToShortName[$browserId])) {
+ return self::$browserIdToShortName[$browserId];
+ }
+ return false;
+ }
+
+ static public function getBrowserFamilyFromId($browserId)
+ {
+ self::init();
+ $familyNameToUse = 'unknown';
+ foreach (self::$browserType as $familyName => $aBrowsers) {
+ if (in_array($browserId, $aBrowsers)) {
+ $familyNameToUse = $familyName;
+ break;
+ }
+ }
+ return $familyNameToUse;
+ }
+
+ static public function getOperatingSystemNameFromId($osId)
+ {
+ self::init();
+ if (isset(self::$operatingSystemsIdToName[$osId])) {
+ return self::$operatingSystemsIdToName[$osId];
+ }
+ return false;
+ }
+
+ static public function getOperatingSystemShortNameFromId($osId)
+ {
+ self::init();
+ if (isset(self::$operatingSystemsIdToShortName[$osId])) {
+ return self::$operatingSystemsIdToShortName[$osId];
+ }
+ return false;
+ }
+
+ static public function getOperatingSystemIdFromName($osName)
+ {
+ return isset(self::$operatingSystems[$osName]) ? self::$operatingSystems[$osName] : false;
+ }
+
+ static public function getOperatingSystemFamilyFromId($osId)
+ {
+ self::init();
+ foreach (self::$osType as $familyName => $aSystems) {
+ if (in_array($osId, $aSystems)) {
+ return $familyName;
+ }
+ }
+ return 'unknown';
+ }
}
diff --git a/libs/UserAgentParser/UserAgentParser.test.php b/libs/UserAgentParser/UserAgentParser.test.php
index f5468c1b6b..cd23f36e99 100644
--- a/libs/UserAgentParser/UserAgentParser.test.php
+++ b/libs/UserAgentParser/UserAgentParser.test.php
@@ -1,48 +1,48 @@
<?php
-if(!isset($_GET['setUserAgent']) && !isset($_SERVER['HTTP_USER_AGENT'])) die;
+if (!isset($_GET['setUserAgent']) && !isset($_SERVER['HTTP_USER_AGENT'])) die;
-require_once dirname(__FILE__).'/UserAgentParser.php';
+require_once dirname(__FILE__) . '/UserAgentParser.php';
echo "<h2>UserAgentParser php library test</h2>";
-$testUserAgent = array(
- 'my user agent' => '',
- 'ie8 on win7' => 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET CLR 3.0.04506; .NET CLR 3.5.21022; InfoPath.2; SLCC1; Zune 3.0)',
- 'ie8 on vista (compatibility view)' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/4.0)',
- 'ie8 on vista' => 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)',
- 'chrome on winxp' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/1.0.154.48 Safari/525.19',
- 'IE6 on winxp' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648)',
- 'safari on winxp' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Version/3.1.2 Safari/525.21',
- 'FF3 on winxp' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6',
- 'opera 9.63 on winxp' => 'Opera/9.63 (Windows NT 5.1; U; en) Presto/2.1.1',
- 'Blackberry' => 'BlackBerry8700/4.1.0 Profile/MIDP-2.0 Configuration/CLDC-1.1',
- 'opera 9.30 on Nintendo Wii' => 'Opera/9.30 (Nintendo Wii; U; ; 2047-7; en)',
- 'iphone' => 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 2_2 like Mac OS X; en-us) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5G77 Safari/525.20',
- 'iPod touch' => 'Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3A100a Safari/419.3',
- 'iPod' => 'Mozilla/5.0 (iPod; U; CPU iPhone OS 2_2_1 like Mac OS X; en-us) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5H11a Safari/525.20',
- 'Android' => 'Mozilla/5.0 (Linux; U; Android 1.1; en-us; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2',
- 'PalmOS' => 'Mozilla/5.0 [en] (PalmOS; U; WebPro/3.5; Palm-Zi72) ',
- 'safari on mac os X' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_5; en-us) AppleWebKit/527.3+ (KHTML, like Gecko) Version/3.1.2 Safari/525.20.1',
- 'opera 9.64 on win ME' => 'Opera/9.64 (Windows ME; U; en) Presto/2.1.1',
- 'opera 10.00 on XP' => 'Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.00',
- 'iron on win7' => 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/531.0 (KHTML, like Gecko) Iron/3.0.189.0 Safari/531.0',
- 'firefox 3.6 alpha on vista' => 'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2a2pre) Gecko/20090826 Namoroka/3.6a2pre',
- 'firefox 3.5 alpha on win7' => 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1b4pre) Gecko/20090420 Shiretoko/3.5b4pre (.NET CLR 3.5.30729)',
- 'firefox nightly build' => 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:2.0a1pre) Gecko/2008060602 Minefield/4.0a1pre',
- 'thunderbird 14.0 with lightning 1.6' => 'Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20120713 Thunderbird/14.0 Lightning/1.6',
+$testUserAgent = array(
+ 'my user agent' => '',
+ 'ie8 on win7' => 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET CLR 3.0.04506; .NET CLR 3.5.21022; InfoPath.2; SLCC1; Zune 3.0)',
+ 'ie8 on vista (compatibility view)' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/4.0)',
+ 'ie8 on vista' => 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)',
+ 'chrome on winxp' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/1.0.154.48 Safari/525.19',
+ 'IE6 on winxp' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648)',
+ 'safari on winxp' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Version/3.1.2 Safari/525.21',
+ 'FF3 on winxp' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6',
+ 'opera 9.63 on winxp' => 'Opera/9.63 (Windows NT 5.1; U; en) Presto/2.1.1',
+ 'Blackberry' => 'BlackBerry8700/4.1.0 Profile/MIDP-2.0 Configuration/CLDC-1.1',
+ 'opera 9.30 on Nintendo Wii' => 'Opera/9.30 (Nintendo Wii; U; ; 2047-7; en)',
+ 'iphone' => 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 2_2 like Mac OS X; en-us) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5G77 Safari/525.20',
+ 'iPod touch' => 'Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3A100a Safari/419.3',
+ 'iPod' => 'Mozilla/5.0 (iPod; U; CPU iPhone OS 2_2_1 like Mac OS X; en-us) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5H11a Safari/525.20',
+ 'Android' => 'Mozilla/5.0 (Linux; U; Android 1.1; en-us; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2',
+ 'PalmOS' => 'Mozilla/5.0 [en] (PalmOS; U; WebPro/3.5; Palm-Zi72) ',
+ 'safari on mac os X' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_5; en-us) AppleWebKit/527.3+ (KHTML, like Gecko) Version/3.1.2 Safari/525.20.1',
+ 'opera 9.64 on win ME' => 'Opera/9.64 (Windows ME; U; en) Presto/2.1.1',
+ 'opera 10.00 on XP' => 'Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.00',
+ 'iron on win7' => 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/531.0 (KHTML, like Gecko) Iron/3.0.189.0 Safari/531.0',
+ 'firefox 3.6 alpha on vista' => 'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2a2pre) Gecko/20090826 Namoroka/3.6a2pre',
+ 'firefox 3.5 alpha on win7' => 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1b4pre) Gecko/20090420 Shiretoko/3.5b4pre (.NET CLR 3.5.30729)',
+ 'firefox nightly build' => 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:2.0a1pre) Gecko/2008060602 Minefield/4.0a1pre',
+ 'thunderbird 14.0 with lightning 1.6' => 'Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20120713 Thunderbird/14.0 Lightning/1.6',
);
echo "Test with another user agent: ";
-foreach($testUserAgent as $name => $userAgent) {
- echo "<a href='?setUserAgent=".urlencode($userAgent)."'>$name</a>, ";
+foreach ($testUserAgent as $name => $userAgent) {
+ echo "<a href='?setUserAgent=" . urlencode($userAgent) . "'>$name</a>, ";
}
echo "<hr>";
-if(isset($_GET['setUserAgent']) && !empty($_GET['setUserAgent'])) {
- echo "User Agent:";
- $userAgent = urldecode($_GET['setUserAgent']);
+if (isset($_GET['setUserAgent']) && !empty($_GET['setUserAgent'])) {
+ echo "User Agent:";
+ $userAgent = urldecode($_GET['setUserAgent']);
} else {
- echo "Your user agent:";
- $userAgent = $_SERVER['HTTP_USER_AGENT'];
+ echo "Your user agent:";
+ $userAgent = $_SERVER['HTTP_USER_AGENT'];
}
-echo " <b>".htmlentities($userAgent)."</b><br><br>";
+echo " <b>" . htmlentities($userAgent) . "</b><br><br>";
echo "Browser info:<pre>";
var_dump(UserAgentParser::getBrowser($userAgent));