/webapp-php/application/models/daily.php
PHP | 1022 lines | 655 code | 115 blank | 252 comment | 123 complexity | 80170429f61b414ba9474884ee029bd1 MD5 | raw file
- <?php defined('SYSPATH') or die('No direct script access.');
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- require_once(Kohana::find_file('libraries', 'timeutil', TRUE, 'php'));
- /**
- * Model class for ADU, a.k.a. Active Daily Users / Installs.
- *
- * @package SocorroUI
- * @subpackage Models
- * @author Ryan Snyder <rsnyder@mozilla.com>
- */
- class Daily_Model extends Model {
- /**
- * The timestamp for today's date.
- */
- public $today = 0;
- /**
- * Class Constructor
- */
- public function __construct()
- {
- parent::__construct();
- $config = array();
- $credentials = Kohana::config('webserviceclient.basic_auth');
- if ($credentials) {
- $config['basic_auth'] = $credentials;
- }
- $this->service = new Web_Service($config);
- $this->today = strtotime(date('Y-m-d'));
- }
- /**
- * Prepare the statistics for Crashes per ADU by Operating System.
- *
- * The idea of throttled users were implemented in Socorro 1.5 - https://bugzilla.mozilla.org/show_bug.cgi?id=539337
- *
- * Throttling is inputted into the UI. It is an effective throttling of client throttling * server throttling. Reported
- * Active Daily Users are updated according to throttling percentages.
- *
- * @access public
- * @param object The response object from the API call
- * @param array An array of effective throttle rates for each version
- * @return array An array of statistics
- */
- public function calculateStatisticsByOS ($results, $throttle)
- {
- if (!empty($results)) {
- if (!empty($throttle)) {
- $t = array_shift($throttle);
- $throttle_1 = ($t > 0) ? ($t / 100) : 1;
- $throttle_2 = 1 - $throttle_1;
- $throttle_ratio = $throttle_2 / $throttle_1;
- } else {
- $throttle_1 = 1;
- $throttle_2 = 0;
- $throttle_ratio = 0;
- }
- $statistics = array(
- 'ratio' => 0.00,
- 'crashes' => 0,
- 'os' => array(),
- 'throttle' => $throttle_1,
- 'users' => 0,
- );
- foreach ($results->versions as $version) {
- foreach ($version->statistics as $v) {
- $date = $v->date;
- if (strtotime($date) < $this->today) {
- $key = $v->os;
- if (!isset($statistics['os'][$key])) {
- $statistics['os'][$key] = array(
- 'crashes' => 0,
- 'users' => 0,
- 'ratio' => 0.00,
- );
- }
- if (!isset($statistics['os'][$key][$date])) {
- $statistics['os'][$key][$date] = array(
- 'crashes' => 0,
- 'users' => 0,
- 'ratio' => 0.00,
- );
- }
- $throttled_crashes = $v->crashes;
- if ($throttle_ratio > 0) {
- $throttled_crashes += ($v->crashes * $throttle_ratio);
- }
- $statistics['os'][$key][$date]['crashes'] += $throttled_crashes;
- $statistics['os'][$key][$date]['throttle'] = $throttle_1;
- $statistics['os'][$key][$date]['users'] += $v->users;
- if ($statistics['os'][$key][$date]['crashes'] > 0 && $statistics['os'][$key][$date]['users'] > 0) {
- $statistics['os'][$key][$date]['ratio'] = $statistics['os'][$key][$date]['crashes'] / $statistics['os'][$key][$date]['users'];
- } else {
- $statistics['os'][$key][$date]['ratio'] = 0.00;
- }
- $statistics['crashes'] += $throttled_crashes;
- $statistics['users'] += $v->users;
- $statistics['os'][$key]['crashes'] += $throttled_crashes;
- $statistics['os'][$key]['users'] += $v->users;
- if ($statistics['os'][$key]['crashes'] > 0 && $statistics['os'][$key]['users'] > 0) {
- $statistics['os'][$key]['ratio'] = $statistics['os'][$key]['crashes'] / $statistics['os'][$key]['users'];
- } else {
- $statistics['os'][$key]['ratio'] = 0.00;
- }
- }
- }
- }
- if ($statistics['crashes'] > 0 && $statistics['users'] > 0) {
- $statistics['ratio'] = round(($statistics['crashes'] / $statistics['users']), 2);
- } else {
- $statistics['ratio'] = 0.00;
- }
- return $statistics;
- }
- return false;
- }
- /**
- * Returns the correct UI string for the provided OS
- *
- * @param string operating system name
- * @return string correctly formatted OS string
- */
- private function getOSDisplayName($os)
- {
- $formattedOS = "";
- if(stripos($os, "win") !== false) {
- $formattedOS = Kohana::config('platforms.win_name');
- } else if(stripos($os, "mac") !== false) {
- $formattedOS = Kohana::config('platforms.mac_name');
- } else if(stripos($os, "lin") !== false) {
- $formattedOS = Kohana::config('platforms.lin_name');
- } else {
- $formattedOS = "Unsupported OS Name.";
- }
- return $formattedOS;
- }
- /**
- *
- */
- public function calculateOverallTotal($product_data, $report_type='by_version')
- {
- $product_info = array();
- $versions = array();
- $os = array();
- $total_users = 0;
- $total_crashes = 0;
- $ratio = 0.00;
- // Extract the version data
- foreach (get_object_vars($product_data) as $key => $data) {
- $current_key = explode(':', $key);
- if($report_type != 'by_os') {
- array_push($versions, $current_key[1]);
- } else {
- array_push($os, $this->getOSDisplayName($current_key[2]));
- }
- $product_info = $data;
- }
- // Loop through all items and total up the amounts
- foreach ($product_info as $key => $current_item) {
- $ratio += $current_item->crash_hadu;
- $total_crashes += $current_item->report_count;
- $total_users += $current_item->adu;
- }
- $statistics['ratio'] = $ratio;
- $statistics['crashes'] = $total_crashes;
- $statistics['users'] = $total_users;
- if($report_type != 'by_os') {
- $statistics['versions'] = $versions;
- } else {
- $statistics['os'] = $os;
- }
- if ($statistics['crashes'] > 0 && $statistics['users'] > 0) {
- $statistics['ratio'] = round(($statistics['crashes'] / $statistics['users']), 2);
- } else {
- $statistics['ratio'] = 0.00;
- }
- return $statistics;
- }
- /**
- *
- */
- public function calculateTotalByVersion($statistics, $version_data)
- {
- // Extract the version data
- foreach (get_object_vars($version_data) as $version => $data) {
- // We only want the version string not including the product name
- $prod_ver = explode(':', $version);
- $key = $prod_ver[1];
- $ratio = 0.00;
- $total_crashes = 0;
- $throttle = 0;
- $total_users = 0;
- $statistics['versions'][$key] = array();
- // Loop through the data for the current version and total up the amounts
- foreach ($data as $date => $current_version) {
- $ratio += $current_version->crash_hadu;
- $total_crashes += $current_version->report_count;
- $throttle = $current_version->throttle;
- $total_users += $current_version->adu;
- if (strtotime($date) < $this->today) {
- if (!isset($statistics['versions'][$key][$date])) {
- $statistics['versions'][$key][$date] = array(
- 'crashes' => $current_version->report_count,
- 'users' => $current_version->adu,
- 'ratio' => $current_version->crash_hadu,
- 'throttle' => $current_version->throttle,
- );
- }
- }
- }
- $statistics['versions'][$key]['ratio'] = $ratio;
- $statistics['versions'][$key]['crashes'] = $total_crashes;
- $statistics['versions'][$key]['throttle'] = $throttle;
- $statistics['versions'][$key]['users'] = $total_users;
- $statistics['versions'][$key]['version'] = $key;
- }
- return $statistics;
- }
- /**
- *
- */
- public function calculateTotalByOS($statistics, $os_data)
- {
- // Extract the OS data
- foreach (get_object_vars($os_data) as $os => $data) {
- $prod_ver_os = explode(':', $os);
- $key = $this->getOSDisplayName($prod_ver_os[2]);
- $ratio = 0.00;
- $total_crashes = 0;
- $throttle = 0;
- $total_users = 0;
- $statistics['os'][$key] = array();
- foreach ($data as $date => $current_os) {
- $ratio += $current_os->crash_hadu;
- $total_crashes += $current_os->report_count;
- $throttle = $current_os->throttle;
- $total_users += $current_os->adu;
- if (!isset($statistics['os'][$key][$date])) {
- $statistics['os'][$key][$date] = array(
- 'crashes' => $current_os->report_count,
- 'users' => $current_os->adu,
- 'ratio' => $current_os->crash_hadu,
- 'throttle' => $current_os->throttle,
- );
- if ($statistics['os'][$key][$date]['crashes'] > 0 && $statistics['os'][$key][$date]['users'] > 0) {
- $statistics['os'][$key][$date]['ratio'] = $statistics['os'][$key][$date]['crashes'] / $statistics['os'][$key][$date]['users'];
- } else {
- $statistics['os'][$key][$date]['ratio'] = 0.00;
- }
- }
- }
- $statistics['os'][$key]['ratio'] = $ratio;
- $statistics['os'][$key]['crashes'] = $total_crashes;
- $statistics['os'][$key]['throttle'] = $throttle;
- $statistics['os'][$key]['users'] = $total_users;
- $statistics['os'][$key]['os'] = $key;
- }
- return $statistics;
- }
- /**
- *
- */
- public function calculateStatistics($results, $report_type)
- {
- $statistics = $this->calculateOverallTotal($results, $report_type);
- if ($report_type == 'by_version') {
- $statistics = $this->calculateTotalByVersion($statistics, $results);
- } elseif ($report_type == 'by_os') {
- $statistics = $this->calculateTotalByOS($statistics, $results);
- }
- return $statistics;
- }
- /**
- * Prepare the statistics for Crashes per ADU by Version.
- *
- * The idea of throttled users were implemented in Socorro 1.5 - https://bugzilla.mozilla.org/show_bug.cgi?id=539337
- *
- * Throttling is inputted into the UI. It is an effective throttling of client throttling * server throttling. Reported
- * Active Daily Users are updated according to throttling percentages.
- *
- * @access public
- * @param object The response object from the API call
- * @param array An array of effective throttle rates for each version
- * @return array An array of statistics
- */
- public function calculateStatisticsByVersion ($results, $throttle)
- {
- if (!empty($results)) {
- $this->calculateTotalForProduct($results);
- $statistics = array(
- 'ratio' => 0.00,
- 'crashes' => 0,
- 'versions' => array(),
- 'users' => 0,
- );
- foreach ($results as $key => $version_data) {
- if (!empty($throttle)) {
- $t = array_shift($throttle);
- $throttle_1 = ($t > 0) ? ($t / 100) : 1;
- $throttle_2 = 1 - $throttle_1;
- $throttle_ratio = $throttle_2 / $throttle_1;
- } else {
- $throttle_1 = 1;
- $throttle_2 = 0;
- $throttle_ratio = 0;
- }
- $statistics['versions'][$key] = array(
- 'ratio' => 0.00,
- 'crashes' => 0,
- 'throttle' => $throttle_1,
- 'users' => 0,
- 'version' => $key,
- );
- foreach ($version->statistics as $v) {
- $date = $v->date;
- if (strtotime($date) < $this->today) {
- if (!isset($statistics['versions'][$key][$date])) {
- $statistics['versions'][$key][$date] = array(
- 'crashes' => 0,
- 'users' => 0,
- 'ratio' => 0.00,
- );
- }
- $throttled_crashes = $v->crashes;
- if ($throttle_ratio > 0) {
- $throttled_crashes += ($v->crashes * $throttle_ratio);
- }
- $statistics['versions'][$key][$date]['crashes'] += $throttled_crashes;
- $statistics['versions'][$key][$date]['throttle'] = $throttle_1;
- $statistics['versions'][$key][$date]['users'] += $v->users;
- if ($statistics['versions'][$key][$date]['crashes'] > 0 && $statistics['versions'][$key][$date]['users'] > 0) {
- $statistics['versions'][$key][$date]['ratio'] = $statistics['versions'][$key][$date]['crashes'] / $statistics['versions'][$key][$date]['users'];
- } else {
- $statistics['versions'][$key][$date]['ratio'] = 0.00;
- }
- $statistics['crashes'] += $throttled_crashes;
- $statistics['users'] += $v->users;
- $statistics['versions'][$key]['crashes'] += $throttled_crashes;
- $statistics['versions'][$key]['users'] += $v->users;
- }
- }
- if ($statistics['versions'][$key]['crashes'] > 0 && $statistics['versions'][$key]['users'] > 0) {
- $statistics['versions'][$key]['ratio'] = $statistics['versions'][$key]['crashes'] / $statistics['versions'][$key]['users'];
- } else {
- $statistics['versions'][$key]['ratio'] = 0.00;
- }
- }
- if ($statistics['crashes'] > 0 && $statistics['users'] > 0) {
- $statistics['ratio'] = $statistics['crashes'] / $statistics['users'];
- } else {
- $statistics['ratio'] = 0.00;
- }
- return $statistics;
- }
- return false;
- }
- /**
- * Prepare an array of parameters for the url.
- *
- * @access private
- * @param array The array that needs to be parameterized.
- * @return string The url-encoded string.
- */
- private function encodeArray (array $parameters) {
- $uri = '';
- $parameters = array_unique($parameters);
- $num_parameters = count($parameters);
- for ($i = 0; $i <= $num_parameters; $i++) {
- $parameter = array_shift($parameters);
- if (!empty($parameter)) {
- if ($i > 0) {
- $uri .= ";";
- }
- $uri .= rawurlencode($parameter);
- }
- }
- return $uri;
- }
- /**
- * Format the URL for the ADU web service call.
- *
- * @access private
- * @param string The product name (e.g. 'Camino', 'Firefox', 'Seamonkey, 'Thunderbird')
- * @param string The version number (e.g. '3.5', '3.5.1', '3.5.1pre', '3.5.2', '3.5.2pre')
- * @param string The Report Type [any|crash|hang]
- * @param string The start date for this product YYYY-MM-DD
- * @param string The end date for this product YYYY-MM-DD (usually +90 days)
- * @return string The URL.
- */
- private function formatURL ($api, $product, $versions, $hang_type, $operating_systems, $start_date, $end_date) {
- $host = Kohana::config('webserviceclient.socorro_hostname');
- $p = rawurlencode($product);
- $v = $this->encodeArray($versions);
- $os = $this->encodeArray($operating_systems);
- $start = rawurlencode($start_date);
- $end = rawurlencode($end_date);
- $url = $host . $api . $p . "/v/" . $v . "/rt/" . $hang_type . "/os/" . $os . "/start/" . $start . "/end/" . $end;
- return $url;
- }
- /**
- * Format the URL for the ADU web service call.
- *
- * @access private
- * @param string The product name (e.g. 'Camino', 'Firefox', 'Seamonkey, 'Thunderbird')
- * @param string The version number (e.g. '3.5', '3.5.1', '3.5.1pre', '3.5.2', '3.5.2pre')
- * @param string The Report Type [any|crash|hang]
- * @param string The start date for this product YYYY-MM-DD
- * @param string The end date for this product YYYY-MM-DD (usually +90 days)
- * @return string The URL.
- */
- private function formatADUOverviewURL ($product, $versions, $hang_type, $operating_systems, $start_date, $end_date) {
- return $this->formatURL("/adu/byday/p/", $product, $versions, $hang_type, $operating_systems, $start_date, $end_date);
- }
- /**
- * Format the URL for the aduByDayDetails web service call.
- *
- * @access private
- * @param string The product name (e.g. 'Camino', 'Firefox', 'Seamonkey, 'Thunderbird')
- * @param string The version number (e.g. '3.5', '3.5.1', '3.5.1pre', '3.5.2', '3.5.2pre')
- * @param array The Report Types
- * @param string The start date for this product YYYY-MM-DD
- * @param string The end date for this product YYYY-MM-DD (usually +90 days)
- * @return string The URL.
- */
- private function formatADUDetailsByReportTypeURL ($product, $versions, $report_types, $operating_systems, $start_date, $end_date) {
- $rt = $this->encodeArray($report_types);
- return $this->formatURL("/adu/byday/details/p/", $product, $versions, $rt, $operating_systems, $start_date, $end_date);
- }
- private function _sortVersions($versions)
- {
- $sorted_versions_array = array();
- foreach ($versions as $key => $value) {
- array_push($sorted_versions_array, $key);
- }
- usort($sorted_versions_array, function ($a, $b) {
- return ($a > $b) ? -1 : 1;
- });
- return $sorted_versions_array;
- }
- private function _sortVersionData($version_data)
- {
- $sorted_version_data_array = array();
- foreach ($version_data as $item) {
- array_push($sorted_version_data_array, $item);
- }
- usort($sorted_version_data_array, function ($a, $b) {
- return ($a->date < $b->date) ? -1 : 1;
- });
- return $sorted_version_data_array;
- }
- /**
- * Build data object for front page graph.
- *
- * @access public
- * @param string The start date for this product YYYY-MM-DD
- * @param string The end date for this product YYYY-MM-DD
- * @param object The individual items from which we extract the ratios for the graph
- * @return array The compiled data for the front page graph
- */
- public function buidDataObjectForGraph($date_start=null, $date_end=null, $response_items=null, $report_type='by_version')
- {
- $count = count(get_object_vars($response_items));
- $counter = 1;
- $cadu = array();
- $data = array(
- 'startDate' => $date_start,
- 'endDate' => $date_end,
- 'count' => $count,
- );
- foreach ($response_items as $version => $version_data) {
- if ($counter <= $count) {
- $key_ratio = 'ratio' . $counter;
- $cadu[$key_ratio] = array();
- array_push($cadu[$key_ratio], $version);
- $version_data_array = $this->_sortVersionData($version_data);
- foreach ($version_data_array as $details) {
- if(strtotime($details->date) < $this->today) {
- array_push($cadu[$key_ratio], array(strtotime($details->date) * 1000, $details->crash_hadu));
- }
- }
- }
- $counter++;
- }
- $data['cadu'] = $cadu;
- usort($data['cadu'], function ($a, $b) {
- return ($a[0] > $b[0]) ? -1 : 1;
- });
- return $data;
- }
- private function _buildDataObjectForCrashReports($response_items)
- {
- $crashReports = array();
- $prod_ver = array();
- $version_array = $this->_sortVersions($response_items);
- foreach ($version_array as $version) {
- if (strrpos($version, ":")) {
- $products_versions = explode(":", $version);
- }
- $prod_ver['product'] = $products_versions[0];
- $prod_ver['version'] = $products_versions[1];
- array_push($crashReports, $prod_ver);
- }
- return $crashReports;
- }
- /**
- * Build the service URI from the paramters passed and returns the URI with
- * all values rawurlencoded.
- *
- * @param array url parameters to append and encode
- * @param string the main api entry point ex. crashes
- * @return string service URI with all values encoded
- */
- public function buildURI($params, $apiEntry)
- {
- $separator = "/";
- $host = Kohana::config('webserviceclient.socorro_hostname');
- $apiData = array(
- $host,
- $apiEntry
- );
- foreach ($params as $key => $value) {
- $apiData[] = $key;
- $apiData[] = (is_array($value) ? $this->encodeArray($value) : rawurlencode($value));
- }
- $apiData[] = ''; // Trick to have the closing '/'
- return implode($separator, $apiData);
- }
- /**
- * Fetch records for active daily users.
- *
- * @access public
- * @param string The product name (e.g. 'Camino', 'Firefox', 'Seamonkey, 'Thunderbird')
- * @param string The versions for this product
- * @param string The start date for this product YYYY-MM-DD
- * @param string The end date for this product YYYY-MM-DD
- * @param string The date range for which to fetch record. Should be either 'build' or 'report'
- * @param string The string of operating systems selected for this report.
- * @param string The hang type selected for this report. Can be one of crash, oopp, hang browser, hang plugin
- * @param string The report type selectd, can be one of by_version, by_os, by_report_type
- * @return array The compiled data for the front page graph or Crashes per ADU
- */
- public function getCrashesPerADU($product=null, $versions=null, $start_date=null, $end_date=null,
- $date_range_type=null, $operating_systems=null, $report_types=null, $form_selection='by_version')
- {
- $graph_data = array();
- $isDataForGraph = TRUE;
- $params['product'] = $product;
- $params['versions'] = $versions;
- $params['from_date'] = $start_date;
- $params['to_date'] = $end_date;
- $params['date_range_type'] = $date_range_type;
- if ($operating_systems != null) {
- $isDataForGraph = FALSE;
- $params['os'] = $operating_systems;
- // Operating systems can be specified for by version as well but,
- // we only want to separate the results by OS if the selected,
- // report type was by_os.
- if($form_selection == 'by_os') {
- $params['separated_by'] = 'os';
- }
- }
- if ($report_types != null) {
- $params['report_type'] = $report_types;
- }
- $url = $this->buildURI($params, "crashes/daily");
- $lifetime = Kohana::config('webserviceclient.topcrash_vers_rank_cache_minutes', 60) * 60; // number of seconds
- $response = $this->service->get($url, 'json', $lifetime);
- if (isset($response) && !empty($response)) {
- // If true, data is for the frontpage
- if ($isDataForGraph) {
- $graph_data = $this->buidDataObjectForGraph($start_date, $end_date, $response->hits);
- $graph_data['productVersions'] = $this->_buildDataObjectForCrashReports($response->hits);
- return $graph_data;
- }
- return $response;
- }
- return false;
- }
- /**
- * Fetch records for active daily users / installs by crash report type
- *
- * @access public
- * @param string The product name (e.g. 'Camino', 'Firefox', 'Seamonkey, 'Thunderbird')
- * @param array An array of versions of this product
- * @param array An array of operating systems to query
- * @param array The Report Type [crash|oopp|hang_browser|hang_plugin]
- * @param string The start date for this product YYYY-MM-DD
- * @param string The end date for this product YYYY-MM-DD (usually +90 days)
- * @return object The database query object
- */
- public function getDetailsByReportType($product, $versions, $operating_systems, $report_types, $start_date, $end_date) {
- $url = $this->formatADUDetailsByReportTypeURL($product, $versions, $report_types, $operating_systems, $start_date, $end_date);
- $lifetime = Kohana::config('webserviceclient.topcrash_vers_rank_cache_minutes', 60) * 60; // number of seconds
- $response = $this->service->get($url, 'json', $lifetime);
- if (isset($response) && !empty($response)) {
- return $response;
- } else {
- Kohana::log('error', "No ADU data was avialable at \"$url\" via soc.web daily.getDetailsByReportType()");
- }
- return false;
- }
- /**
- * Fetch records for active daily users / installs.
- *
- * @access public
- * @param string The product name (e.g. 'Camino', 'Firefox', 'Seamonkey, 'Thunderbird')
- * @param array An array of versions of this product
- * @param array An array of operating systems to query
- * @param string The start date for this product YYYY-MM-DD
- * @param string The end date for this product YYYY-MM-DD (usually +90 days)
- * @return object The database query object
- * @param string The Report Type [any|crash|hang] - defaults to 'any'
- */
- public function get($product, $versions, $operating_systems, $start_date, $end_date, $hang_type='any') {
- $url = $this->formatADUOverviewURL($product, $versions, $hang_type, $operating_systems, $start_date, $end_date);
- $lifetime = Kohana::config('webserviceclient.topcrash_vers_rank_cache_minutes', 60) * 60; // number of seconds
- $response = $this->service->get($url, 'json', $lifetime);
- if (isset($response) && !empty($response)) {
- return $response;
- } else {
- Kohana::log('error', "No ADU data was avialable at \"$url\" via soc.web daily.get()");
- }
- return false;
- }
-
- /**
- * Get version information that includes throttle level from products_versions service
- *
- * @access public
- * @param string The product
- * @param string The version number
- * @return object The JSON result
- */
- public function getVersionInfo($product, $versions) {
- $host = Kohana::config('webserviceclient.socorro_hostname');
- $p = rawurlencode($product);
- $v = $this->encodeArray($versions);
- $url = $host . "/products/versions/" . $p . ":" . $v;
-
- $lifetime = Kohana::config('webserviceclient.topcrash_vers_rank_cache_minutes', 60) * 60;
- $response = $this->service->get($url, 'json', $lifetime);
- return $response;
- }
- /**
- * Prepare the data for the crash graph for ADU by Operating System.
- *
- * @access public
- * @param string The start date for this product YYYY-MM-DD
- * @param string The end date for this product YYYY-MM-DD (usually +90 days)
- * @param array An array of dates
- * @param array An array of operating_systems
- * @param array An array of statistics
- * @return array The array prepared for the crash data graph
- */
- public function prepareCrashGraphDataByOS($date_start, $date_end, $dates, $operating_systems, $statistics) {
- if (!empty($statistics)) {
- $data = array(
- 'startDate' => $date_start,
- 'endDate' => $date_end,
- 'count' => count($operating_systems),
- );
- for($i = 1; $i <= $data['count']; $i++) {
- $key_ratio = 'ratio' . $i;
- $key_item = 'item' . $i;
- $item = substr(array_shift($operating_systems), 0, 3);
- $data[$key_item] = $item;
- $data[$key_ratio] = array();
- foreach ($dates as $date) {
- if (strtotime($date) < $this->today) {
- if (isset($statistics['os'][$item][$date])) {
- array_push($data[$key_ratio], array(strtotime($date)*1000, $statistics['os'][$item][$date]['ratio'] * 100));
- } else {
- array_push($data[$key_ratio], array(strtotime($date)*1000, null));
- }
- }
- }
- }
- return $data;
- }
- return false;
- }
- /**
- * Prepare the data for the crash graph for ADU by Version.
- *
- * @access public
- * @param string The start date for this product YYYY-MM-DD
- * @param string The end date for this product YYYY-MM-DD (usually +90 days)
- * @param array An array of dates
- * @param array An array of version numbers
- * @param array An array of statistics
- * @return array The array prepared for the crash data graph
- */
- public function prepareCrashGraphDataByVersion($date_start, $date_end, $dates, $versions, $statistics) {
- if (!empty($statistics)) {
- $data = array(
- 'startDate' => $date_start,
- 'endDate' => $date_end,
- 'count' => count($versions),
- );
- for($i = 1; $i <= $data['count']; $i++) {
- $key_ratio = 'ratio' . $i;
- $key_item = 'item' . $i;
- $item = array_shift($versions);
- $data[$key_item] = $item;
- $data[$key_ratio] = array();
- foreach ($dates as $date) {
- if (strtotime($date) < $this->today) {
- if (isset($statistics['versions'][$item][$date])) {
- array_push($data[$key_ratio], array(strtotime($date)*1000, $statistics['versions'][$item][$date]['ratio'] * 100));
- } else {
- array_push($data[$key_ratio], array(strtotime($date)*1000, null));
- }
- }
- }
- }
- return $data;
- }
- return false;
- }
- /**
- * Prepare the data for the crash graph for ADU by Operating System.
- *
- * What we want to create is
- [
- { 'label': '3.6.4 Crash Ratio',
- 'data': [[123456777, 2.2], [1234545645, 2.3]...]},
- ...
- ]
- *
- * @access public
- * @param string The start date for this product YYYY-MM-DD
- * @param string The end date for this product YYYY-MM-DD (usually +90 days)
- * @param array An array of dates
- * @param array An array of operating_systems
- * @param array An array of statistics
- * @return array The array prepared for the crash data graph
- */
- public function prepareCrashGraphDataByReportType($date_start, $date_end, $dates, $versions, $statistics) {
- if (!empty($statistics)) {
- $data = array();
- $keys = $this->statistic_keys($statistics, $dates);
- foreach($versions as $version) {
- $label = "$version Crash %";
- $ratio_data = array();
- $oopp_ratio_data = array();
- $hang_browser_ratio_data = array();
- $hang_plugin_ratio_data = array();
- foreach ($dates as $date) {
- if (strtotime($date) < $this->today) {
- if (in_array('crash', $keys)) {
- if (isset($statistics['versions'][$version][$date])) {
- array_push($ratio_data, array(strtotime($date)*1000, $statistics['versions'][$version][$date]['crash_ratio'] * 100));
- } else {
- array_push($ratio_data, array(strtotime($date)*1000, null));
- }
- }
- if (in_array('oopp', $keys)) {
- if (isset($statistics['versions'][$version][$date])) {
- array_push($oopp_ratio_data, array(strtotime($date)*1000, $statistics['versions'][$version][$date]['oopp_ratio'] * 100));
- } else {
- array_push($oopp_ratio_data, array(strtotime($date)*1000, null));
- }
- }
- if (in_array('hang_browser', $keys)) {
- if (isset($statistics['versions'][$version][$date])) {
- array_push($hang_browser_ratio_data, array(strtotime($date)*1000, $statistics['versions'][$version][$date]['hang_browser_ratio'] * 100));
- } else {
- array_push($hang_browser_ratio_data, array(strtotime($date)*1000, null));
- }
- }
- if (in_array('hang_plugin', $keys)) {
- if (isset($statistics['versions'][$version][$date])) {
- array_push($hang_plugin_ratio_data, array(strtotime($date)*1000, $statistics['versions'][$version][$date]['hang_plugin_ratio'] * 100));
- } else {
- array_push($hang_plugin_ratio_data, array(strtotime($date)*1000, null));
- }
- }
- }
- }
- if (in_array('crash', $keys)) {
- array_push($data, array('label' => "$version Crash %",
- 'data' => $ratio_data));
- }
- if (in_array('oopp', $keys)) {
- array_push($data, array('label' => "$version OOPP %",
- 'data' => $oopp_ratio_data));
- }
- if (in_array('hang_browser', $keys)) {
- array_push($data, array('label' => "$version Hang B %",
- 'data' => $hang_browser_ratio_data));
- }
- if (in_array('hang_plugin', $keys)) {
- array_push($data, array('label' => "$version Hang P%",
- 'data' => $hang_plugin_ratio_data));
- }
- }
- return $data;
- }
- return false;
- }
- /**
- * Prepare the dates that will be used for statistic collection.
- *
- * @param string The end date
- * @param int The number of dates to query
- * @return array
- */
- public function prepareDates($date_end, $duration) {
- $dates = array();
- $date_diff = TimeUtil::determineDayDifferential($date_end, date('Y-m-d', mktime(0, 0, 0, date("m"), date("d"), date("Y"))));
- $timestamp = time();
- for($i = 0; $i <= $duration; $i++) {
- $date = date('Y-m-d', mktime(0, 0, 0, date("m"), date("d")-($i+$date_diff), date("Y")));
- if (strtotime($date) <= $timestamp) {
- $dates[] = $date;
- }
- }
- return $dates;
- }
- /**
- * Prepare the Crash Data for the Crash Graphs.
- *
- * @param array The array of crash data statistics
- * @param string The graph type, whether reporting by version or by O/S
- * @param string The start date
- * @param string The end date
- * @param array The array of O/S that will be reported
- * @param array The array of versions that will be reported
- * @return array
- */
- public function prepareGraphData($statistics, $form_selection='by_version', $date_start, $date_end, $dates, $operating_systems=null, $versions=null)
- {
- $graph_data = null;
- if ($form_selection == 'by_version') {
- $graph_data = $this->prepareCrashGraphDataByVersion($date_start, $date_end, $dates, $versions, $statistics);
- } elseif ($form_selection == 'by_os') {
- $graph_data = $this->prepareCrashGraphDataByOS($date_start, $date_end, $dates, $operating_systems, $statistics);
- } elseif ($form_selection == 'by_report_type') {
- $graph_data = $this->prepareCrashGraphDataByReportType($date_start, $date_end, $dates, $versions, $statistics);
- }
- return $graph_data;
- }
- /**
- * Prepare the Crash Data for the Crash Graphs.
- *
- * @param array The array of crash stats data results
- * @param string The graph type, whether reporting by version or by O/S
- * @param string The product name
- * @param array An array of versions
- * @param array An array of operating systems
- * @param string The start date
- * @param string The end date
- * @param array An array of effective throttling rates for each version
- * @return array The array of crash stats data statistics
- */
- public function prepareStatistics($results, $form_selection='by_version', $product, $versions, $operating_system, $date_start, $date_end, $throttle) {
- $statistics = null;
- if ($form_selection == 'by_version') {
- $statistics = (!empty($results)) ? $this->calculateStatisticsByVersion($results, $throttle) : null;
- } elseif ($form_selection == 'by_os') {
- $statistics = (!empty($results)) ? $this->calculateStatisticsByOS($results, $throttle) : null;
- } elseif ($form_selection == 'by_report_type') {
- $statistics = (!empty($results)) ? $this->calculateStatisticsByReportType($results, $throttle) : null;
- }
- return $statistics;
- }
- /**
- * Given a set of statistics and dates determine which report_types are present.
- *
- * @param $statistics array
- * @param $dates array
- *
- * @return array of report types
- */
- public function statistic_keys($statistics, $dates)
- {
- $keys = array();
- if (is_null($statistics)) {
- return $keys;
- }
- foreach ($dates as $date) {
- if (isset($statistics['versions']) && !empty($statistics['versions'])) {
- foreach ($statistics['versions'] as $version) {
- if (isset($version[$date]) &&
- ( isset($version[$date]['crash_ratio']) ||
- isset($version[$date]['oopp_ratio']) ||
- isset($version[$date]['hang_browser_ratio']) ||
- isset($version[$date]['hang_plugin_ratio']))) {
- $stats = $version[$date];
- if (array_key_exists('crash_ratio', $stats)) {
- array_push($keys, 'crash');
- }
- if (array_key_exists('oopp_ratio', $stats)) {
- array_push($keys, 'oopp');
- }
- if (array_key_exists('hang_browser_ratio', $stats)) {
- array_push($keys, 'hang_browser');
- }
- if (array_key_exists('hang_plugin_ratio', $stats)) {
- array_push($keys, 'hang_plugin');
- }
- return $keys;
- }
- }
- }
- }
- return $keys;
- }
- }