Mercurial > defr > drupal > ad
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 |
