Mercurial > defr > drupal > ad
comparison report/ad_report.module @ 1:948362c2a207 ad
update advertisement
author | pierre |
---|---|
date | Thu, 02 Apr 2009 15:28:21 +0000 |
parents | d8a3998dac8e |
children | 6aeff3329e01 |
comparison
equal
deleted
inserted
replaced
0:d8a3998dac8e | 1:948362c2a207 |
---|---|
1 <?php | 1 <?php |
2 // $Id: ad_report.module,v 1.1.2.3.2.7.2.6 2009/02/16 23:12:29 jeremy Exp $ | 2 // $Id: ad_report.module,v 1.1.2.3.2.7.2.6.2.7 2009/03/27 19:31:36 jeremy Exp $ |
3 | 3 |
4 /** | 4 /** |
5 * @file | 5 * @file |
6 * Provides comprehensive charts and reports about advertising statistics. | 6 * Provides comprehensive charts and reports about advertising statistics. |
7 * | 7 * |
8 * Copyright (c) 2005-2009. | 8 * Copyright (c) 2007-2009. |
9 * Jeremy Andrews <jeremy@tag1consulting.com>. | 9 * Jeremy Andrews <jeremy@tag1consulting.com>. |
10 */ | 10 */ |
11 | 11 |
12 /** | 12 /** |
13 * Implementation of hook_menu(). | 13 * Implementation of hook_menu(). |
14 */ | 14 */ |
15 function ad_report_menu() { | 15 function ad_report_menu() { |
16 $items = array(); | 16 $items = array(); |
17 | 17 $items['admin/content/ad/report'] = array( |
18 'title' => t('Reports'), | |
19 'page callback' => 'drupal_get_form', | |
20 'page arguments' => array('ad_report_admin'), | |
21 'access arguments' => array('generate administrative reports'), | |
22 'type' => MENU_LOCAL_TASK, | |
23 'weight' => 1 | |
24 ); | |
25 $items['admin/content/ad/report/display'] = array( | |
26 'page callback' => 'ad_report_admin_display', | |
27 'access arguments' => array('generate administrative reports'), | |
28 'type' => MENU_CALLBACK | |
29 ); | |
30 $items['admin/content/ad/report/csv'] = array( | |
31 'page callback' => 'ad_report_admin_ad_table', | |
32 'page arguments' => array('0', '0', array(), TRUE), | |
33 'access arguments' => array('generate administrative reports'), | |
34 'type' => MENU_CALLBACK | |
35 ); | |
18 $items['node/%node/report'] = array( | 36 $items['node/%node/report'] = array( |
19 'title' => 'Reports', | 37 'title' => t('Reports'), |
20 'page callback' => 'ad_report_bargraph', | 38 'page callback' => 'ad_report_bargraph_handler', |
21 'page arguments' => array(1), | 39 'page arguments' => array(1), |
22 'type' => MENU_LOCAL_TASK, | 40 'type' => MENU_LOCAL_TASK, |
23 'access callback' => 'ad_report_access', | 41 'access callback' => 'ad_report_bargraph_access', |
24 'access arguments' => array(1), | 42 'access arguments' => array(1), |
25 ); | 43 ); |
26 $items['node/%node/report/monthly'] = array( | 44 $items['ad_report/%node/bargraph/node/%/%'] = array( |
27 'title' => 'Monthly Reports', | |
28 'page callback' => 'ad_report_bargraph', | |
29 'page arguments' => array(1,3), | |
30 'type' => MENU_LOCAL_TASK, | |
31 'access callback' => 'ad_report_access', | |
32 'access arguments' => array(1), | |
33 ); | |
34 $items['node/%node/report/weekly'] = array( | |
35 'title' => 'Weekly Reports', | |
36 'page callback' => 'ad_report_bargraph', | |
37 'page arguments' => array(1,3), | |
38 'type' => MENU_LOCAL_TASK, | |
39 'access callback' => 'ad_report_access', | |
40 'access arguments' => array(1), | |
41 ); | |
42 $items['node/%node/report/daily'] = array( | |
43 'title' => 'Daily Reports', | |
44 'page callback' => 'ad_report_bargraph', | |
45 'page arguments' => array(1,3), | |
46 'type' => MENU_DEFAULT_LOCAL_TASK, | |
47 'access callback' => 'ad_report_access', | |
48 'access arguments' => array(1), | |
49 ); | |
50 $items['node/%node/report/hourly'] = array( | |
51 'title' => 'Hourly Reports', | |
52 'page callback' => 'ad_report_bargraph', | |
53 'page arguments' => array(1,3), | |
54 'type' => MENU_LOCAL_TASK, | |
55 'access callback' => 'ad_report_access', | |
56 'access arguments' => array(1), | |
57 ); | |
58 $items['ad_report/%node/bargraph'] = array( | |
59 'title' => 'Bar graph', | 45 'title' => 'Bar graph', |
60 'page callback' => 'ad_report_generate_bargraph', | 46 'page callback' => 'ad_report_generate_bargraph', |
61 'page arguments' => array(1), | 47 'page arguments' => array(1, 'node', 4, 5), |
62 'type' => MENU_CALLBACK, | 48 'type' => MENU_CALLBACK, |
63 'access callback' => 'ad_report_access', | 49 'access callback' => 'ad_report_bargraph_access', |
64 'access arguments' => array(1), | 50 'access arguments' => array(1), |
65 ); | 51 ); |
66 | |
67 return $items; | 52 return $items; |
68 } | 53 } |
69 /** | 54 |
70 * Implementation of access callback. | 55 /** |
71 * | 56 * Drupal hook_perm implementation. |
72 * @param mixed $node | 57 */ |
73 * Ad object. | 58 function ad_report_perm() { |
74 */ | 59 return array(t('generate administrative reports')); |
75 function ad_report_access($node){ | 60 } |
76 return ($node->type == 'ad') && ad_adaccess($node, 'access statistics'); | 61 |
77 } | 62 /** |
63 * Menu system callback, determine if current user can generate reports. | |
64 */ | |
65 function ad_report_bargraph_access($node) { | |
66 if (isset($node->adtype)) { | |
67 return ad_permission($node->nid, 'generate reports'); | |
68 } | |
69 } | |
70 | |
71 /** | |
72 * | |
73 */ | |
74 function ad_report_bargraph_handler($node) { | |
75 return ad_report_bargraph($node, "node/$node->nid/report", 'node', arg(3), arg(4)); | |
76 } | |
77 | |
78 /** | |
79 * Ad module hook_adapi. | |
80 */ | |
81 function ad_report_adapi($op, $node = NULL) { | |
82 switch ($op) { | |
83 case 'permissions': | |
84 return array( | |
85 'generate reports' => TRUE, | |
86 ); | |
87 } | |
88 } | |
89 | |
90 /** | |
91 * | |
92 */ | |
93 function ad_report_admin() { | |
94 $form = array(); | |
95 | |
96 $start = isset($_SESSION['ad_report_start']) ? strtotime($_SESSION['ad_report_start']) : _ad_report_first_day_of_month(); | |
97 $end = isset($_SESSION['ad_report_end']) ? strtotime($_SESSION['ad_report_end']) : _ad_report_last_day_of_month(); | |
98 $group = isset($_SESSION['ad_report_group']) ? $_SESSION['ad_report_group'] : array('all'); | |
99 | |
100 $form['dates'] = array( | |
101 '#type' => 'fieldset', | |
102 '#title' => t('Report dates'), | |
103 '#prefix' => '<div class="container-inline">', | |
104 '#suffix' => '</div>', | |
105 ); | |
106 $form['dates']['start'] = array( | |
107 '#type' => 'textfield', | |
108 '#title' => t('Start'), | |
109 '#size' => 24, | |
110 '#maxlength' => 64, | |
111 '#default_value' => _ad_report_format_date_human($start), | |
112 // display pop up calendar if jstools jscalendar module enabled | |
113 '#attributes' => array('class' => 'jscalendar'), | |
114 '#jscalendar_ifFormat' => '%Y-%m-%d %H:%M', | |
115 '#jscalendar_timeFormat' => '24', | |
116 ); | |
117 $form['dates']['space1'] = array( | |
118 '#value' => ' ', | |
119 ); | |
120 $form['dates']['end'] = array( | |
121 '#type' => 'textfield', | |
122 '#title' => t('End'), | |
123 '#size' => 24, | |
124 '#maxlength' => 64, | |
125 '#default_value' => _ad_report_format_date_human($end), | |
126 // display pop up calendar if jstools jscalendar module enabled | |
127 '#attributes' => array('class' => 'jscalendar'), | |
128 '#jscalendar_ifFormat' => '%Y-%m-%d %H:%M', | |
129 ); | |
130 $form['dates']['space2'] = array( | |
131 '#value' => ' ', | |
132 ); | |
133 | |
134 // groups | |
135 $groups = ad_groups_list(); | |
136 $form['groups'] = array( | |
137 '#type' => 'fieldset', | |
138 '#title' => t('Groups'), | |
139 ); | |
140 $options = array(); | |
141 $options['all'] = t('- All -'); | |
142 $options = $options + $groups; | |
143 $form['groups']['group'] = array( | |
144 '#type' => 'select', | |
145 '#title' => t('Ad groups'), | |
146 '#options' => $options, | |
147 '#multiple' => TRUE, | |
148 '#required' => TRUE, | |
149 '#default_value' => $group, | |
150 ); | |
151 | |
152 // submit | |
153 $form['submit'] = array( | |
154 '#type' => 'submit', | |
155 '#value' => t('Generate report'), | |
156 '#weight' => 10, | |
157 ); | |
158 $form['reset'] = array( | |
159 '#type' => 'submit', | |
160 '#value' => t('Reset report'), | |
161 '#weight' => 10, | |
162 ); | |
163 | |
164 return $form; | |
165 } | |
166 | |
167 /** | |
168 * Sanity check the date range. | |
169 */ | |
170 function ad_report_admin_validate($form, $form_state) { | |
171 if ($form_state['clicked_button']['#value'] == t('Reset report')) { | |
172 unset($_SESSION['ad_report_start']); | |
173 unset($_SESSION['ad_report_end']); | |
174 unset($_SESSION['ad_report_group']); | |
175 } | |
176 else { | |
177 $start = isset($form_state['values']['start']) ? strtotime($form_state['values']['start']) : 0; | |
178 $end = isset($form_state['values']['start']) ? strtotime($form_state['values']['end']) : 0; | |
179 if (!$start) { | |
180 form_set_error('start', t('You must enter a valid start date.')); | |
181 } | |
182 else if ($start >= (time() - 3600)) { | |
183 form_set_error('start', t('The report must start at least one hour before the current time.')); | |
184 } | |
185 else if ($start >= $end) { | |
186 form_set_error('start', t('The report must start before it ends.')); | |
187 } | |
188 if (!$end) { | |
189 form_set_error('end', t('You must enter a valid end date.')); | |
190 } | |
191 } | |
192 } | |
193 | |
194 /** | |
195 * Redirect to a path to generate the requested report. | |
196 */ | |
197 function ad_report_admin_submit($form, $form_state) { | |
198 if ($form_state['clicked_button']['#value'] == t('Generate report')) { | |
199 $start = date('YmdHi', strtotime($form_state['values']['start'])); | |
200 $end = date('YmdHi', strtotime($form_state['values']['end'])); | |
201 $group = $form_state['values']['group']; | |
202 $_SESSION['ad_report_start'] = $start; | |
203 $_SESSION['ad_report_end'] = $end; | |
204 $_SESSION['ad_report_group'] = $group; | |
205 | |
206 drupal_goto('admin/content/ad/report/display'); | |
207 } | |
208 } | |
209 | |
210 /** | |
211 * Display the administrative report. | |
212 */ | |
213 function ad_report_admin_display() { | |
214 $start = isset($_SESSION['ad_report_start']) ? $_SESSION['ad_report_start'] : 0; | |
215 $end = isset($_SESSION['ad_report_end']) ? $_SESSION['ad_report_end'] : 0; | |
216 $group = isset($_SESSION['ad_report_group']) ? $_SESSION['ad_report_group'] : array(); | |
217 if (!$start && !$end) { | |
218 drupal_goto('admin/content/ad/report'); | |
219 } | |
220 $output = '<div class="image"><img src="'. url("ad_report/0/bargraph/admin/$start/$end") .'" /></div>'; | |
221 $output .= ad_report_admin_ad_table(strtotime($start), strtotime($end), $group); | |
222 $output .= '<div>'. l(t('Modify report'), 'admin/content/ad/report') .'</div>'; | |
223 return $output; | |
224 } | |
225 | |
226 /** | |
227 * | |
228 */ | |
229 function ad_report_admin_ad_table($start = 0, $end = 0, $group = array(), $csv = FALSE) { | |
230 if (!$start) { | |
231 $start = isset($_SESSION['ad_report_start']) ? strtotime($_SESSION['ad_report_start']) : 0; | |
232 } | |
233 if (!$end) { | |
234 $end = isset($_SESSION['ad_report_end']) ? strtotime($_SESSION['ad_report_end']) : 0; | |
235 } | |
236 if (empty($group)) { | |
237 $group = isset($_SESSION['ad_report_group']) ? $_SESSION['ad_report_group'] : array(); | |
238 } | |
239 // prepare dates | |
240 $start = _ad_report_format_date_db($start); | |
241 $end = _ad_report_format_date_db($end); | |
242 | |
243 // prepare groups | |
244 $groups = ad_groups_list(); | |
245 $all = FALSE; | |
246 $none = FALSE; | |
247 if (is_array($group)) { | |
248 if (in_array('all', $group)) { | |
249 $all = TRUE; | |
250 } | |
251 if (!$all) { | |
252 if (sizeof($group) == sizeof($groups)) { | |
253 $all = TRUE; | |
254 } | |
255 } | |
256 if (in_array('0', $group)) { | |
257 unset($group[0]); | |
258 $none = TRUE; | |
259 } | |
260 } | |
261 | |
262 $select = 'SELECT DISTINCT(aid) as nid FROM {ad_statistics} a'; | |
263 if ($all) { | |
264 $where = array( | |
265 "a.action = 'view'", | |
266 'a.date >= %d', | |
267 'a.date <= %d', | |
268 'a.aid > 0', | |
269 ); | |
270 $join = array(); | |
271 $args = array($start, $end); | |
272 } | |
273 else if ($none) { | |
274 if (sizeof($group)) { | |
275 $where = array( | |
276 '(t.tid IN (%s) OR ISNULL(t.tid))', | |
277 "a.action = 'view'", | |
278 'a.date >= %d', | |
279 'a.date <= %d', | |
280 ); | |
281 $join = array( | |
282 'LEFT JOIN {term_node} t ON a.aid = t.tid', | |
283 ); | |
284 $args = array(implode(',', $group), $start, $end); | |
285 } | |
286 else { | |
287 $where = array( | |
288 'ISNULL(t.tid)', | |
289 "a.action = 'view'", | |
290 'a.date >= %d', | |
291 'a.date <= %d', | |
292 ); | |
293 $join = array( | |
294 'LEFT JOIN {term_node} t ON a.aid = t.tid', | |
295 ); | |
296 $args = array($start, $end); | |
297 } | |
298 } | |
299 else { | |
300 $where = array( | |
301 't.tid IN (%s)', | |
302 "a.action = 'view'", | |
303 'a.date >= %d', | |
304 'a.date <= %d', | |
305 ); | |
306 $join = array( | |
307 'LEFT JOIN {term_node} t ON a.aid = t.tid', | |
308 ); | |
309 $args = array(implode(',', $group), $start, $end); | |
310 } | |
311 | |
312 $return = module_invoke_all('adreport', $join, $where, $args, $select); | |
313 foreach ($return as $type => $value) { | |
314 switch ($type) { | |
315 case 'join': | |
316 if (is_array($value)) { | |
317 foreach ($value as $option) { | |
318 $join[] = $option; | |
319 } | |
320 } | |
321 break; | |
322 case 'where': | |
323 if (is_array($value)) { | |
324 foreach ($value as $option) { | |
325 $where[] = $option; | |
326 } | |
327 } | |
328 break; | |
329 case 'args': | |
330 if (is_array($value)) { | |
331 foreach ($value as $option) { | |
332 $args[] = $option; | |
333 } | |
334 } | |
335 break; | |
336 } | |
337 } | |
338 | |
339 // Build the query. | |
340 $query = $select .' '. implode(' ', $join) .' WHERE '. implode(' AND ', $where); | |
341 $ads = array(); | |
342 $result = db_query($query, $args); | |
343 while ($ad = db_fetch_object($result)) { | |
344 if ($ad->nid) { | |
345 $ads[$ad->nid] = $ad->nid; | |
346 } | |
347 } | |
348 | |
349 if ($csv) { | |
350 header('Content-type: application/octet-stream'); | |
351 header("Content-Disposition: attachment; filename=report-$start-$end.csv"); | |
352 echo "ad id, title, first view, last view, clicks, views, click-thru\n"; | |
353 } | |
354 else { | |
355 $output = '<div class="describe">' . t('There !count matching your parameters.', array('!count' => format_plural(sizeof($ads), 'was 1 active ad', 'were @count active ads'))) . '</div>'; | |
356 | |
357 $headers = array(t('Advertisement'), t('Active dates'), t('Views'), t('Clicks'), t('Click-thru')); | |
358 // get counts for each ad | |
359 $rows = array(); | |
360 } | |
361 $total_views = $total_clicks = 0; | |
362 foreach ($ads as $nid) { | |
363 $ad = node_load($nid); | |
364 if ($ad->nid) { | |
365 $views = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} WHERE aid = %d AND action = 'view' AND date >= %d AND date <= %d", $nid, $start, $end)); | |
366 $first = _ad_report_get_date_from_path((int)db_result(db_query("SELECT MIN(date) FROM {ad_statistics} WHERE aid = %d AND action = 'view' AND date >= %d AND date <= %d", $nid, $start, $end))); | |
367 $first = format_date($first, 'small'); | |
368 $last = _ad_report_get_date_from_path((int)db_result(db_query("SELECT MAX(date) FROM {ad_statistics} WHERE aid = %d AND action = 'view' AND date >= %d AND date <= %d", $nid, $start, $end))); | |
369 $last = format_date($last, 'small'); | |
370 $clicks = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} WHERE aid = %d AND action = 'click' AND date >= %d AND date <= %d", $nid, $start, $end)); | |
371 if ($views) { | |
372 $clickthru = number_format($clicks / $views, 2) .'%'; | |
373 } | |
374 else { | |
375 $clickthru = '0%'; | |
376 } | |
377 if ($views || $clicks) { | |
378 if ($csv) { | |
379 echo "$ad->nid, $ad->title, $first, $last, $views, $clicks, $clickthru\n"; | |
380 } | |
381 else { | |
382 $row = array(); | |
383 $row[] = l($ad->title, "node/$ad->nid"); | |
384 $row[] = "first view: $first<br />last view: $last"; | |
385 $row[] = number_format($views); | |
386 $row[] = number_format($clicks); | |
387 $row[] = $clickthru; | |
388 $rows[] = $row; | |
389 $total_views += $views; | |
390 $total_clicks += $clicks; | |
391 } | |
392 } | |
393 } | |
394 } | |
395 if ($csv) { | |
396 return (0); | |
397 } | |
398 if ($total_views || $total_clicks) { | |
399 $row = array(); | |
400 $row[] = '<strong>'. t('Total') .'</strong>'; | |
401 $row[] = ''; | |
402 $row[] = '<strong>'. number_format($total_views) .'</strong>'; | |
403 $row[] = '<strong>'. number_format($total_clicks) .'</strong>'; | |
404 if ($total_views) { | |
405 $row[] = '<strong>'. number_format($total_clicks / $total_views, 2) .'%' .'</strong>'; | |
406 } | |
407 else { | |
408 $row[] = '<strong>'. '0%' .'</strong>'; | |
409 } | |
410 $rows[] = $row; | |
411 } | |
412 $output .= theme('table', $headers, $rows); | |
413 $output .= l(t('Download CSV'), 'admin/content/ad/report/csv'); | |
414 return $output; | |
415 } | |
416 | |
417 /** | |
418 * Returns a timestamp for the first hour of the first day of the month. | |
419 */ | |
420 function _ad_report_first_day_of_month($time = NULL) { | |
421 if ($time === NULL) { | |
422 $time = time(); | |
423 } | |
424 return strtotime(date('Ym010000', $time)); | |
425 } | |
426 | |
427 /** | |
428 * Returns a timestamp for the last hour of the last day of the month. | |
429 */ | |
430 function _ad_report_last_day_of_month($time = NULL) { | |
431 if ($time === NULL) { | |
432 $time = time(); | |
433 } | |
434 $month = date('m', $time); | |
435 $year = date('Y', $time); | |
436 $day = date('d', mktime(0, 0, 0, ($month + 1), 0, $year)); | |
437 return strtotime("{$year}{$month}{$day}2359"); | |
438 } | |
439 | |
78 /** | 440 /** |
79 * Page to display ad with bargraph. | 441 * Page to display ad with bargraph. |
80 */ | 442 */ |
81 function ad_report_bargraph($node, $granularity = 'daily', $type = 'node') { | 443 function ad_report_bargraph($data, $url, $type = 'node', $start = 0, $end = 0) { |
82 switch ($granularity) { | 444 if ($type == 'node') { |
83 case 'hourly': | 445 drupal_set_title($data->title); |
84 drupal_set_title(t('Past twelve hours')); | 446 } |
85 break; | 447 $start_date = _ad_report_get_date_from_path($start); |
86 case 'daily': | 448 $end_date = _ad_report_get_date_from_path($end); |
87 drupal_set_title(t('Past twelve days')); | 449 $output = drupal_get_form('ad_report_range_form', $type, $url, $start_date, $end_date); |
88 break; | 450 if ($start && $end) { |
89 case 'weekly': | 451 switch ($type) { |
90 drupal_set_title(t('Past twelve weeks')); | 452 case 'node': |
91 break; | 453 $ad = db_fetch_object(db_query('SELECT aid, redirect, adtype FROM {ads} WHERE aid = %d', $data->nid)); |
92 case 'monthly': | 454 if ($ad->aid) { |
93 drupal_set_title(t('Past twelve months')); | 455 $output .= '<img src="'. url("ad_report/$data->nid/bargraph/node/$start/$end") .'" />'; |
94 break; | 456 $output .= theme('box', '', module_invoke("ad_$data->adtype", 'display_ad', $ad)); |
95 } | 457 $output .= ad_report_group_table($data->nid, $type, $start, $end); |
96 | 458 } |
97 switch ($type) { | 459 $output .= module_invoke('ad', 'click_history', $data->nid); |
98 case 'node': | 460 break; |
99 if ($node->aid) { | 461 default: |
100 $output = '<img src="'. url("ad_report/$node->nid/bargraph/$granularity/node") .'" />'; | 462 $output = '<img src="'. url("ad_report/$data->uid/bargraph/$granularity/$type") .'" />'; |
101 $ad_link = module_invoke('ad_' . $node->adtype, 'display_ad', $node); | 463 break; |
102 $output .= theme('box', $node->title, $ad_link); | 464 } |
103 } | |
104 break; | |
105 default: | |
106 $output = '<img src="'. url("ad_report/$node->uid/bargraph/$granularity/$type") .'" />'; | |
107 break; | |
108 } | 465 } |
109 return $output; | 466 return $output; |
110 } | 467 } |
111 | 468 |
112 /** | 469 /** |
470 * Return a form for selecting a date range for generating a report. | |
471 */ | |
472 function ad_report_range_form($form_state, $type, $url = NULL, $start = NULL, $end = NULL) { | |
473 $form = array(); | |
474 | |
475 $start = $start ? $start : _ad_report_first_day_of_month(); | |
476 $end = $end ? $end : _ad_report_last_day_of_month(); | |
477 | |
478 $form['report'] = array( | |
479 '#type' => 'fieldset', | |
480 '#title' => t('Report dates'), | |
481 '#prefix' => '<div class="container-inline">', | |
482 '#suffix' => '</div>', | |
483 ); | |
484 $form['report']['type'] = array( | |
485 '#value' => $type, | |
486 '#type' => 'hidden', | |
487 ); | |
488 $form['report']['url'] = array( | |
489 '#value' => $url, | |
490 '#type' => 'hidden', | |
491 ); | |
492 $form['report']['start'] = array( | |
493 '#type' => 'textfield', | |
494 '#title' => t('Start'), | |
495 '#size' => 24, | |
496 '#maxlength' => 64, | |
497 '#default_value' => _ad_report_format_date_human($start), | |
498 // display pop up calendar if jstools jscalendar module enabled | |
499 '#attributes' => array('class' => 'jscalendar'), | |
500 '#jscalendar_ifFormat' => '%Y-%m-%d %H:%M', | |
501 '#jscalendar_timeFormat' => '24', | |
502 ); | |
503 $form['report']['space1'] = array( | |
504 '#value' => ' ', | |
505 ); | |
506 $form['report']['end'] = array( | |
507 '#type' => 'textfield', | |
508 '#title' => t('End'), | |
509 '#size' => 24, | |
510 '#maxlength' => 64, | |
511 '#default_value' => _ad_report_format_date_human($end), | |
512 // display pop up calendar if jstools jscalendar module enabled | |
513 '#attributes' => array('class' => 'jscalendar'), | |
514 '#jscalendar_ifFormat' => '%Y-%m-%d %H:%M', | |
515 ); | |
516 $form['report']['space2'] = array( | |
517 '#value' => ' ', | |
518 ); | |
519 $form['report']['generate'] = array( | |
520 '#type' => 'submit', | |
521 '#value' => t('Generate report'), | |
522 ); | |
523 | |
524 return $form; | |
525 } | |
526 | |
527 /** | |
528 * Validate the form range. | |
529 */ | |
530 function ad_report_range_form_validate($form, $form_state) { | |
531 $start = isset($form_state['values']['start']) ? strtotime($form_state['values']['start']) : 0; | |
532 $end = isset($form_state['values']['start']) ? strtotime($form_state['values']['end']) : 0; | |
533 if (!$start) { | |
534 form_set_error('start', t('You must enter a valid start date.')); | |
535 } | |
536 else if ($start >= (time() - 3600)) { | |
537 form_set_error('start', t('The report must start at least one hour before the current time.')); | |
538 } | |
539 else if ($start >= $end) { | |
540 form_set_error('start', t('The report must start before it ends.')); | |
541 } | |
542 if (!$end) { | |
543 form_set_error('end', t('You must enter a valid end date.')); | |
544 } | |
545 } | |
546 | |
547 /** | |
548 * Redirect to URL for displaying report. | |
549 */ | |
550 function ad_report_range_form_submit($form, $form_state) { | |
551 $start = date('YmdHi', strtotime($form_state['values']['start'])); | |
552 $end = date('YmdHi', strtotime($form_state['values']['end'])); | |
553 drupal_goto($form_state['values']['url'] ."/$start/$end"); | |
554 } | |
555 | |
556 /** | |
557 * Helper function to extract date from URL. | |
558 */ | |
559 function _ad_report_get_date_from_path($path) { | |
560 if (isset($path) && $path) { | |
561 $year = substr($path, 0, 4); | |
562 $month = substr($path, 4, 2); | |
563 $day = substr($path, 6, 2); | |
564 $hour = substr($path, 8, 2); | |
565 if (strlen($path) == 12) { | |
566 $minute = substr($path, 10, 2); | |
567 } | |
568 else { | |
569 $minute = 0; | |
570 } | |
571 $date = strtotime("$month/$day/$year $hour:$minute"); | |
572 if ($date > 0) { | |
573 return $date; | |
574 } | |
575 drupal_set_message(t('Invalid date specified in range.'), 'error'); | |
576 } | |
577 } | |
578 | |
579 /** | |
580 * Helper function to format date. | |
581 */ | |
582 function _ad_report_format_date_human($date) { | |
583 return date('Y-m-d H:i', $date); | |
584 } | |
585 | |
586 /** | |
587 * Helper function to format date. | |
588 */ | |
589 function _ad_report_format_date_db($date) { | |
590 return date('YmdH', $date); | |
591 } | |
592 | |
593 /** | |
594 * Display table with per-group statistics. | |
595 */ | |
596 function ad_report_group_table($id, $type, $start, $end) { | |
597 $start_date = _ad_report_format_date_db(_ad_report_get_date_from_path($start)); | |
598 $end_date = _ad_report_format_date_db(_ad_report_get_date_from_path($end)); | |
599 // TODO: Support other types than nodes | |
600 $result = db_query('SELECT DISTINCT(adgroup) FROM {ad_statistics} WHERE aid = %d AND date >= %d AND date <= %d', $id, $start_date, $end_date); | |
601 // extract all groups that this advertisement has been displayed in | |
602 while ($group = db_fetch_object($result)) { | |
603 if ($group->adgroup) { | |
604 $first = substr($group->adgroup, 0, 1); | |
605 if ($first == 't') { | |
606 $tids = $tids = explode(',', substr($group->adgroup, 1, strlen($group->adgroup))); | |
607 foreach ($tids as $tid) { | |
608 if ($tid) { | |
609 $adgroups[$tid][] = $group->adgroup; | |
610 } | |
611 } | |
612 } | |
613 else { | |
614 // handle this type of "group" | |
615 $adgroups['other'][] = $group->adgroup; | |
616 } | |
617 } | |
618 else { | |
619 $adgroups[0][] = $group->adgroup; | |
620 } | |
621 } | |
622 $headers = array(t('Group'), t('Active dates'), t('Views'), t('Clicks'), t('Click-thru')); | |
623 // get counts for each group | |
624 $groups = ad_groups_list(); | |
625 $rows = array(); | |
626 $total_views = $total_clicks = 0; | |
627 foreach ($groups as $tid => $group) { | |
628 $views = $clicks = 0; | |
629 if (isset($adgroups[$tid]) && is_array($adgroups[$tid])) { | |
630 foreach ($adgroups[$tid] as $adgroup) { | |
631 $views += (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} WHERE aid = %d AND adgroup = '%s' AND action = 'view' AND date >= %d AND date <= %d", $id, $adgroup, $start_date, $end_date)); | |
632 $clicks += (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} WHERE aid = %d AND adgroup = '%s' AND action = 'click' AND date >= %d AND date <= %d", $id, $adgroup, $start_date, $end_date)); | |
633 } | |
634 } | |
635 if ($views || $clicks) { | |
636 $begin = (int)db_result(db_query("SELECT MIN(date) FROM {ad_statistics} WHERE (adgroup LIKE '%%t%s' OR adgroup LIKE '%%,%s') AND action = 'view' AND date >= %d AND date <= %d", $tid, $tid, $start_date, $end_date)); | |
637 if ($begin) { | |
638 $begin = format_date(_ad_report_get_date_from_path($begin), 'small'); | |
639 $finish = (int)db_result(db_query("SELECT MAX(date) FROM {ad_statistics} WHERE (adgroup LIKE '%%t%s' OR adgroup LIKE '%%,%s') AND action = 'view' AND date >= %d AND date <= %d", $tid, $tid, $start_date, $end_date)); | |
640 if ($finish) { | |
641 $finish = format_date(_ad_report_get_date_from_path($finish), 'small'); | |
642 } | |
643 } | |
644 if ($begin && $finish) { | |
645 $row = array(); | |
646 $row[] = $group; | |
647 $row[] = "first view: $begin<br />last view: $finish"; | |
648 $row[] = number_format($views); | |
649 $row[] = number_format($clicks); | |
650 if ($views) { | |
651 $row[] = number_format($clicks / $views, 2) .'%'; | |
652 } | |
653 else { | |
654 $row[] = '0%'; | |
655 } | |
656 $rows[] = $row; | |
657 $total_views += $views; | |
658 $total_clicks += $clicks; | |
659 } | |
660 } | |
661 } | |
662 if ($total_views || $total_clicks) { | |
663 $row = array(); | |
664 $row[] = '<strong>'. t('Total') .'</strong>'; | |
665 $row[] = ''; | |
666 $row[] = '<strong>'. number_format($total_views) .'</strong>'; | |
667 $row[] = '<strong>'. number_format($total_clicks) .'</strong>'; | |
668 if ($total_views) { | |
669 $row[] = '<strong>'. number_format($total_clicks / $total_views, 2) .'%' .'</strong>'; | |
670 } | |
671 else { | |
672 $row[] = '<strong>'. '0%' .'</strong>'; | |
673 } | |
674 $rows[] = $row; | |
675 } | |
676 | |
677 return theme('table', $headers, $rows); | |
678 } | |
679 | |
680 /** | |
113 * Page that utilizes gd to generate a bargraph. | 681 * Page that utilizes gd to generate a bargraph. |
114 * | 682 */ |
115 * TODO: Make this more dynamic, allowing to move through time, etc. | 683 function ad_report_generate_bargraph($id, $type, $start, $end) { |
116 */ | |
117 function ad_report_generate_bargraph($node, $granularity = 'daily', $type = 'node') { | |
118 $id = $node->nid; | |
119 header("Content-type: image/png"); | 684 header("Content-type: image/png"); |
120 | 685 |
121 // Preperation. | 686 if ($type == 'node' && is_object($id)) { |
687 $id = $id->nid; | |
688 } | |
689 $start = _ad_report_get_date_from_path($start); | |
690 $end = _ad_report_get_date_from_path($end); | |
691 | |
692 // be sure we've been passed in valid parameters | |
693 $elapse = $end - $start; | |
694 if ($elapse <= 0 || $start <= 0 || $end <= 0) { | |
695 return NULL; | |
696 } | |
697 $increments = (int)($elapse / 3600); | |
698 | |
699 // image size | |
700 $image_width = 700; | |
701 $image_height = 360; | |
702 | |
703 // graph size | |
704 $graph_width = 600; | |
705 $graph_height = 250; | |
706 $graph_x_offset = 8; | |
707 $graph_y_offset = 8; | |
708 $graph_y = 8; | |
709 | |
710 // calculate slices to extract from database | |
711 $width = $graph_width / $increments; | |
712 $number = $increments; | |
713 $factor = 1; | |
714 if ($width < 1) { | |
715 $factor = 1 / $width; | |
716 } | |
717 $number = $number / $factor; | |
718 $width = $width * $factor; | |
719 $slice = $elapse / $number; | |
720 | |
721 // retrieve views and clicks from the database | |
122 $views = array(); | 722 $views = array(); |
723 $clicks = array(); | |
123 $max_views = 0; | 724 $max_views = 0; |
124 $statistics = array(); | |
125 $clicks = array(); | |
126 $max_clicks = 0; | 725 $max_clicks = 0; |
127 $time = time(); | 726 $key = 0; |
128 | 727 for ($i = $start; $i < $end; $i += $slice) { |
129 $increments = 12; | 728 $start_date = _ad_report_format_date_db($i); |
130 $end_add = 0; | 729 $end_date = _ad_report_format_date_db($i + $slice); |
131 switch ($granularity) { | 730 switch ($type) { |
132 case 'hourly': | 731 case 'node': |
133 $start_time = (60 * 60 * 11); | 732 $views[] = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} WHERE aid = %d AND action = 'view' AND date >= %d AND date <= %d", $id, $start_date, $end_date)); |
134 // Increment hourly. | 733 $clicks[] = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} WHERE aid = %d AND action = 'click' AND date >= %d AND date <= %d", $id, $start_date, $end_date)); |
135 $increment_time = (60 * 60); | 734 break; |
136 | 735 case 'user': |
137 $format_start = 'YmdH'; | 736 $views[] = (int)db_result(db_query("SELECT SUM(a.count) FROM {ad_statistics} a LEFT JOIN {node} n ON a.aid = n.nid WHERE n.uid = %d AND n.type = 'ad' AND a.action = 'view' AND a.date >= %d AND a.date <= %d", $id, $start_date, $end_date)); |
138 $format_end = 'YmdH'; | 737 $clicks[] = (int)db_result(db_query("SELECT SUM(a.count) FROM {ad_statistics} a LEFT JOIN {node} n ON a.aid = n.nid WHERE n.uid = %d AND n.type = 'ad' AND a.action = 'click' AND a.date >= %d AND a.date <= %d", $id, $start_date, $end_date)); |
139 $format_end_append = ''; | 738 break; |
140 $format_upper = 'M d'; | 739 case 'admin': |
141 $format_lower = 'ga'; | 740 $group = $_SESSION['ad_report_group']; |
142 $graph_height = 250; | 741 $all = FALSE; |
143 break; | 742 $none = FALSE; |
144 case 'daily': | 743 if (is_array($group)) { |
145 default: | 744 if (in_array('all', $group)) { |
146 $start_time = (60 * 60 * 24 * 11); | 745 $all = TRUE; |
147 // Increment daily. | 746 } |
148 $increment_time = (60 * 60 * 24); | 747 if (!$all) { |
149 | 748 $groups = ad_groups_list(); |
150 $format_start = 'Ymd00'; | 749 if (sizeof($group) == sizeof($groups)) { |
151 $format_end = 'Ymd'; | 750 $all = TRUE; |
152 $format_end_append = '24'; | 751 } |
153 $format_upper = 'D'; | 752 } |
154 $format_lower = 'M d'; | 753 if (in_array('0', $group)) { |
155 break; | 754 unset($group[0]); |
156 case 'weekly': | 755 $none = TRUE; |
157 $start_time = (60 * 60 * 24 * 7 * 11); | 756 } |
158 // Increment weekly. | 757 } |
159 $increment_time = (60 * 60 * 24 * 7); | 758 if ($all) { |
160 | 759 $views[] = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} WHERE action = 'view' AND date >= %d AND date <= %d", $start_date, $end_date)); |
161 $format_start = 'Ymd00'; | 760 $clicks[] = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} WHERE action = 'click' AND date >= %d AND date <= %d", $start_date, $end_date)); |
162 $format_end = 'Ymd'; | 761 } |
163 $format_end_append = '24'; | 762 else if ($none) { |
164 $end_add = (60 * 60 * 24 * 6); | 763 if (sizeof($group)) { |
165 //$end_add = 600; | 764 $views[] = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} a LEFT JOIN {term_node} t ON a.aid = t.tid WHERE (t.tid IN (%s) OR ISNULL(t.tid)) AND action = 'view' AND date >= %d AND date <= %d", implode(',', $group), $start_date, $end_date)); |
166 $format_upper = 'M d -'; | 765 $clicks[] = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} a LEFT JOIN {term_node} t ON a.aid = t.tid WHERE (t.tid IN (%s) OR ISNULL(t.tid)) AND action = 'click' AND date >= %d AND date <= %d", implode(',', $group), $start_date, $end_date)); |
167 $format_lower = ''; | 766 } |
168 break; | 767 else { |
169 case 'monthly': | 768 $views[] = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} a LEFT JOIN {term_node} t ON a.aid = t.tid WHERE ISNULL(t.tid) AND action = 'view' AND date >= %d AND date <= %d", $start_date, $end_date)); |
170 $start_time = ((60 * 60 * 24 * 2) + (60 * 60 * 24 * 7 * 4)) * 11; | 769 $clicks[] = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} a LEFT JOIN {term_node} t ON a.aid = t.tid WHERE ISNULL(t.tid) AND action = 'click' AND date >= %d AND date <= %d", $start_date, $end_date)); |
171 // Increment monthly (every 30 days). | 770 } |
172 $increment_time = (60 * 60 * 24 * 2) + (60 * 60 * 24 * 7 * 4); | 771 } |
173 | 772 else { |
174 $format_start = 'Ymd00'; | 773 $views[] = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} a LEFT JOIN {term_node} t ON a.aid = t.tid WHERE tid IN (%s) AND action = 'view' AND date >= %d AND date <= %d", implode(',', $group), $start_date, $end_date)); |
175 $format_end = 'Ymd'; | 774 $clicks[] = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} a LEFT JOIN {term_node} t ON a.aid = t.tid WHERE t.tid IN (%s) AND action = 'click' AND date >= %d AND date <= %d", implode(',', $group), $start_date, $end_date)); |
176 $format_end_append = '24'; | 775 } |
177 $end_add = (60 * 60 * 24 * 29); | 776 break; |
178 $format_upper = 'M d -'; | 777 default: |
179 $format_lower = ''; | 778 $function = "ad_report_views_$type"; |
180 break; | 779 if (function_exists("$function")) { |
181 } | 780 $views[] = $function($id, $day_start, $day_end); |
182 | 781 } |
183 // Retrive data from database. | 782 $function = "ad_report_clicks_$type"; |
184 for ($i = $time - $start_time; $i <= $time; $i = $i + $increment_time) { | 783 if (function_exists("$function")) { |
185 $day_start = date($format_start, $i); | 784 $clicks[] = $function($id, $day_start, $day_end); |
186 $day_end = date($format_end, $i + $end_add). $format_end_append; | 785 } |
187 if ($type == 'node') { | 786 break; |
188 $view = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} WHERE aid = %d AND action = 'view' AND date >= %d AND date <= %d", $id, $day_start, $day_end)); | 787 } |
189 $click = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} WHERE aid = %d AND action = 'click' AND date >= %d AND date <= %d", $id, $day_start, $day_end)); | 788 $max_views = $views[$key] > $max_views ? $views[$key] : $max_views; |
190 } | 789 $max_clicks = $clicks[$key] > $max_clicks ? $clicks[$key] : $max_clicks; |
191 else if ($type == 'user') { | 790 $key++; |
192 $view = (int)db_result(db_query("SELECT SUM(a.count) FROM {ad_statistics} a LEFT JOIN {node} n ON a.aid = n.nid WHERE uid = %d AND type = 'ad' AND (action = 'view' OR action = 'count') AND date >= %d AND date <= %d", $id, $day_start, $day_end)); | 791 } |
193 $click = (int)db_result(db_query("SELECT SUM(a.count) FROM {ad_statistics} a LEFT JOIN {node} n ON a.aid = n.nid WHERE uid = %d AND type = 'ad' AND action = 'click' AND date >= %d AND date <= %d", $id, $day_start, $day_end)); | 792 |
194 } | 793 // create graph |
195 else { | |
196 $function = "ad_report_views_$type"; | |
197 if (function_exists("$function")) { | |
198 $view = $function($id, $day_start, $day_end); | |
199 } | |
200 $function = "ad_report_clicks_$type"; | |
201 if (function_exists("$function")) { | |
202 $click = $function($id, $day_start, $day_end); | |
203 } | |
204 } | |
205 if ($view > $max_views) { | |
206 $max_views = $view; | |
207 } | |
208 $statistics[] = array( | |
209 'upper' => date($format_upper, $i), | |
210 'lower' => date($format_lower, $i), | |
211 'views' => $view, | |
212 'clicks' => $click | |
213 ); | |
214 } | |
215 | |
216 // Build graph image. | |
217 $image_width = 50 * $increments + 1; | |
218 $image_height = 300; | |
219 $graph_width = 50 * $increments; | |
220 $graph_height = 250; | |
221 | |
222 $graph = imagecreate($image_width, $image_height); | 794 $graph = imagecreate($image_width, $image_height); |
223 | 795 |
224 // Configure colors to use in chart. | 796 // configure colors to use in chart |
225 $color = array( | 797 $color = array( |
226 'white' => imagecolorallocate($graph, 255, 255, 255), | 798 'white' => imagecolorallocate($graph, 255, 255, 255), |
227 'black' => imagecolorallocate($graph, 0, 0, 0), | 799 'black' => imagecolorallocate($graph, 0, 0, 0), |
228 'grey' => imagecolorallocate($graph, 192, 192, 192), | 800 'grey' => imagecolorallocate($graph, 192, 192, 192), |
229 'blue' => imagecolorallocate($graph, 0, 0, 255), | 801 'blue' => imagecolorallocate($graph, 0, 0, 255), |
230 'orange' => imagecolorallocate($graph, 220, 210, 60), | 802 'orange' => imagecolorallocate($graph, 220, 210, 60), |
231 ); | 803 'red' => imagecolorallocate($graph, 255, 0, 0), |
232 | 804 ); |
233 // Draw the outside edges of the graph. | 805 |
234 imageline($graph, 0, 0, 0, $graph_height, $color['grey']); | 806 // determine how big the spacers should be |
235 imageline($graph, 0, 0, $graph_width, 0, $color['grey']); | 807 $max = $max_views > $max_clicks ? $max_views : $max_clicks; |
236 imageline($graph, $graph_width - 1, 0, $graph_width - 1, $graph_height, $color['grey']); | 808 $y_map = ceil($max / $graph_y / $graph_y) * $graph_y; |
237 imageline($graph, 0, $graph_height - 1, $graph_width - 1, $graph_height - 1, $color['grey']); | 809 $y_total = $y_map * $graph_y; |
238 | 810 |
239 // Draw a grid. | 811 if ($y_total) { |
240 for ($i = 0; $i < ($increments + 1); $i++) { | 812 // plot views and clicks on graph |
241 imageline($graph, $i*50, 0, $i*50, $graph_height, $color['grey']); | 813 foreach ($views as $key => $value) { |
242 } | 814 $view_height = $graph_height / $y_total * $value; |
243 for ($i = 0; $i < 11; $i++) { | 815 if ($view_height) { |
244 imageline($graph, 0, $i*25, $graph_width, $i*25, $color['grey']); | 816 imagefilledrectangle($graph, $graph_x_offset + $key * $width, $graph_y_offset + $graph_height - $view_height, $graph_x_offset + ($key + 1) * $width - 1, $graph_y_offset + $graph_height - 1, $color['blue']); |
245 } | 817 } |
246 | 818 $click_height = $graph_height / $y_total * $clicks[$key]; |
247 $multiply = 0; | 819 if ($click_height) { |
248 if ($max_views > $graph_height) { | 820 imagefilledrectangle($graph, $graph_x_offset + $key * $width, $graph_y_offset + $graph_height - $click_height, $graph_x_offset + ($key + 1) * $width - 1, $graph_y_offset + $graph_height - 1, $color['red']); |
249 if (!$multiply) { | 821 } |
250 $multiply = .9; | 822 } |
251 } | 823 } |
252 while (($max_views * $multiply) >= $graph_height) { | 824 |
253 $multiply *= .9; | 825 // add scale to y |
254 } | 826 if ($y_map) { |
255 } | 827 $graph_y_width = $graph_height / $graph_y; |
256 else if ($max_views) { | 828 for ($i = 1; $i <= $graph_y; $i++) { |
257 while (($max_views * ($multiply + 1)) <= $graph_height) { | 829 $text = number_format($i * $y_map); |
258 $multiply++; | 830 $len = strlen($text); |
259 } | 831 $x_offset = $graph_width + 14; |
260 } | 832 $y_pos = $graph_height - $i * $graph_y_width; |
261 | 833 //imagestring($graph, 1, $x_offset, $graph_y_offset + $y_pos - 3, $text, $color['black']); |
262 // Display impressions. | 834 imagestring($graph, 2, $x_offset, $graph_y_offset + $y_pos - 7, $text, $color['black']); |
263 for ($i = 0; $i < $increments ; $i++) { | 835 } |
264 $view = $multiply ? $statistics[$i]['views'] * $multiply : $statistics[$i]['views']; | 836 } |
265 if ($view) { | 837 else { |
266 imagefilledrectangle($graph, $i*50 + 4, $graph_height-$view, ($i+1)*50, $graph_height, $color['grey']); | 838 $graph_y_width = 0; |
267 $string_height = $view < 10 ? $graph_height - 10 : $graph_height - $view; | 839 } |
268 imagestring($graph, 2, $i*50 + 15, $string_height, $statistics[$i]['views'], $color['black']); | 840 |
269 } | 841 // add scale to x |
270 // Display timestamp | 842 $graph_x = _ad_report_select_x($number, 8, 0); |
271 imagestring($graph, 2, $i*50 + 2, 255, $statistics[$i]['upper'], $color['black']); | 843 $offset = $elapse / $graph_x; |
272 imagestring($graph, 2, $i*50 + 3, 265, $statistics[$i]['lower'], $color['black']); | 844 $graph_x_width = $graph_width / $graph_x; |
273 } | 845 $x_offset = $graph_x_width / 2; |
274 | 846 for ($i = 1; $i <= $graph_x; $i++) { |
275 // Display clicks. | 847 $text = date('M d, Y H', $start + ($offset * $i) - $offset / 2); |
276 for ($i = 0; $i < $increments; $i++) { | 848 $len = strlen($text); |
277 $click = $multiply ? $statistics[$i]['clicks'] * $multiply : $statistics[$i]['clicks']; | 849 $x_pos = $graph_x_offset - $x_offset + $i * $graph_x_width - 7; |
278 if ($click) { | 850 $y_pos = $graph_height + $graph_y_offset + ($len * 6) + 3; |
279 imagefilledrectangle($graph, $i*50 + 10, $graph_height-$click, ($i+1)*50, $graph_height, $color['blue']); | 851 imagestringup($graph, 2, $x_pos, $y_pos, $text, $color['black']); |
280 $string_height = $click < 10 ? $graph_height - 10 : $graph_height - $click; | 852 //$x_pos = $graph_x_offset - $x_offset + $i * $graph_x_width - 4; |
281 imagestring($graph, 2, $i*50 + 20, $string_height, $statistics[$i]['clicks'], $color['white']); | 853 //$y_pos = $graph_height + $graph_y_offset + ($len * 5) + 3; |
282 } | 854 //imagestringup($graph, 1, $x_pos, $y_pos, $text, $color['black']); |
283 } | 855 } |
284 | 856 |
857 // draw a grid | |
858 $style = array($color['grey'], IMG_COLOR_TRANSPARENT, IMG_COLOR_TRANSPARENT); | |
859 imagesetstyle($graph, $style); | |
860 for ($i = 1; $i <= $graph_x; $i++) { | |
861 imageline($graph, $graph_x_offset + $i * $graph_x_width - $graph_x_width / 2, $graph_y_offset, $graph_x_offset + $i * $graph_x_width - $graph_x_width / 2, $graph_y_offset + $graph_height - 1, IMG_COLOR_STYLED); | |
862 } | |
863 for ($i = 1; $i < $graph_y; $i++) { | |
864 imageline($graph, $graph_x_offset, $graph_y_offset + $i * $graph_y_width, $graph_x_offset + $graph_width, $graph_y_offset + $i * $graph_y_width, IMG_COLOR_STYLED); | |
865 } | |
866 // left, right, top, and bottom borders, respectively | |
867 imageline($graph, $graph_x_offset, $graph_y_offset, $graph_x_offset, $graph_y_offset + $graph_height, $color['grey']); | |
868 imageline($graph, $graph_x_offset + $graph_width - 1, $graph_y_offset, $graph_x_offset + $graph_width - 1, $graph_y_offset + $graph_height, $color['grey']); | |
869 imageline($graph, $graph_x_offset, $graph_y_offset, $graph_x_offset + $graph_width - 1, $graph_y_offset, $color['grey']); | |
870 imageline($graph, $graph_x_offset, $graph_y_offset + $graph_height, $graph_x_offset + $graph_width - 1, $graph_y_offset + $graph_height, $color['grey']); | |
871 | |
872 // display the graph | |
285 imagepng($graph); | 873 imagepng($graph); |
286 imagedestroy($graph); | 874 imagedestroy($graph); |
287 | 875 } |
288 } | 876 |
289 | 877 /** |
878 * Figure out how many x columns to display. | |
879 * TODO: Find a better algorithm than this slop. | |
880 */ | |
881 function _ad_report_select_x($number, $divisor, $diff) { | |
882 if ($divisor < 2) { | |
883 return $number; | |
884 } | |
885 $divisor = $divisor + $diff; | |
886 if ($divisor == 0) { | |
887 $divisor = $divisor + $diff; | |
888 } | |
889 $result = (int)($number / $divisor); | |
890 if ($result < 8) { | |
891 $diff -= 1; | |
892 if ($diff) { | |
893 return _ad_report_select_x($number, $divisor, $diff); | |
894 } | |
895 } | |
896 else if ($result > 12) { | |
897 $diff += 1; | |
898 if ($diff) { | |
899 return _ad_report_select_x($number, $divisor, $diff); | |
900 } | |
901 } | |
902 return $result; | |
903 } |