PageRenderTime 54ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/includes/functions-infos.php

https://gitlab.com/Slind/YOURLS
PHP | 339 lines | 209 code | 50 blank | 80 comment | 41 complexity | ef1a98d25ad08c31d132727df92071d3 MD5 | raw file
  1. <?php
  2. /**
  3. * Echoes an image tag of Google Charts map from sorted array of 'country_code' => 'number of visits' (sort by DESC)
  4. *
  5. */
  6. function yourls_stats_countries_map( $countries, $id = null ) {
  7. yourls_do_action( 'pre_stats_countries_map' );
  8. // if $id is null then assign a random string
  9. if( $id === null )
  10. $id = uniqid ( 'yourls_stats_map_' );
  11. $data = array_merge( array( 'Country' => 'Hits' ), $countries );
  12. $data = yourls_google_array_to_data_table( $data );
  13. $options = array(
  14. 'backgroundColor' => "white",
  15. 'colorAxis' => "{colors:['A8D0ED','99C4E4','8AB8DB','7BACD2','6BA1C9','5C95C0','4D89B7','3E7DAE','2E72A5','1F669C']}",
  16. 'width' => "550",
  17. 'height' => "340",
  18. 'theme' => 'maximized'
  19. );
  20. $options = yourls_apply_filter( 'stats_countries_map_options', $options );
  21. $map = yourls_google_viz_code( 'GeoChart', $data, $options, $id );
  22. echo yourls_apply_filter( 'stats_countries_map', $map, $countries, $options, $id );
  23. }
  24. /**
  25. * Echoes an image tag of Google Charts pie from sorted array of 'data' => 'value' (sort by DESC). Optional $limit = (integer) limit list of X first countries, sorted by most visits
  26. *
  27. */
  28. function yourls_stats_pie( $data, $limit = 10, $size = '340x220', $id = null ) {
  29. yourls_do_action( 'pre_stats_pie' );
  30. // if $id is null then assign a random string
  31. if( $id === null )
  32. $id = uniqid ( 'yourls_stats_pie_' );
  33. // Trim array: $limit first item + the sum of all others
  34. if ( count( $data ) > $limit ) {
  35. $i= 0;
  36. $trim_data = array( 'Others' => 0 );
  37. foreach( $data as $item=>$value ) {
  38. $i++;
  39. if( $i <= $limit ) {
  40. $trim_data[$item] = $value;
  41. } else {
  42. $trim_data['Others'] += $value;
  43. }
  44. }
  45. $data = $trim_data;
  46. }
  47. // Scale items
  48. $_data = yourls_scale_data( $data );
  49. list($width, $height) = explode( 'x', $size );
  50. $options = array(
  51. 'theme' => 'maximized',
  52. 'width' => $width,
  53. 'height' => $height,
  54. 'colors' => "['A8D0ED','99C4E4','8AB8DB','7BACD2','6BA1C9','5C95C0','4D89B7','3E7DAE','2E72A5','1F669C']",
  55. 'legend' => 'none',
  56. 'chartArea' => '{top: "5%", height: "90%"}',
  57. 'pieSliceText' => 'label',
  58. );
  59. $options = yourls_apply_filter( 'stats_pie_options', $options );
  60. $script_data = array_merge( array( 'Country' => 'Value' ), $_data );
  61. $script_data = yourls_google_array_to_data_table( $script_data );
  62. $pie = yourls_google_viz_code( 'PieChart', $script_data, $options, $id );
  63. echo yourls_apply_filter( 'stats_pie', $pie, $data, $limit, $size, $options, $id );
  64. }
  65. /**
  66. * Build a list of all daily values between d1/m1/y1 to d2/m2/y2.
  67. *
  68. */
  69. function yourls_build_list_of_days( $dates ) {
  70. /* Say we have an array like:
  71. $dates = array (
  72. 2009 => array (
  73. '08' => array (
  74. 29 => 15,
  75. 30 => 5,
  76. ),
  77. '09' => array (
  78. '02' => 3,
  79. '03' => 5,
  80. '04' => 2,
  81. '05' => 99,
  82. ),
  83. ),
  84. )
  85. */
  86. if( !$dates )
  87. return array();
  88. // Get first & last years from our range. In our example: 2009 & 2009
  89. $first_year = key( $dates );
  90. $_keys = array_keys( $dates );
  91. $last_year = end( $_keys );
  92. reset( $dates );
  93. // Get first & last months from our range. In our example: 08 & 09
  94. $first_month = key( $dates[ $first_year ] );
  95. $_keys = array_keys( $dates[ $last_year ] );
  96. $last_month = end( $_keys );
  97. reset( $dates );
  98. // Get first & last days from our range. In our example: 29 & 05
  99. $first_day = key( $dates[ $first_year ][ $first_month ] );
  100. $_keys = array_keys( $dates[ $last_year ][ $last_month ] );
  101. $last_day = end( $_keys );
  102. unset( $_keys );
  103. // Now build a list of all years (2009), month (08 & 09) and days (all from 2009-08-29 to 2009-09-05)
  104. $list_of_years = array();
  105. $list_of_months = array();
  106. $list_of_days = array();
  107. for ( $year = $first_year; $year <= $last_year; $year++ ) {
  108. $_year = sprintf( '%04d', $year );
  109. $list_of_years[ $_year ] = $_year;
  110. $current_first_month = ( $year == $first_year ? $first_month : '01' );
  111. $current_last_month = ( $year == $last_year ? $last_month : '12' );
  112. for ( $month = $current_first_month; $month <= $current_last_month; $month++ ) {
  113. $_month = sprintf( '%02d', $month );
  114. $list_of_months[ $_month ] = $_month;
  115. $current_first_day = ( $year == $first_year && $month == $first_month ? $first_day : '01' );
  116. $current_last_day = ( $year == $last_year && $month == $last_month ? $last_day : yourls_days_in_month( $month, $year) );
  117. for ( $day = $current_first_day; $day <= $current_last_day; $day++ ) {
  118. $day = sprintf( '%02d', $day );
  119. $key = date( 'M d, Y', mktime( 0, 0, 0, $_month, $day, $_year ) );
  120. $list_of_days[ $key ] = isset( $dates[$_year][$_month][$day] ) ? $dates[$_year][$_month][$day] : 0;
  121. }
  122. }
  123. }
  124. return array(
  125. 'list_of_days' => $list_of_days,
  126. 'list_of_months' => $list_of_months,
  127. 'list_of_years' => $list_of_years,
  128. );
  129. }
  130. /**
  131. * Echoes an image tag of Google Charts line graph from array of values (eg 'number of clicks').
  132. *
  133. * $legend1_list & legend2_list are values used for the 2 x-axis labels. $id is an HTML/JS id
  134. *
  135. */
  136. function yourls_stats_line( $values, $id = null ) {
  137. yourls_do_action( 'pre_stats_line' );
  138. // if $id is null then assign a random string
  139. if( $id === null )
  140. $id = uniqid ( 'yourls_stats_line_' );
  141. // If we have only 1 day of data, prepend a fake day with 0 hits for a prettier graph
  142. if ( count( $values ) == 1 )
  143. array_unshift( $values, 0 );
  144. // Keep only a subset of values to keep graph smooth
  145. $values = yourls_array_granularity( $values, 30 );
  146. $data = array_merge( array( 'Time' => 'Hits' ), $values );
  147. $data = yourls_google_array_to_data_table( $data );
  148. $options = array(
  149. "legend" => "none",
  150. "pointSize" => "3",
  151. "theme" => "maximized",
  152. "curveType" => "function",
  153. "width" => 430,
  154. "height" => 220,
  155. "hAxis" => "{minTextSpacing: 80, maxTextLines: 1, maxAlternation: 1}",
  156. "vAxis" => "{minValue: -0.5, format: '#'}",
  157. "colors" => "['#2a85b3']",
  158. );
  159. $options = yourls_apply_filter( 'stats_line_options', $options );
  160. $lineChart = yourls_google_viz_code( 'LineChart', $data, $options, $id );
  161. echo yourls_apply_filter( 'stats_line', $lineChart, $values, $options, $id );
  162. }
  163. /**
  164. * Return the number of days in a month. From php.net, used if PHP built without calendar functions
  165. *
  166. */
  167. function yourls_days_in_month( $month, $year ) {
  168. // calculate number of days in a month
  169. return $month == 2 ? ( $year % 4 ? 28 : ( $year % 100 ? 29 : ( $year % 400 ? 28 : 29 ) ) ) : ( ( $month - 1 ) % 7 % 2 ? 30 : 31 );
  170. }
  171. /**
  172. * Get max value from date array of 'Aug 12, 2012' = '1337'
  173. *
  174. */
  175. function yourls_stats_get_best_day( $list_of_days ) {
  176. $max = max( $list_of_days );
  177. foreach( $list_of_days as $k=>$v ) {
  178. if ( $v == $max )
  179. return array( 'day' => $k, 'max' => $max );
  180. }
  181. }
  182. /**
  183. * Return domain of a URL
  184. *
  185. */
  186. function yourls_get_domain( $url, $include_scheme = false ) {
  187. $parse = @parse_url( $url ); // Hiding ugly stuff coming from malformed referrer URLs
  188. // Get host & scheme. Fall back to path if not found.
  189. $host = isset( $parse['host'] ) ? $parse['host'] : '';
  190. $scheme = isset( $parse['scheme'] ) ? $parse['scheme'] : '';
  191. $path = isset( $parse['path'] ) ? $parse['path'] : '';
  192. if( !$host )
  193. $host = $path;
  194. if ( $include_scheme && $scheme )
  195. $host = $scheme.'://'.$host;
  196. return $host;
  197. }
  198. /**
  199. * Return favicon URL
  200. *
  201. */
  202. function yourls_get_favicon_url( $url ) {
  203. return yourls_match_current_protocol( 'http://www.google.com/s2/u/0/favicons?domain=' . yourls_get_domain( $url, false ) );
  204. }
  205. /**
  206. * Scale array of data from 0 to 100 max
  207. *
  208. */
  209. function yourls_scale_data( $data ) {
  210. $max = max( $data );
  211. if( $max > 100 ) {
  212. foreach( $data as $k=>$v ) {
  213. $data[$k] = intval( $v / $max * 100 );
  214. }
  215. }
  216. return $data;
  217. }
  218. /**
  219. * Tweak granularity of array $array: keep only $grain values. This make less accurate but less messy graphs when too much values. See http://code.google.com/apis/chart/formats.html#granularity
  220. *
  221. */
  222. function yourls_array_granularity( $array, $grain = 100, $preserve_max = true ) {
  223. if ( count( $array ) > $grain ) {
  224. $max = max( $array );
  225. $step = intval( count( $array ) / $grain );
  226. $i = 0;
  227. // Loop through each item and unset except every $step (optional preserve the max value)
  228. foreach( $array as $k=>$v ) {
  229. $i++;
  230. if ( $i % $step != 0 ) {
  231. if ( $preserve_max == false ) {
  232. unset( $array[$k] );
  233. } else {
  234. if ( $v < $max )
  235. unset( $array[$k] );
  236. }
  237. }
  238. }
  239. }
  240. return $array;
  241. }
  242. /**
  243. * Transform data array to data table for Google API
  244. *
  245. */
  246. function yourls_google_array_to_data_table( $data ){
  247. $str = "var data = google.visualization.arrayToDataTable([\n";
  248. foreach( $data as $label => $values ){
  249. if( !is_array( $values ) ) {
  250. $values = array( $values );
  251. }
  252. $str .= "\t['$label',";
  253. foreach( $values as $value ){
  254. if( !is_numeric( $value ) && strpos( $value, '[' ) !== 0 && strpos( $value, '{' ) !== 0 ) {
  255. $value = "'$value'";
  256. }
  257. $str .= "$value";
  258. }
  259. $str .= "],\n";
  260. }
  261. $str = substr( $str, 0, -2 ) . "\n"; // remove the trailing comma/return, reappend the return
  262. $str .= "]);\n"; // wrap it up
  263. return $str;
  264. }
  265. /**
  266. * Return javascript code that will display the Google Chart
  267. *
  268. */
  269. function yourls_google_viz_code( $graph_type, $data, $options, $id ) {
  270. $function_name = 'yourls_graph' . $id;
  271. $code = "\n<script id=\"$function_name\" type=\"text/javascript\">\n";
  272. $code .= "function $function_name() { \n";
  273. $code .= "$data\n";
  274. $code .= "var options = {\n";
  275. foreach( $options as $field => $value ) {
  276. if( !is_numeric( $value ) && strpos( $value, '[' ) !== 0 && strpos( $value, '{' ) !== 0 ) {
  277. $value = "\"$value\"";
  278. }
  279. $code .= "\t'$field': $value,\n";
  280. }
  281. $code = substr( $code, 0, -2 ) . "\n"; // remove the trailing comma/return, reappend the return
  282. $code .= "\t}\n";
  283. $code .= "new google.visualization.$graph_type( document.getElementById('visualization_$id') ).draw( data, options );";
  284. $code .= "}\n";
  285. $code .= "google.setOnLoadCallback( $function_name );\n";
  286. $code .= "</script>\n";
  287. $code .= "<div id=\"visualization_$id\"></div>\n";
  288. return $code;
  289. }