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