comparison adserve.inc @ 0:d8a3998dac8e ad

ajout module ad
author pierre
date Fri, 20 Feb 2009 14:04:09 +0000
parents
children 948362c2a207
comparison
equal deleted inserted replaced
-1:000000000000 0:d8a3998dac8e
1 <?php
2 // $Id: adserve.inc,v 1.1.2.31.2.8 2009/02/17 19:22:45 jeremy Exp $
3
4 /**
5 * @file
6 * Configuration.
7 *
8 * Copyright (c) 2005-2009.
9 * Jeremy Andrews <jeremy@tag1consulting.com>.
10 *
11 * By default, adserve configuration happens dynamically as ads are served.
12 * However, it is possible to override dynamic settings with static defaults.
13 * Refer to the documentation/ADSERVE_CONFIGURATION.txt for details on adding
14 * adserve overrides to settings.php.
15 *
16 * Note that the path to Drupal's root directory can not be overriden in
17 * settings.php as adserve needs this path to find settings.php in the first
18 * place. To hard code the path to Drupal's root directory, uncomment the
19 * following define statement, and set the correct path. This is not generally
20 * required. On a Unix server this path will be something like '/path/to/web'.
21 * On a Windows server this path will be something like 'D:\path\to\web'.
22 */
23 //define('DRUPAL_ROOT', '/var/www/html');
24
25 /**
26 * The main adserve logic.
27 */
28 function adserve_ad($options = array()) {
29 static $displayed_count = 0;
30
31 // If no $options are passed in, assume we're using JavaScript.
32 if (!empty($options)) {
33 adserve_variable('variable_load', $options);
34 }
35 else {
36 adserve_variable('variable_load');
37 }
38 adserve_bootstrap(0);
39
40 adserve_debug();
41
42 adserve_variable('error', FALSE);
43 $output = NULL;
44 if (adserve_variable('adcache') != 'none') {
45 /**
46 * Ad caches are defined through external modules. Ad caches are composed
47 * of a module 'ad_cache_TYPE.module' and an include file
48 * 'ad_cache_TYPE.inc' that live in the 'cache/TYPE' subdirectory where
49 * 'TYPE' is replaced with the type of cache. For example, the included
50 * file cache lives in 'cache/file'.
51 *
52 * The ad_cache_TYPE.inc file must have a function named ad_cache_TYPE()
53 * which is used to display ads. It can optionally include a function
54 * titled ad_cache_TYPE_variables used to extract any necessary
55 * variables from the global $_GET array (this can also be used to override
56 * values that would normally be set from $_GET). Any functions used
57 * by this code without bootstrapping Drupal should also be in this file.
58 *
59 * The ad_cache_TYPE.module file should define the drupal _help() hook
60 * so the module can be enabled. It should also define the _adcacheapi()
61 * hook allowing for configuration and processing. Any functions used by
62 * this code after bootstrapping Drupal should also be in this module.
63 *
64 * Refer to cache/file/* for an implementation example.
65 */
66 $function = 'ad_cache_'. adserve_variable('adcache');
67 $output = adserve_invoke_file($function);
68
69 }
70
71 // If there's no output, we assume either there's no cache enabled, or the
72 // cache failed.
73 // TODO: Log failures with the watchdog.
74 if ($output == NULL) {
75 if (adserve_variable('debug')) {
76 echo "No cache enabled.<br />\n";
77 }
78
79 adserve_bootstrap();
80
81 if (adserve_variable('nids')) {
82 $id = adserve_variable('nids');
83 $type = 'nids';
84 adserve_variable('group', "n$id");
85
86 // Retrieve all active advertisements from the provided nid list.
87 $sql = "SELECT aid FROM {ads} WHERE adstatus = 'active' AND aid IN (%s)";
88 $result = db_query($sql, $id);
89
90 if (adserve_variable('debug')) {
91 echo "Searching for ad from nid list: $id.<br />\n";
92 echo "Query: \"$sql;\"<br />\n";
93 }
94 }
95 else if (adserve_variable('tids')) {
96 $id = adserve_variable('tids');
97 $type = 'tids';
98 adserve_variable('group', "t$id");
99
100 // Retrieve all active advertisements from the provided tid list.
101 $sql = "SELECT a.aid FROM {ads} a INNER JOIN {term_node} n ON a.aid = n.nid WHERE a.adstatus = 'active' AND n.tid IN (%s)";
102 $result = db_query($sql, $id);
103
104 if (adserve_variable('debug')) {
105 echo "Searching for ad from tid list: $id.<br />\n";
106 echo "Query: \"$sql;\"<br />\n";
107 }
108 }
109 else {
110 $id = 0;
111 $type = 'default';
112 adserve_variable('group', "$id");
113
114 // Randomly determine which ad to display from those that do not have
115 // any tid assigned to them.
116 $sql = "SELECT a.aid FROM {ads} a LEFT JOIN {term_node} n ON a.aid = n.nid WHERE a.adstatus = 'active' AND n.tid IS NULL";
117 $result = db_query($sql);
118
119 if (adserve_variable('debug')) {
120 echo "Searching for ads with no tids.<br />\n";
121 echo "Query: \"$sql;\"<br />\n";
122 }
123 }
124
125 // Build list of all available ads to choose from.
126 $available = array();
127 while ($ad = db_fetch_object($result)) {
128 $available[$ad->aid] = $ad->aid;
129 }
130 if (adserve_variable('debug')) {
131 echo 'Available ads: ';
132 if (sizeof($ads)) {
133 echo implode(', ', $available) ."<br />";
134 }
135 else {
136 echo 'none<br />';
137 }
138 }
139
140 // Randomly select from available advertisements.
141 $selected = adserve_select_ad($available, adserve_variable('quantity'));
142
143 $output = '';
144 $ads = 0;
145 $details = array();
146 $ids = array();
147 // Include appropriate module for displaying selected ad.
148 foreach ($selected as $aid) {
149 $ids[$aid] = $aid;
150 $ads++;
151 $detail = $details[$aid] = node_load($aid);
152 if (!isset($modules[$detail->adtype])) {
153 $modules[$detail->adtype] = db_result(db_query("SELECT filename FROM {system} WHERE name = '%s'", 'ad_'. $detail->adtype));
154 }
155 if (adserve_variable('debug')) {
156 echo 'ad: <pre>';
157 print_r($detail);
158 echo '</pre>';
159 echo "Loading module '". $modules[$detail->adtype] ."'.<br />\n";
160 }
161 include_once $modules[$detail->adtype];
162
163 if ($output) {
164 // Add a div between ads that themers can use to arrange ads when
165 // displaying more than one at a time.
166 $displayed_count++;
167 $output .= "<div class=\"advertisement-space\" id=\"space-$id-$displayed_count\"></div>";
168 }
169 $output .= module_invoke("ad_$detail->adtype", 'display_ad', $detail);
170
171 // Update the ad's impressions counter.
172 if (adserve_variable('ad_display') == 'raw') {
173 $output .= ad_display_image($detail);
174 }
175 else {
176 adserve_increment($detail);
177 }
178 }
179 adserve_variable("$type-ids", $ids);
180 if (empty($ads)) {
181 adserve_variable('error', TRUE);
182 $output = 'No active ads were found in the '. (empty($nids) ? 'tids' : 'nids') ." '$id'.";
183 adserve_increment(NULL, 'count');
184 }
185 if (adserve_variable('debug')) {
186 echo "Ads displayed: $ads<br />";
187 }
188 }
189
190 $hostid = adserve_variable('hostid');
191 $group = adserve_variable('group');
192 $replace = "/$group";
193 if (!empty($hostid)) {
194 $replace .= "/$hostid";
195 }
196 if ($url = htmlentities(adserve_variable('url'))) {
197 $replace .= "?u=$url";
198 }
199
200 $output = preg_replace('&/@HOSTID___&', $replace, $output);
201 if (adserve_variable('error')) {
202 $output = "<!-- $output -->";
203 }
204
205 /**
206 * Modules can add custom code to be displayed before or after ads are
207 * displayed. For example, you many want to add a tagline, "Powered by
208 * Drupal". To do so, define 'adserve_exit_text' within your module's
209 * adapi hook.
210 *
211 * Code sample for adserve_exit_text example:
212 *
213 * sample_adapi($op, $ad) {
214 * case 'adserve_exit_text':
215 * return array(
216 * 'sample' => array(
217 * 'text' => t('Powered by Drupal'),
218 * )
219 * );
220 * }
221 *
222 * As another example use case, you could also use the _init_text and
223 * _exit_text hooks to wrap all advertisements in a custom div.
224 */
225 $init = TRUE;
226 foreach (array('adserve_init_text', 'adserve_exit_text') as $hook) {
227 $result = adserve_invoke_hook($hook);
228 if (is_array($result)) {
229 $append = '';
230 foreach ($result as $text) {
231 if ($text['text']) {
232 $append .= $text['text'];
233 }
234 }
235 if ($init) {
236 $output = $append . $output;
237 }
238 else {
239 $output .= $append;
240 }
241 }
242 $init = FALSE;
243 }
244
245 switch (adserve_variable('ad_display')) {
246 case 'iframe':
247 case 'jquery':
248 if (!adserve_variable('debug')) {
249 // Tell the web browser not to cache this frame so the ad refreshes
250 // each time the page is viewed.
251
252 // Expires in the past:
253 header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
254 // Last load:
255 header('Last-Modified: '. gmdate('D, d M Y H:i:s') .' GMT');
256 // HTTP 1.1:
257 header('Cache-Control: no-store, no-cache, must-revalidate');
258 header('Cache-Control: post-check=0, pre-check=0', FALSE);
259 // HTTP 1.0:
260 header('Pragma: no-cache');
261 }
262 print "$output";
263 exit(0);
264 case 'javascript':
265 default:
266 $output = str_replace(array("\r", "\n", "<", ">", "&"),
267 array('\r', '\n', '\x3c', '\x3e', '\x26'),
268 addslashes($output));
269 if (!adserve_variable('debug')) {
270 // Tell the web browser not to cache this script so the ad refreshes
271 // each time the page is viewed.
272 // Expires in the past:
273 header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
274 // Last load:
275 header('Last-Modified: '. gmdate('D, d M Y H:i:s') .' GMT');
276 // HTTP 1.1:
277 header('Cache-Control: no-store, no-cache, must-revalidate');
278 header('Cache-Control: post-check=0, pre-check=0', FALSE);
279 // HTTP 1.0:
280 header('Pragma: no-cache');
281 // Output is a JavaScript:
282 header('Content-Type: application/x-javascript; charset=utf-8');
283 }
284 print "document.write('$output');";
285 exit(0);
286 case 'raw':
287 chdir(adserve_variable('ad_dir'));
288 return $output;
289 }
290 }
291
292 /**
293 * Retrieve variables from $_GET array or from passed in $value array.
294 */
295 function adserve_variable($variable, $value = NULL) {
296 global $conf;
297 static $variables = NULL, $overridden = NULL, $cache_loaded = array();
298
299 // Update the value, if set.
300 if (isset($value)) {
301 $variables->$variable = $value;
302 }
303
304 if (!isset($variables->loaded) || $variable == 'variable_load') {
305 if ($variable == 'variable_load' && isset($value)) {
306 $values['debug'] = isset($value['debug']) ? $value['debug'] : '';
307 $values['c'] = isset($value['adcache']) ? $value['adcache'] : '';
308 $values['n'] = isset($value['nids']) ? $value['nids'] : '';
309 $values['t'] = isset($value['tids']) ? $value['tids'] : '';
310 $values['k'] = isset($value['hostid']) ? $value['hostid'] : '';
311 $values['q'] = isset($value['quantity']) ? $value['quantity'] : 1;
312 $values['m'] = isset($value['ad_display']) ? $value['ad_display'] : 0;
313 unset($value);
314 }
315 else {
316 $values = $_GET;
317 }
318
319 // Don't use getcwd as path may involve symbolic links
320 $variables->ad_dir = dirname($_SERVER['SCRIPT_FILENAME']);
321 // 'debug' is an integer.
322 $variables->debug = isset($values['debug']) ? (int)$values['debug'] : 0;
323 // Cache types are comprised of only letters.
324 $variables->adcache = isset($values['c']) ? preg_replace('/[^a-zA-Z]/', '', $values['c']) : 'none';
325 // Nids is an integer or a ",".
326 $variables->nids = isset($values['n']) ? preg_replace('/[^0-9,]/', '', $values['n']) : '';
327 // Tids is an integer or a ",".
328 $variables->tids = isset($values['t']) ? preg_replace('/[^0-9,]/', '', $values['t']) : '';
329 // Hostid is an md5() which is comprised of numbers and letters a-f.
330 $variables->hostid = isset($values['k']) ? preg_replace('/[^0-9a-f]/', '', $values['k']) : '';
331 // Click url
332 $variables->url = isset($values['u']) ? $values['u'] : '';
333 // Quantity is an integer.
334 $variables->quantity = isset($values['q']) ? (int)$values['q'] : 0;
335 // Ad ID is an integer.
336 $variables->aid = isset($values['a']) ? (int)$values['a'] : 0;
337 // Method is compriese of only letters.
338 $variables->ad_display = isset($values['m']) ? preg_replace('/[^a-zA-Z]/', '', $values['m']) : 'javascript';
339
340 // Set defaults.
341 $variables->quantity = $variables->quantity ? $variables->quantity : 1;
342
343 if ($variables->debug) {
344 foreach ($variables as $variable => $val) {
345 echo "$variable: '$val'<br />\n";
346 }
347 if ($variables->debug == 1) exit;
348 }
349 $variables->loaded = TRUE;
350
351 // Override the value, if set during initialization.
352 if (isset($value)) {
353 $variables->$variable = $value;
354 }
355 }
356
357 if (!$overridden) {
358 if (isset($conf)) {
359 foreach ($conf as $var => $val) {
360 $variables->$var = $val;
361 if ($variables->debug) {
362 echo "Override $var: '$val'<br />\n";
363 }
364 }
365 $overridden = TRUE;
366 }
367 }
368
369 if (!isset($cache_loaded[$variables->adcache])) {
370 // Retrieve variables defined by cache plugin, if enabled.
371 if ($variables->adcache != 'none') {
372 $include = $variables->ad_dir ."/cache/$variables->adcache/ad_cache_$variables->adcache.inc";
373 if (file_exists($include)) {
374 if ($variables->debug) {
375 echo "Attempting to include cache include file '$include'.<br />\n";
376 }
377 require_once($include);
378 }
379 else if ($variables->debug) {
380 echo "Failed to find cache include file '$include'.<br />\n";
381 }
382 $function = 'ad_cache_'. $variables->adcache .'_variables';
383 if (function_exists($function)) {
384 $external_variables = $function();
385 foreach ($external_variables as $key => $val) {
386 if (!isset($variables->$key)) {
387 $variables->$key = $val;
388 }
389 }
390 }
391 }
392 $cache_loaded[$variables->adcache] = TRUE;
393 }
394
395 if ($variable == 'variable_dump') {
396 echo "Dumping \$variables:<br />\n";
397 echo '<pre>';
398 foreach ($variables as $var => $val) {
399 echo " $var($val)<br />\n";
400 }
401 echo '</pre>';
402 }
403
404 if (isset($variables->$variable)) {
405 return $variables->$variable;
406 }
407 else {
408 return NULL;
409 }
410 }
411
412 /**
413 * Invoke a function in the specified file.
414 */
415 function adserve_invoke_file($function, $arg1 = NULL, $arg2 = NULL) {
416 $output = '';
417 if (function_exists($function)) {
418 $output = $function($arg1, $arg2);
419 }
420 else if (adserve_variable('debug')) {
421 echo "Function '$function' does not exist.<br />\n";
422 }
423 return $output;
424 }
425
426 /**
427 * Invoke adserve hooks, defined in adapi with adserve_HOOK.
428 */
429 function adserve_invoke_hook($hook, $a1 = NULL, $a2 = NULL) {
430 if (adserve_variable('adcache') != 'none') {
431 $cache = adserve_variable('adcache');
432 _debug_echo("Invoking adserve hook '$hook' in $cache cache.");
433 // Get information from cache.
434 return adserve_invoke_file("ad_cache_{$cache}_$hook", $a1, $a2);
435 }
436 else {
437 _debug_echo("Invoking adserve hook '$hook'.");
438 // Get information from Drupal variable table.
439 $actions = variable_get($hook, '');
440 $return = array();
441 if (!empty($actions)) {
442 $actions = unserialize($actions);
443 foreach ($actions as $name => $action) {
444 if ($action['function']) {
445 $function = $action['function'];
446 if (!function_exists($function)) {
447 if ($action['path']) {
448 _debug_echo("Including file '". $action['path'] ."'.");
449 include_once($action['path']);
450 }
451 }
452 if (function_exists($function)) {
453 _debug_echo("Invoking function '$function'.");
454 $return[] = $function($a1, $a2);
455 }
456 else if (adserve_variable('debug')) {
457 echo "Function '$function' does not exist.<br />\n";
458 }
459 }
460 else {
461 $return[] = $action;
462 }
463 }
464 }
465 return $return;
466 }
467 // Retreive hook definition from cache if using, or from variable_get
468 // return hook action.
469 }
470
471 function _debug_echo($text) {
472 if (adserve_variable('debug')) {
473 echo "$text<br />\n";
474 }
475 }
476
477 /**
478 * Remove one or more ids from array.
479 * TODO: Optimize. Perhaps something like array_flip, unset, array_flip.
480 * @param $ids An array of ID's, ie array(5, 8, 9, 11).
481 * @param $remove An ID or an array of ID's to be removed from $ids.
482 */
483 function adserve_select_reindex($ids, $remove) {
484 $new = array();
485 // Walk through array of IDs and decide what to keep.
486 foreach ($ids as $id) {
487 // If $remove is an array, walk through array to decide fate of ID.
488 if (is_array($remove)) {
489 $keep = TRUE;
490 foreach ($remove as $rem) {
491 // Loop until we find one that matches or reach end of array.
492 if ($id == $rem) {
493 $keep = FALSE;
494 break;
495 }
496 }
497 if ($keep) {
498 $new[] = $id;
499 }
500 }
501 else {
502 if ($id != $remove) {
503 $new[] = $id;
504 }
505 }
506 }
507 return $new;
508 }
509
510 /**
511 * Disabled: will be re-implemented with new adserve hooks introduced for
512 * geotargeting.
513 function adserve_invoke_weight($ads, $quantity = 1, $invalid = array()) {
514 $parent = adserve_variable('ad_dir') .'/weight';
515 if (is_dir($parent) && $handle = opendir($parent)) {
516 while ($dir = readdir($handle)) {
517 if (is_dir("$parent/$dir") && !in_array($dir, array('.', '..', 'CVS'))) {
518 $include = "$parent/$dir/ad_weight_$dir.inc";
519 if (file_exists($include)) {
520 require_once($include);
521 $function = "ad_weight_{$dir}_select_ad";
522 if (function_exists($function)) {
523 $return = $function($ads, $quantity, $invalid);
524 // First come, first serve. We found an ad_weight function that
525 // returned something, so we'll take it.
526 if ($return) {
527 return $return;
528 }
529 }
530 }
531 }
532 }
533 }
534 }
535 */
536
537 /**
538 * Simple default function to randomly select an ad. Provides a hook to allow
539 * the definition of external display methods.
540 * @param An array of valid ad IDs, ie array(5, 8, 9, 11).
541 * @param Optional, how many unique ads to select.
542 * @param Optional, an array of invalid IDs.
543 */
544 function adserve_select_ad($ads, $quantity = 1, $invalid = array()) {
545 //adserve_invoke_weight($ads, $quantity, $invalid);
546
547 $ids = array();
548 $id = 0;
549 $total = sizeof($ads);
550 _debug_echo("Selecting $quantity ad(s) from $total total ad(s).");
551 if (is_array($ads)) {
552 $ads = adserve_select_reindex($ads, $invalid);
553 $total = sizeof($ads);
554 for ($i = 0; $i < $quantity; $i++) {
555 _debug_echo('Randomly selecting ad: '. ($i + 1) ." of $quantity.");
556 $id = 0;
557 // Randomly select a unique banner to display. We subtract 1 as arrays
558 // start at 0.
559 $return = adserve_invoke_hook('adserve_select', $ads, $invalid);
560 if (is_array($return) && !empty($return)) {
561 foreach ($return as $id) {
562 // First come first serve.
563 if ((int)$id) break;
564 }
565 }
566 if ($id >= 0 && sizeof($ads)) {
567 if ($id == 0) {
568 _debug_echo("Default ID selection in adserve.inc.");
569 $id = $total > 1 ? $ads[mt_rand(0, $total - 1)] : $ads[0];
570 _debug_echo("Randomly selected ID: $id.");
571 }
572 if ($id > 0) {
573 $ids[] = $id;
574 }
575 }
576 else {
577 // There are no more valid advertisements left to display.
578 break;
579 }
580 $invalid[] = $id;
581 $ads = adserve_select_reindex($ads, $id);
582 $total = sizeof($ads);
583 // We're out of ads to display.
584 if ($total <= 0) {
585 break;
586 }
587 }
588 }
589 return $ids;
590 }
591
592 /**
593 * Include Drupal's bootstrap.inc.
594 */
595 function adserve_include_drupal() {
596 // For optimal performance set DRUPAL_ROOT at the top of this file.
597 if (defined('DRUPAL_ROOT')) {
598 if (is_dir(DRUPAL_ROOT) && file_exists(DRUPAL_ROOT .'/includes/bootstrap.inc')) {
599 chdir(DRUPAL_ROOT);
600 adserve_variable('root_dir', DRUPAL_ROOT);
601 }
602 else {
603 echo 'Invalid DRUPAL_ROOT ('. DRUPAL_ROOT .') defined in adserve.inc';
604 }
605 }
606 else {
607 $path = explode('/', adserve_variable('ad_dir'));
608 while (!empty($path)) {
609 // Search for top level Drupal directory to perform bootstrap.
610 chdir(implode('/', $path));
611 if (file_exists('./includes/bootstrap.inc')) {
612 adserve_variable('root_dir', getcwd());
613 break;
614 }
615 array_pop($path);
616 }
617 }
618 require_once adserve_variable('root_dir') .'/includes/bootstrap.inc';
619 }
620
621 /**
622 * Include the necessary files and call the Drupal bootstrap.
623 */
624 function adserve_bootstrap($bootstrap = NULL) {
625 adserve_include_drupal();
626
627 // If no specific bootstrap is specified, do a full bootstrap.
628 if (!isset($bootstrap)) {
629 $bootstrap = DRUPAL_BOOTSTRAP_FULL;
630 }
631
632 if (adserve_variable('debug')) {
633 echo "Drupal bootstrap '". $bootstrap ."'.<br />\n";
634 }
635
636 drupal_bootstrap($bootstrap);
637 }
638
639 /**
640 * Increment ad counters. Increment in cache if enabled.
641 */
642 function adserve_increment($ad, $action = 'view') {
643 $cache = adserve_variable('adcache');
644 if (adserve_variable('debug')) {
645 echo "adserve_increment action($action) cache($cache)<br />\n";
646 }
647 if (is_object($ad) && isset($ad->aid)) {
648 $aid = $ad->aid;
649 }
650 else {
651 $aid = 0;
652 }
653 if ($cache != 'none') {
654 $rc = adserve_invoke_file("ad_cache_{$cache}_increment", $action, $aid);
655 if ($rc) return;
656 }
657 adserve_bootstrap();
658 // Update impressions statistics.
659 db_query("UPDATE {ad_statistics} SET count = count + 1 WHERE aid = %d AND action = '%s' AND date = %d AND adgroup = '%s' AND hostid = '%s'", $aid, $action, date('YmdH'), adserve_variable('group'), adserve_variable('hostid'));
660 // If column doesn't already exist, we need to add it.
661 if (!db_affected_rows()) {
662 db_query("INSERT INTO {ad_statistics} (aid, date, action, adgroup, hostid, count) VALUES(%d, %d, '%s', '%s', '%s', 1)", $aid, date('YmdH'), $action, adserve_variable('hostid'), adserve_variable('hostid'));
663 // If another process already added this row our INSERT will fail, if
664 // so we still need to increment it so we don't loose an impression.
665 if (!db_affected_rows()) {
666 db_query("UPDATE {ad_statistics} SET count = count + 1 WHERE aid = %d AND action = '%s' AND date = %d AND adgroup = '%s' AND hostid = '%s'", $aid, $action, date('YmdH'), adserve_variable('group'), adserve_variable('hostid'));
667 }
668 }
669
670 if ($action == 'view') {
671 // See if we need to perform additional queries.
672 if (isset($ad->maxviews) && $ad->maxviews > 0) {
673 $views = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} WHERE aid = %d AND action = 'view' AND date >= %d", $aid, date('YmdH', $ad->activated)));
674 if ($views >= $ad->maxviews) {
675 db_query("UPDATE {ads} SET adstatus = 'expired', autoexpire = 0, autoexpired = %d, expired = %d WHERE aid = %d", time(), time(), $aid);
676 ad_statistics_increment($aid, 'autoexpired');
677 ad_statistics_increment($aid, 'expired');
678 }
679 }
680 }
681 // TODO: Do we need to do this here? Can it happen when a new click is
682 // registered?
683 if (isset($ad->maxclicks) && $ad->maxclicks > 0) {
684 $clicks = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} WHERE aid = %d AND action = 'click' AND date >= %d", $aid, date('YmdH', $ad->activated)));
685 if ($clicks >= $ad->maxclicks) {
686 db_query("UPDATE {ads} SET adstatus = 'expired', autoexpire = 0, autoexpired = %d, expired = %d WHERE aid = %d", time(), time(), $aid);
687 ad_statistics_increment($aid, 'autoexpired');
688 ad_statistics_increment($aid, 'expired');
689 }
690 }
691 }
692
693 /**
694 * Display additional debug information.
695 */
696 function adserve_debug() {
697 if (adserve_variable('debug')) {
698 echo "Root drupal directory detected as '". adserve_variable('root_dir') ."'.<br />\n<br />\n";
699
700 $ad_dir = adserve_variable('ad_dir');
701 $files = array("$ad_dir/serve.php", "$ad_dir/ad.module");
702 if (adserve_variable('debug') > 2) {
703 $files = array_merge($files, array("$ad_dir/ad.install"));
704 }
705 if (adserve_variable('debug') > 3) {
706 $files = array_merge($files, array("$ad_dir/image/ad_image.module", "$ad_dir/image/ad_image.install", "$ad_dir/text/ad_text.module", "$ad_dir/text/ad_text.install", "$ad_dir/embed/ad_embed.module", "$ad_dir/report/ad_report.module", "$ad_dir/notify/ad_notify.module", "$ad_dir/notify/ad_notify.install"));
707 }
708 foreach ($files as $file) {
709 if (!file_exists($file)) {
710 echo "Error: '$file' does not exist!<br />\n";
711 }
712 else if (!is_readable($file)) {
713 echo "Error: '$file' is not readable!<br />\n";
714 }
715 else {
716 $fd = fopen($file, 'r');
717 while (!feof($fd)) {
718 $line = fgets($fd);
719 if (substr($line, 0, 5) == "<?php") {
720 continue;
721 }
722 else {
723 echo "$file: $line<br />";
724 break;
725 }
726 }
727 }
728 }
729 echo "<br />\n";
730 }
731 }
732