]> CyberLeo.Net >> Repos - Github/YOURLS.git/blob - includes/functions-infos.php
Load assets on stats pages complying to SSL preference. Partially fixed only. See...
[Github/YOURLS.git] / includes / functions-infos.php
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 function yourls_stats_countries_map( $countries ) {
5         yourls_do_action( 'stats_countries_map' );
6         
7         // Echo static map. Will be hidden if JS
8         $map = array(
9                 'cht' => 't',
10                 'chs' => '440x220',
11                 'chtm'=> 'world',
12                 'chco'=> 'FFFFFF,88C0EB,2A85B3,1F669C',
13                 'chld'=> join('' , array_keys( $countries ) ),
14                 'chd' => 't:'. join(',' ,  $countries ),
15                 'chf' => 'bg,s,EAF7FE'
16         );
17         $map_src = 'http://chart.apis.google.com/chart?' . http_build_query( $map );
18         //$map_src = yourls_match_current_protocol( $map_src, 'http://chart.apis.', 'https://www.' );
19         
20         $static = "<img id='yourls_stat_countries_static' class='hide-if-js' src='$map_src' width='440' height='220' border='0' />";
21         echo yourls_apply_filter( 'stats_countries_static', $static, $countries );
22
23         // Echo dynamic map. Will be hidden if no JS
24         $jsapi = yourls_match_current_protocol( 'http://www.google.com/jsapi' );
25         $dynamic = <<<MAP
26 <script type='text/javascript' src='$jsapi'></script>
27 <script type='text/javascript'>
28 google.load('visualization', '1', {'packages': ['geomap']});
29 google.setOnLoadCallback(drawMap);
30 function drawMap() {
31   var data = new google.visualization.DataTable();
32 MAP;
33         $dynamic .= '
34         data.addRows('.count( $countries ).');
35         ';
36         $dynamic .= "
37         data.addColumn('string', 'Country');
38         data.addColumn('number', 'Hits');
39         ";
40         $i = 0;
41         foreach( $countries as $c => $v ) {
42                 $dynamic .= "
43                   data.setValue($i, 0, '$c');
44                   data.setValue($i, 1, $v);
45                 ";
46                 $i++;
47         }
48
49         $dynamic .= <<<MAP
50   var options = {};
51   options['dataMode'] = 'regions';
52   options['width'] = '550px';
53   options['height'] = '340px';
54   options['colors'] = [0x88C0EB,0x2A85B3,0x1F669C];
55   var container = document.getElementById('yourls_stat_countries');
56   var geomap = new google.visualization.GeoMap(container);
57   geomap.draw(data, options);
58 };
59 </script>
60 <div id="yourls_stat_countries"></div>
61 MAP;
62
63         echo yourls_apply_filter( 'stats_countries_dynamic', $dynamic, $countries );
64 }
65
66 // 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
67 function yourls_stats_pie( $data, $limit = 10, $size = '340x220', $colors = 'C7E7FF,1F669C' ) {
68         yourls_do_action( 'stats_pie' );
69
70         // Trim array: $limit first item + the sum of all others
71         if ( count( $data ) > $limit ) {
72                 $i= 0;
73                 $trim_data = array('Others' => 0);
74                 foreach( $data as $item=>$value ) {
75                         $i++;
76                         if( $i <= $limit ) {
77                                 $trim_data[$item] = $value;
78                         } else {
79                                 $trim_data['Others'] += $value;
80                         }
81                 }
82                 $data = $trim_data;
83         }
84         
85         // Scale items
86         $_data = yourls_scale_data( $data );
87         
88         // Hmmm, pie
89         $pie = array(
90                 'cht' => 'p',
91                 'chs' => $size,
92                 'chd' => 't:'.( join(',' ,  $_data ) ),
93                 'chco'=> $colors,
94                 'chl' => join('|' , array_keys( $data ) )
95         );
96         $pie_src = 'http://chart.apis.google.com/chart?' . http_build_query( $pie );
97         //$pie_src = yourls_match_current_protocol( $pie_src, 'http://chart.apis.', 'https://www.' );
98         list( $size_x, $size_y ) = split( 'x', $size );
99         
100         $pie = "<img src='$pie_src' width='$size_x' height='$size_y' border='0' />";
101         echo yourls_apply_filter( 'stats_pie', $pie, $data, $limit, $size, $colors );
102 }
103
104 // Build a list of all daily values between d1/m1/y1 to d2/m2/y2.
105 function yourls_build_list_of_days( $dates ) {
106         /* Say we have an array like:
107         $dates = array (
108                 2009 => array (
109                         '08' => array (
110                                 29 => 15,
111                                 30 => 5,
112                                 ),
113                     '09' => array (
114                                 '02' => 3,
115                                 '03' => 5,
116                                 '04' => 2,
117                                 '05' => 99,
118                                 ),
119                         ),
120                 )
121         */
122         
123         if( !$dates )
124                 return array();
125
126         // Get first & last years from our range. In our example: 2009 & 2009
127         $first_year = key( $dates );
128         $last_year  = end( array_keys($dates) );
129         reset( $dates );
130
131         // Get first & last months from our range. In our example: 08 & 09
132         $first_month = key( $dates[$first_year] );
133         $last_month  = end( array_keys($dates[$last_year]) );
134         reset( $dates );
135         
136         // Get first & last days from our range. In our example: 29 & 05
137         $first_day = key( $dates[$first_year][$first_month] );
138         $last_day  = end( array_keys($dates[$last_year][$last_month]) );
139
140         // Now build a list of all years (2009), month (08 & 09) and days (all from 2009-08-29 to 2009-09-05)
141         $list_of_years = array();
142         $list_of_months = array();
143         $list_of_days = array();
144         for ( $year = $first_year; $year <= $last_year; $year++ ) {
145                 $_year = sprintf('%04d', $year);
146                 $list_of_years[$_year] = $_year;
147                 $current_first_month = ( $year == $first_year ? $first_month : '01' );
148                 $current_last_month  = ( $year == $last_year ? $last_month : '12' );
149                 for ( $month = $current_first_month; $month <= $current_last_month; $month++ ) {
150                         $_month = sprintf('%02d', $month);
151                         $list_of_months[$_month] = $_month;
152                         $current_first_day = ( $year == $first_year && $month == $first_month ? $first_day : '01' );
153                         $current_last_day  = ( $year == $last_year && $month == $last_month ? $last_day : yourls_days_in_month($month, $year) );
154                         for ( $day = $current_first_day; $day <= $current_last_day; $day++ ) {
155                                 $day = sprintf('%02d', $day);
156                                 $list_of_days["$_year-$_month-$day"] = isset( $dates[$_year][$_month][$day] ) ? $dates[$_year][$_month][$day] : 0;
157                         }
158                 }
159         }
160         
161         return array(
162                 'list_of_days' => $list_of_days,
163                 'list_of_months' => $list_of_months,
164                 'list_of_years' => $list_of_years,
165         );
166 }
167
168 // Echoes an image tag of Google Charts line graph from array of values (eg 'number of clicks'). $legend1_list & legend2_list are values used for the 2 x-axis labels
169 function yourls_stats_line( $values, $legend1_list, $legend2_list ) {
170         yourls_do_action( 'stats_line' );
171
172         // If we have only 1 day of data, prepend a fake day with 0 hits for a prettier graph
173         if ( count( $values ) == 1 )
174                 array_unshift( $values, 0 );
175                 
176         $values = yourls_array_granularity( $values, 30 );
177         
178         // If x-axis labels have only 1 value, double it for a nicer graph
179         if( count( $legend1_list ) == 1 )
180                 $legend1_list[] = current( $legend1_list );
181         if( count( $legend2_list ) == 1 )
182                 $legend2_list[] = current( $legend2_list );
183
184         // Make the chart
185         $legend1 = join('|', $legend1_list );
186         $legend2 = join('|', $legend2_list );
187         $max = max( $values );
188         if ( $max >= 4 ) {
189                 $label_clicks = '0|'.intval( $max / 4 ).'|'.intval( $max / 2 ).'|'.intval( $max / 1.5 ).'|'.$max;
190         } else {
191                 $label_clicks = array();
192                 for ($i = 0; $i <= $max; $i++) {
193                         $label_clicks[] = $i;
194                 }
195                 $label_clicks = join( '|', $label_clicks );
196         }
197         $line = array(
198                 'cht' => 'lc',
199                 'chs' => '440x220',
200                 'chxt'=> 'x,x,y',
201                 'chd' => 't:'.( join(',' ,  $values ) ),
202                 'chds' => '0,'.$max,
203                 'chm' => 'B,E3F3FF,0,0,0|o,2a85b3,0,-1,6|o,FFFFFF,0,-1,4',
204                 'chco' => '2a85b3',
205                 'chxl'=> '0:|'. $legend1 .'|1:|'. $legend2 .'|2:|'. $label_clicks
206         );
207         $line_src = 'http://chart.apis.google.com/chart?' . http_build_query( $line );
208         //$line_src = yourls_match_current_protocol( $line_src, 'http://chart.apis.', 'https://www.' );
209
210         echo yourls_apply_filter( 'stats_line', "<img src='$line_src' />", $values, $legend1_list, $legend2_list );
211 }
212
213 // Return the number of days in a month. From php.net, used if PHP built without calendar functions
214 function yourls_days_in_month($month, $year) {
215         // calculate number of days in a month
216         return $month == 2 ? ($year % 4 ? 28 : ($year % 100 ? 29 : ($year % 400 ? 28 : 29))) : (($month - 1) % 7 % 2 ? 30 : 31);
217 }
218
219 // Get max value from date array of 'year-month-day' = 'hits'
220 function yourls_stats_get_best_day( $list_of_days ) {
221         $max = 0; $day = 0;
222         $max = max( $list_of_days );
223         foreach( $list_of_days as $k=>$v ) {
224                 if ( $v == $max )
225                         return array( 'day' => $k, 'max' => $max );
226         }
227 }
228
229 // Return domain of a URL
230 function yourls_get_domain( $url, $include_scheme = false ) {
231         $parse = @parse_url( $url ); // Hiding ugly stuff coming from malformed referrer URLs
232
233         // Get host & scheme. Fall back to path if not found.
234         $host = isset( $parse['host'] ) ? $parse['host'] : '';
235         $scheme = isset( $parse['scheme'] ) ? $parse['scheme'] : '';
236         $path = isset( $parse['path'] ) ? $parse['path'] : '';
237         if( !$host )
238                 $host = $path;  
239                 
240         if ( $include_scheme && $scheme )
241                 $host = $scheme.'://'.$host;
242                 
243         return $host;
244 }
245
246 // Return favicon URL
247 function yourls_get_favicon_url( $url ) {
248         return yourls_match_current_protocol( 'http://www.google.com/s2/u/0/favicons?domain=' . yourls_get_domain( $url, false ) );
249 }
250
251 // Scale array of data from 0 to 100 max
252 function yourls_scale_data( $data ) {
253         $max = max( $data );
254         if( $max > 100 ) {
255                 foreach( $data as $k=>$v ) {
256                         $data[$k] = intval( $v / $max * 100 );
257                 }
258         }
259         return $data;
260 }
261
262 // 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
263 function yourls_array_granularity( $array, $grain = 100, $preserve_max = true ) {
264         if ( count( $array ) > $grain ) {
265                 $max = max( $array );
266                 $step = intval( count( $array ) / $grain );
267                 $i = 0;
268                 // Loop through each item and unset except every $step (optional preserve the max value)
269                 foreach( $array as $k=>$v ) {
270                         $i++;
271                         if ( $i % $step != 0 ) {
272                                 if ( $preserve_max == false ) {
273                                         unset( $array[$k] );
274                                 } else {
275                                         if ( $v < $max )
276                                                 unset( $array[$k] );
277                                 }
278                         }
279                 }
280         }
281         return $array;
282 }