PageRenderTime 76ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/application/models/stats.php

https://github.com/jasonmule/Ushahidi_Web
PHP | 294 lines | 195 code | 51 blank | 48 comment | 41 complexity | 20f1cc7354fe5524b5c7de344ad7637e MD5 | raw file
  1. <?php defined('SYSPATH') or die('No direct script access.');
  2. /**
  3. * Model for Statistics
  4. *
  5. *
  6. * PHP version 5
  7. * LICENSE: This source file is subject to LGPL license
  8. * that is available through the world-wide-web at the following URI:
  9. * http://www.gnu.org/copyleft/lesser.html
  10. * @author Ushahidi Team <team@ushahidi.com>
  11. * @package Ushahidi - http://source.ushahididev.com
  12. * @module Incident Model
  13. * @copyright Ushahidi - http://www.ushahidi.com
  14. * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License (LGPL)
  15. */
  16. class Stats_Model extends ORM
  17. {
  18. /*
  19. * range will be ignored if dp1 and dp2 are set
  20. * dp1 and dp2 format is YYYY-MM-DD
  21. */
  22. static function get_hit_stats($range=30,$dp1=null,$dp2=null)
  23. {
  24. // Get ID for stats
  25. $settings = ORM::factory('settings', 1);
  26. $stat_id = $settings->stat_id;
  27. $twodates = '';
  28. if($dp1 !== null && $dp2 !== null) {
  29. $twodates = '&twodates='.urlencode($dp1.','.$dp2);
  30. }
  31. $stat_url = 'http://tracker.ushahidi.com/px.php?stat_key='.$settings->stat_key.'&task=stats&siteid='.urlencode($stat_id).'&period=day&range='.urlencode($range).$twodates;
  32. $response = simplexml_load_string(self::_curl_req($stat_url));
  33. // If we encounter an error, return false
  34. if(isset($response->result->error[0]) || isset($response->error[0]) || !isset($response->visits->result)) {
  35. Kohana::log('error', "Error on stats request");
  36. return false;
  37. }
  38. foreach($response->visits->result as $res) {
  39. $dt = $res['date'];
  40. $y = substr($dt,0,4);
  41. $m = substr($dt,5,2);
  42. $d = substr($dt,8,2);
  43. $timestamp = mktime(0,0,0,$m,$d,$y)*1000;
  44. if(isset($res->nb_visits)){
  45. $data['visits'][(string)$timestamp] = (string)$res->nb_visits;
  46. }else{
  47. $data['visits'][(string)$timestamp] = '0';
  48. }
  49. if(isset($res->nb_uniq_visitors)){
  50. $data['uniques'][(string)$timestamp] = (string)$res->nb_uniq_visitors;
  51. }else{
  52. $data['uniques'][(string)$timestamp] = '0';
  53. }
  54. if(isset($res->nb_actions)){
  55. $data['pageviews'][(string)$timestamp] = (string)$res->nb_actions;
  56. }else{
  57. $data['pageviews'][(string)$timestamp] = '0';
  58. }
  59. }
  60. return $data;
  61. }
  62. static function get_hit_countries($range=30,$dp1=null,$dp2=null)
  63. {
  64. $settings = ORM::factory('settings', 1);
  65. $stat_id = $settings->stat_id;
  66. $twodates = '';
  67. if($dp1 !== null && $dp2 !== null) {
  68. $twodates = '&twodates='.urlencode($dp1.','.$dp2);
  69. }
  70. $stat_url = 'http://tracker.ushahidi.com/px.php?stat_key='.$settings->stat_key.'&task=stats&siteid='.urlencode($stat_id).'&period=day&range='.urlencode($range).$twodates;
  71. $response = simplexml_load_string(self::_curl_req($stat_url));
  72. // If we encounter an error, return false
  73. if(isset($response->result->error[0]) || isset($response->error[0]) || !isset($response->countries->result)) {
  74. Kohana::log('error', "Error on stats request");
  75. return false;
  76. }
  77. $data = array();
  78. foreach($response->countries->result as $res) {
  79. $date = (string)$res['date'];
  80. foreach($res->row as $row){
  81. $code = (string)$row->code;
  82. $data[$date][$code]['label'] = (string)$row->label;
  83. $data[$date][$code]['uniques'] = (string)$row->nb_uniq_visitors;
  84. $data[$date][$code]['logo'] = 'http://tracker.ushahidi.com/piwik/'.(string)$row->logo;
  85. }
  86. }
  87. return $data;
  88. }
  89. /*
  90. * get an array of report counts
  91. * @param approved - Only count approved reports if true
  92. * @param by_time - Format array with timestamp as the key if true
  93. * @param range - Number of days back from today to pull reports from. Will end up defaulting to 100000 days to get them all.
  94. * @param dp1 - Arbitrary date range. Low date. YYYY-MM-DD
  95. * @param dp2 - Arbitrary date range. High date. YYYY-MM-DD
  96. */
  97. static function get_report_stats($approved=false,$by_time=false,$range=null,$dp1=null,$dp2=null,$line_chart_data=false)
  98. {
  99. if($range === null) $range = 100000;
  100. if($dp1 === null) $dp1 = 0;
  101. if($dp2 === null) $dp2 = '3000-01-01';
  102. // Set up the range calculation
  103. $time = time() - ($range*86400);
  104. $range_date = date('Y-m-d',$time);
  105. // Only grab approved
  106. if($approved) {
  107. $reports = ORM::factory('incident')->where('incident_active','1')->where('incident_date >=',$dp1)->where('incident_date <=',$dp2)->where('incident_date >',$range_date)->find_all();
  108. }else{
  109. $reports = ORM::factory('incident')->where('incident_date >=',$dp1)->where('incident_date <=',$dp2)->where('incident_date >',$range_date)->find_all();
  110. }
  111. $reports_categories = ORM::factory('incident_category')->find_all();
  112. // Initialize arrays so we don't error out
  113. $report_data = array();
  114. $verified_counts = array();
  115. $approved_counts = array();
  116. $all = array();
  117. $earliest_timestamp = 32503680000; // Year 3000 in epoch so we can catch everything less than this.
  118. $latest_timestamp = 0;
  119. // Gather some data into an array on incident reports
  120. $num_reports = 0;
  121. foreach($reports as $report) {
  122. $timestamp = (string)strtotime(substr($report->incident_date,0,10));
  123. $report_data[$report->id] = array(
  124. 'date'=>$timestamp,
  125. 'mode'=>$report->incident_mode,
  126. 'active'=>$report->incident_active,
  127. 'verified'=>$report->incident_verified
  128. );
  129. if($timestamp < $earliest_timestamp) $earliest_timestamp = $timestamp;
  130. if($timestamp > $latest_timestamp) $latest_timestamp = $timestamp;
  131. if(!isset($verified_counts['verified'][$timestamp])) {
  132. $verified_counts['verified'][$timestamp] = 0;
  133. $verified_counts['unverified'][$timestamp] = 0;
  134. $approved_counts['approved'][$timestamp] = 0;
  135. $approved_counts['unapproved'][$timestamp] = 0;
  136. $all[$timestamp] = 0;
  137. }
  138. $all[$timestamp]++;
  139. if($report->incident_verified == 1){
  140. $verified_counts['verified'][$timestamp]++;
  141. }else{
  142. $verified_counts['unverified'][$timestamp]++;
  143. }
  144. if($report->incident_active == 1){
  145. $approved_counts['approved'][$timestamp]++;
  146. }else{
  147. $approved_counts['unapproved'][$timestamp]++;
  148. }
  149. $num_reports++;
  150. }
  151. $category_counts = array();
  152. $lowest_date = 9999999999; // Really far in the future.
  153. $highest_date = 0;
  154. foreach($reports_categories as $report){
  155. // if this report category doesn't have any reports (in case we are only
  156. // looking at approved reports), move on to the next one.
  157. if(!isset($report_data[$report->incident_id])) continue;
  158. $c_id = $report->category_id;
  159. $timestamp = $report_data[$report->incident_id]['date'];
  160. if($timestamp < $lowest_date) $lowest_date = $timestamp;
  161. if($timestamp > $highest_date) $highest_date = $timestamp;
  162. if(!isset($category_counts[$c_id][$timestamp])) $category_counts[$c_id][$timestamp] = 0;
  163. $category_counts[$c_id][$timestamp]++;
  164. }
  165. // Populate date range
  166. $date_range = array();
  167. $add_date = $lowest_date;
  168. while($add_date <= $highest_date){
  169. $date_range[] = $add_date;
  170. $add_date += 86400;
  171. }
  172. // Zero out days that don't have a count
  173. foreach($category_counts as &$arr) {
  174. foreach($date_range as $timestamp){
  175. if(!isset($arr[$timestamp])) $arr[$timestamp] = 0;
  176. if(!isset($verified_counts['verified'][$timestamp])) $verified_counts['verified'][$timestamp] = 0;
  177. if(!isset($verified_counts['unverified'][$timestamp])) $verified_counts['unverified'][$timestamp] = 0;
  178. if(!isset($approved_counts['approved'][$timestamp])) $approved_counts['approved'][$timestamp] = 0;
  179. if(!isset($approved_counts['unapproved'][$timestamp])) $approved_counts['unapproved'][$timestamp] = 0;
  180. if(!isset($all[$timestamp])) $all[$timestamp] = 0;
  181. }
  182. // keep dates in order
  183. ksort($arr);
  184. ksort($verified_counts['verified']);
  185. ksort($verified_counts['unverified']);
  186. ksort($approved_counts['approved']);
  187. ksort($approved_counts['unapproved']);
  188. ksort($all);
  189. }
  190. // Add all our data sets to the array we are returning
  191. $data['category_counts'] = $category_counts;
  192. $data['verified_counts'] = $verified_counts;
  193. $data['approved_counts'] = $approved_counts;
  194. $data['all']['all'] = $all;
  195. // I'm just tacking this on here. However, we could improve performance
  196. // by implementing the code above but I just don't have the time
  197. // to mess with it.
  198. if($by_time){
  199. // Reorder the array. Is there a built in PHP function that can do this?
  200. $new_data = array();
  201. foreach($data as $main_key => $data_array){
  202. foreach($data_array as $key => $counts){
  203. if($line_chart_data == false){
  204. foreach($counts as $timestamp => $count) $new_data[$main_key][$timestamp][$key] = $count;
  205. }else{
  206. foreach($counts as $timestamp => $count){
  207. $timestamp_key = (string)($timestamp*1000);
  208. if(!isset($new_data[$main_key][$timestamp_key])) $new_data[$main_key][$timestamp_key] = 0;
  209. $new_data[$main_key][$timestamp_key] += $count;
  210. }
  211. }
  212. }
  213. }
  214. $data = $new_data;
  215. }
  216. if($line_chart_data == false) {
  217. $data['total_reports'] = $num_reports;
  218. $data['total_categories'] = count($category_counts);
  219. $data['earliest_report_time'] = $earliest_timestamp;
  220. $data['latest_report_time'] = $latest_timestamp;
  221. }
  222. return $data;
  223. }
  224. /**
  225. * Helper function to send a cURL request
  226. * @param url - URL for cURL to hit
  227. */
  228. public function _curl_req( $url )
  229. {
  230. // Make sure cURL is installed
  231. if (!function_exists('curl_exec')) {
  232. throw new Kohana_Exception('stats.cURL_not_installed');
  233. return false;
  234. }
  235. $curl_handle = curl_init();
  236. curl_setopt($curl_handle,CURLOPT_URL,$url);
  237. curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,15); // Timeout set to 15 seconds. This is somewhat arbitrary and can be changed.
  238. curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1); //Set curl to store data in variable instead of print
  239. $buffer = curl_exec($curl_handle);
  240. curl_close($curl_handle);
  241. return $buffer;
  242. }
  243. }