0) { // Populate the resultset with the profile data and get an array // of profile ids. $profileIds = fiftyone_degrees_readProfiles($base_location, $_51d, $final); // Record the time the matching process took to complete. $time = explode(' ', microtime()); $time = $time[1] + $time[0]; $finish = $time; $total_time = round(($finish - $start), 4); $_51d['DetectionTime'] = $total_time * 1000; // Set the device ID based on the 4 profile ids provided. $_51d['DeviceID'] = $profileIds[0] . '-' . $profileIds[1] . '-' . $profileIds[2] . '-' . $profileIds[3]; // Record the first user agent of the device matched against. $_51d['MatchedUserAgent'] = $final[4]; // Record all the user agent of the device matched against. $_51d['MatchedUserAgents'] = $final[5]; } // If there is a session record the results for future requests. if (isset($_SESSION)) { $_SESSION['51D'] = $_51d; } } else { // The session already holds the results of a previous match. // Use that one and set the detection time to zero. $_51d = $_SESSION['51D']; if ($_51d['DetectionTime'] != 0.00) { $_51d['DetectionTime'] = 0.00; $_SESSION['51D'] = $_51d; } } return $_51d; } function fiftyone_degrees_GetOffsets($useragent, $handlers) { // Request each handler to provide matching devices, if any. foreach ($handlers as $handler_number => $confidence) { include_once "Handlers/" . $handler_number . ".php"; $device = call_user_func("_H" . $handler_number, $useragent); if ($device != NULL) { $devices[] = $device; } } // If devices have been found reduce them to a single device. if (isset($devices[0])) { // Produce an array of final devices. $final_devices = array(); foreach ($devices as $device) { foreach ($device as $fin) { $final_devices[] = $fin; } } if (count($final_devices) == 1) { // If there is only one device found then use this one. $final = $final_devices[0]; } else { // If more than one device has been found then use the // final matcher to reduce to a single device. include_once "Handlers/Calculations/FinalMatcher.php"; $final = fiftyone_degrees_finalMatcher($useragent, $final_devices); } return $final; } return null; } /** * Gets the useragents associated with the current request. * * Checks other header fields for the presence of original * user agent values and returns useful headers and the * components they relate to. * * return array * Each element has a 'value', the useragent string, and * 'coms', and array of ints that show which components * that useragent can be used with. * element [] -> * 'value' (string) -> the useragent string * 'coms' (array (int)) -> a list of component ids the UA * supports. */ function fiftyone_degrees_GetUserAgents() { $results = array(); $headers = array(); // the order that the $headers array gets populated in is very // important. The first array has the most priority. // 'coms' is short for component id. These refer to what components there // headers are able to identify. Some browsers, such as Opera Mobi, have // a UA header only that identifies browser, and another UA header that is the // stock UA for identifying hardware and software. These need to be // processed seperately. // com ids: // 1 - hardware // 2 - software // 3 - browser // 4 - crawler $headers[] = array( 'coms' => array(0,1), 'HTTP_DEVICE_STOCK_UA', 'HTTP_X_DEVICE_USER_AGENT', 'HTTP_X_OPERAMINI_PHONE_UA' ); $headers[] = array( 'coms' => array(0,1,2,3), 'HTTP_USER_AGENT' ); // goes thorugh each set of headers looking for one that has been // populated in $_SERVER foreach($headers as $header) { foreach($header as $UA) { if(is_array($UA)) // ignore array, as array will be 'coms' continue; if (array_key_exists($UA, $_SERVER)) { // match found, add to $results $results[] = fiftyone_degrees_FillUserAgentArray($_SERVER[$UA], $header['coms']); } } } return $results; } /** * Gets an array with a useragent and an aray of int showing which * components the UA supports. * * $UA (string) - the useragent to fill the array with. * * $coms (array (int)) - an array of component ids the useragent supports. * If null, or not an array, the useragent will be assumed to support all * component ids. * * return (array) * An associative array of the useragent and the components it supports. * element -> * 'value' (string) -> the useragent string * 'coms' (array (int)) -> a list of component ids the UA * supports. */ function fiftyone_degrees_FillUserAgentArray($UA, $coms = null) { if(is_array($coms) == FALSE) $coms = array(0,1,2,3); $result = array( 'value' => $UA, 'coms' => $coms ); return $result; } /** * Populates the resultset with profile data. * * Uses the Profiles file to find profile files and read * contents into the resultset. * * array $base_location * Base folder for module. * array $resultset * Resultset to be populated. * array $final * Array of offsets in the profiles file for each profile id. * return array * Array of profile ids for each offset. Used for the DeviceID. */ function fiftyone_degrees_readProfiles($base_location, &$resultset, $final) { $profileIds = array(); if (($handle = fopen($base_location . "Profiles.dat", "r")) !== FALSE) { foreach (array_slice($final, 0, 4) as $offset) { // Move to the position in the profiles file. fseek($handle, $offset); // The first line is the profile id which must be trimmed to remove // the new line character. $profileIds[] = trim(fgets($handle)); // Read the profile values and add to the resultset. while (($data = fgetcsv($handle, 2777, "|")) !== FALSE && $data[0] != NULL) { switch ($data[1]) { // This is a single value property. case "0": $resultset[$data[0]] = $data[2]; break; // This is a list property with multiple values. case "1": $resultset[$data[0]] = array_slice($data, 3); break; } } } fclose($handle); } return $profileIds; }