Skip to content
adserve.inc 10.4 KiB
Newer Older
jeremy's avatar
jeremy committed
<?php
// $Id$

jeremy's avatar
jeremy committed
/**
jeremy's avatar
jeremy committed
 * Configuration.
 *
jeremy's avatar
jeremy committed
 * Copyright (c) 2005-2009.
 *   Jeremy Andrews <jeremy@tag1consulting.com>.
 *
jeremy's avatar
jeremy committed
 * By default, adserve configuration happens dynamically as ads are served.
 * However, it is possible to override dynamic settings with static defaults.
 * Refer to the documentation/ADSERVE_CONFIGURATION.txt for details on adding
 * adserve overrides to settings.php.
 *
 * Note that the path to Drupal's root directory can not be overriden in
 * settings.php as adserve needs this path to find settings.php in the first
 * place.  To hard code the path to Drupal's root directory, uncomment the
 * following define statement, and set the correct path.  This is not generally
jeremy's avatar
jeremy committed
 * required.  On a Unix server this path will be something like '/path/to/web'.
 * On a Windows server this path will be something like 'D:\path\to\web'.
jeremy's avatar
jeremy committed
 */
//define('DRUPAL_ROOT', '/var/www/html');

jeremy's avatar
jeremy committed
/**
 * The main adserve logic.
 */
jeremy's avatar
jeremy committed
function adserve_ad($options = array()) {
jeremy's avatar
jeremy committed
  static $displayed_count = 0;

jeremy's avatar
jeremy committed
  // if no $options are passed in, assume we're using JavaScript
jeremy's avatar
jeremy committed
  if (!empty($options)) {
jeremy's avatar
jeremy committed
    adserve_variable('variable_load', $options);
  }
jeremy's avatar
jeremy committed
  else {
    adserve_variable('variable_load');
  }
jeremy's avatar
jeremy committed
  // include Drupal's settings.php
jeremy's avatar
jeremy committed
  adserve_bootstrap(0);
jeremy's avatar
jeremy committed

jeremy's avatar
jeremy committed
  // if debug enabled, dump current state
jeremy's avatar
jeremy committed
  adserve_debug();

jeremy's avatar
jeremy committed
  // start with 'error' set to false
jeremy's avatar
jeremy committed
  adserve_variable('error', FALSE);
jeremy's avatar
jeremy committed

jeremy's avatar
jeremy committed
  // invoke cache function (file already included in adserve_variable)
  $ids = adserve_cache('get_ad_ids');
jeremy's avatar
jeremy committed

jeremy's avatar
jeremy committed
  // display the advertisement(s)
jeremy's avatar
jeremy committed
  return adserve_cache('display', $ids);
jeremy's avatar
jeremy committed
}

/**
jeremy's avatar
jeremy committed
 * Retrieve variables from $_GET array or from passed in $value array.
jeremy's avatar
jeremy committed
 */
jeremy's avatar
jeremy committed
function adserve_variable($variable, $value = NULL) {
jeremy's avatar
jeremy committed
  global $conf;
  static $variables = NULL, $overridden = NULL, $cache_loaded = array();
jeremy's avatar
jeremy committed

jeremy's avatar
jeremy committed
  // Declare variables if not already declared.
  if ($variables === NULL) {
    $variables = new stdClass();
  }

jeremy's avatar
jeremy committed
  // Update the value, if set.
  if (isset($value)) {
    $variables->$variable = $value;
  }

jeremy's avatar
jeremy committed
  if (!isset($variables->loaded) || $variable == 'variable_load') {
jeremy's avatar
jeremy committed
    if ($variable == 'variable_load' && isset($value)) {
jeremy's avatar
jeremy committed
      $values['debug'] = isset($value['debug']) ? $value['debug'] : '';
      $values['c'] = isset($value['adcache']) ? $value['adcache'] : '';
      $values['n'] = isset($value['nids']) ? $value['nids'] : '';
      $values['t'] = isset($value['tids']) ? $value['tids'] : '';
      $values['k'] = isset($value['hostid']) ? $value['hostid'] : '';
      $values['q'] = isset($value['quantity']) ? $value['quantity'] : 1;
      $values['m'] = isset($value['ad_display']) ? $value['ad_display'] : 0;
jeremy's avatar
jeremy committed
      unset($value);
    }
    else {
      $values = $_GET;
    }
jeremy's avatar
jeremy committed

jeremy's avatar
jeremy committed
    // Don't use getcwd as path may involve symbolic links
    $variables->ad_dir = dirname($_SERVER['SCRIPT_FILENAME']);
jeremy's avatar
jeremy committed
    // 'debug' is an integer.
jeremy's avatar
jeremy committed
    $variables->debug = isset($values['debug']) ? (int)$values['debug'] : 0;
jeremy's avatar
jeremy committed
    // Cache types are comprised of only letters.
jeremy's avatar
jeremy committed
    $variables->adcache = isset($values['c']) ? preg_replace('/[^a-zA-Z]/', '', $values['c']) : 'none';
jeremy's avatar
jeremy committed
    // Nids is an integer or a ",".
jeremy's avatar
jeremy committed
    $variables->nids = isset($values['n']) ? preg_replace('/[^0-9,]/', '', $values['n']) : '';
jeremy's avatar
jeremy committed
    // Tids is an integer or a ",".
jeremy's avatar
jeremy committed
    $variables->tids = isset($values['t']) ? preg_replace('/[^0-9,]/', '', $values['t']) : '';
jeremy's avatar
jeremy committed
    // Hostid is an md5() which is comprised of numbers and letters a-f.
jeremy's avatar
jeremy committed
    $variables->hostid = isset($values['k']) ? preg_replace('/[^0-9a-f]/', '', $values['k']) : '';
jeremy's avatar
jeremy committed
    // Click url
    $variables->url = isset($values['u']) ? $values['u'] : '';
jeremy's avatar
jeremy committed
    if (!$variables->url) {
jeremy's avatar
jeremy committed
      $variables->url = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
jeremy's avatar
jeremy committed
    // Quantity is an integer.
jeremy's avatar
jeremy committed
    $variables->quantity = isset($values['q']) ? (int)$values['q'] : 0;
jeremy's avatar
jeremy committed
    // Ad ID is an integer.
    $variables->aid = isset($values['a']) ? (int)$values['a'] : 0;
jeremy's avatar
jeremy committed
    // Method is compriese of only letters.
jeremy's avatar
jeremy committed
    $variables->ad_display = isset($values['m']) ? preg_replace('/[^a-zA-Z]/', '', $values['m']) : 'javascript';

    // Set defaults.
    $variables->quantity = $variables->quantity ? $variables->quantity : 1;

    if ($variables->debug) {
      foreach ($variables as $variable => $val) {
        echo "$variable: '$val'<br />\n";
      }
      if ($variables->debug == 1) exit;
    }
    $variables->loaded = TRUE;

    // Override the value, if set during initialization.
    if (isset($value)) {
      $variables->$variable = $value;
    }
  }
jeremy's avatar
jeremy committed

jeremy's avatar
jeremy committed
  if (!$overridden) {
    if (isset($conf)) {
      foreach ($conf as $var => $val) {
        $variables->$var = $val;
        if ($variables->debug) {
          echo "Override $var: '$val'<br />\n";
        }
      }
      $overridden = TRUE;
    }
  }

jeremy's avatar
jeremy committed
  if (!isset($cache_loaded[$variables->adcache])) {
jeremy's avatar
jeremy committed
    // Retrieve variables defined by cache plugin, if enabled.
jeremy's avatar
jeremy committed
    if ($variables->adcache != 'none') {
      $include = $variables->ad_dir ."/cache/$variables->adcache/ad_cache_$variables->adcache.inc";
jeremy's avatar
jeremy committed
      if (file_exists($include)) {
        if ($variables->debug) {
          echo "Attempting to include cache include file '$include'.<br />\n";
        }
jeremy's avatar
jeremy committed
      }
      else if ($variables->debug) {
        echo "Failed to find cache include file '$include'.<br />\n";
      }
      $function = 'ad_cache_'. $variables->adcache .'_variables';
jeremy's avatar
jeremy committed
      if (function_exists($function)) {
        $external_variables = $function();
jeremy's avatar
jeremy committed
        foreach ($external_variables as $key => $val) {
jeremy's avatar
jeremy committed
          if (!isset($variables->$key)) {
            $variables->$key = $val;
          }
jeremy's avatar
jeremy committed
        }
      }
    }
jeremy's avatar
jeremy committed
    $cache_loaded[$variables->adcache] = TRUE;
jeremy's avatar
jeremy committed
  }

jeremy's avatar
jeremy committed
  if ($variable == 'variable_dump') {
jeremy's avatar
jeremy committed
    echo "Dumping \$variables:<br />\n";
    echo '<pre>';
jeremy's avatar
jeremy committed
    foreach ($variables as $var => $val) {
      echo "  $var($val)<br />\n";
jeremy's avatar
jeremy committed
    }
    echo '</pre>';
  }

jeremy's avatar
jeremy committed
  if (isset($variables->$variable)) {
    return $variables->$variable;
jeremy's avatar
jeremy committed
  else {
    return NULL;
  }
}

jeremy's avatar
jeremy committed
/**
jeremy's avatar
jeremy committed
 * Invoke a function in the specified file.
jeremy's avatar
jeremy committed
 */
jeremy's avatar
jeremy committed
function adserve_invoke_file($function, $arg1 = NULL, $arg2 = NULL) {
jeremy's avatar
jeremy committed
  $output = '';
jeremy's avatar
jeremy committed
  if (function_exists($function)) {
jeremy's avatar
jeremy committed
    $output = $function($arg1, $arg2);
jeremy's avatar
jeremy committed
  }
  else if (adserve_variable('debug')) {
    echo "Function '$function' does not exist.<br />\n";
  }
  return $output;
}

jeremy's avatar
jeremy committed
/*
 * When debugging, strip away distracting header errors.  Dump all other errors.
jeremy's avatar
jeremy committed
 */
jeremy's avatar
jeremy committed
function _debug_error_handler($errno, $errstr, $errfile = NULL, $errline = 0, $errcontext = NULL) {
  if (!preg_match('/Cannot modify header information/', $errstr) &&
      !preg_match('/Cannot send session cache limiter/', $errstr)) {
    echo "PHP: errno($errno): $errstr ";
    if ($errfile && $errline) {
      echo "; Line $errline in [$errfile]";
jeremy's avatar
jeremy committed
    }
jeremy's avatar
jeremy committed
    echo "<br />\n";
    if (!empty($errcontext) && adserve_variable('debug') >= 5) {
      echo 'Error context:<pre>';
      print_r($errcontext);
      echo '</pre>';
jeremy's avatar
jeremy committed
    }
  }
}

jeremy's avatar
jeremy committed
/**
jeremy's avatar
jeremy committed
 * Dump debug message to screen; set custom error handler.
jeremy's avatar
jeremy committed
 */
jeremy's avatar
jeremy committed
function _debug_echo($text) {
  static $error_handler = FALSE;
jeremy's avatar
jeremy committed
  static $time = 0;

jeremy's avatar
jeremy committed
  if (adserve_variable('debug')) {
    if ($time < time()) {
      $time = time();
jeremy's avatar
jeremy committed
      echo '--> Time mark: '. date('H:i:s', $time) ."<br />\n";
jeremy's avatar
jeremy committed
    if (!$error_handler) {
      set_error_handler('_debug_error_handler');
      $error_handler = TRUE;
jeremy's avatar
jeremy committed
    }
jeremy's avatar
jeremy committed
    echo "$text<br />\n";
jeremy's avatar
jeremy committed
  }
}

function _debug_memory() {
  $memory = '';
  if (adserve_variable('debug') && function_exists('memory_get_usage')) {
    $memory = number_format(round(memory_get_usage() / 1024, 3), 3);
    echo "Memory usage: $memory K<br />\n";
  }
}

jeremy's avatar
jeremy committed
/**
 * Include Drupal's bootstrap.inc.
 */
function adserve_include_drupal() {
jeremy's avatar
jeremy committed
  // For optimal performance set DRUPAL_ROOT at the top of this file.
jeremy's avatar
jeremy committed
  if (defined('DRUPAL_ROOT')) {
    if (is_dir(DRUPAL_ROOT) && file_exists(DRUPAL_ROOT .'/includes/bootstrap.inc')) {
      chdir(DRUPAL_ROOT);
jeremy's avatar
jeremy committed
      adserve_variable('root_dir', DRUPAL_ROOT);
jeremy's avatar
jeremy committed
    }
    else {
      echo 'Invalid DRUPAL_ROOT ('. DRUPAL_ROOT .') defined in adserve.inc';
    }
jeremy's avatar
jeremy committed
  }
  else {
jeremy's avatar
jeremy committed
    $path = explode('/', adserve_variable('ad_dir'));
    while (!empty($path)) {
      // Search for top level Drupal directory to perform bootstrap.
      chdir(implode('/', $path));
jeremy's avatar
jeremy committed
      if (file_exists('./includes/bootstrap.inc')) {
jeremy's avatar
jeremy committed
        adserve_variable('root_dir', getcwd());
jeremy's avatar
jeremy committed
        break;
      }
jeremy's avatar
jeremy committed
      array_pop($path);
jeremy's avatar
jeremy committed
    }
  }
jeremy's avatar
jeremy committed
  require_once adserve_variable('root_dir') .'/includes/bootstrap.inc';
jeremy's avatar
jeremy committed
}

/**
 * Include the necessary files and call the Drupal bootstrap.
 */
jeremy's avatar
jeremy committed
function adserve_bootstrap($bootstrap = NULL) {
  adserve_include_drupal();
jeremy's avatar
jeremy committed

jeremy's avatar
jeremy committed
  // If no specific bootstrap is specified, do a full bootstrap.
  if (!isset($bootstrap)) {
    $bootstrap = DRUPAL_BOOTSTRAP_FULL;
  }
jeremy's avatar
jeremy committed

jeremy's avatar
jeremy committed
  echo _debug_echo("Drupal bootstrap '$bootstrap'.");
jeremy's avatar
jeremy committed

  drupal_bootstrap($bootstrap);
jeremy's avatar
jeremy committed
  echo _debug_echo("Drupal bootstrap complete.");
jeremy's avatar
jeremy committed
}

jeremy's avatar
jeremy committed
/**
 * Display additional debug information.
 */
function adserve_debug() {
  if (adserve_variable('debug')) {
    echo "Root drupal directory detected as '". adserve_variable('root_dir') ."'.<br />\n<br />\n";

    $ad_dir = adserve_variable('ad_dir');
jeremy's avatar
jeremy committed
    $files = array("$ad_dir/serve.php", "$ad_dir/adserve.inc", "$ad_dir/adcache.inc", "$ad_dir/ad.module");
    if (adserve_variable('debug') >= 2) {
jeremy's avatar
jeremy committed
      $files = array_merge($files, array("$ad_dir/ad.install"));
jeremy's avatar
jeremy committed
    }
jeremy's avatar
jeremy committed
    if (adserve_variable('debug') >= 3) {
      $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", "$ad_dir/cache/file/ad_cache_file.inc", "$ad_dir/cache/file/ad_cache_file.module", "$ad_dir/permission/ad_permission.module", "$ad_dir/weight/probability/ad_weight_probability.module", "$ad_dir/weight/probability/ad_weight_probability.inc"));
jeremy's avatar
jeremy committed
    }
    foreach ($files as $file) {
      if (!file_exists($file)) {
        echo "Error: '$file' does not exist!<br />\n";
      }
      else if (!is_readable($file)) {
        echo "Error: '$file' is not readable!<br />\n";
      }
      else {
        $fd = fopen($file, 'r');
        while (!feof($fd)) {
          $line = fgets($fd);
          if (substr($line, 0, 5) == "<?php") {
            continue;
          }
          else {
            echo "$file: $line<br />";
            break;
          }
        }
      }
    }
    echo "<br />\n";
  }
}