You are here

google_admanager.module in DFP Small Business (Google Ad Manager) 6

File

google_admanager.module
View source
<?php

/**
 * Google Admanager, now DoubleClick for Publisher
 * https://www.google.com/dfp/
 */

/**
 * Implementing hook_block
 */
function google_admanager_block($op = 'list', $delta = 0, $edit = array()) {
  if ($op == 'list') {
    $blocks = array();
    if (!variable_get('google_admanager_noblock', FALSE)) {
      $ad_slots = _google_admanager_get_ad_slots();
      foreach ($ad_slots as $delta => $name) {
        $blocks[$delta] = array(
          'info' => 'GAM Ad slot: ' . $name,
          'cache' => BLOCK_NO_CACHE,
        );
      }
    }
    $superslots = variable_get('google_admanager_superslots', array());
    foreach ($superslots as $name => $slots) {
      $blocks['superslot:' . $name] = array(
        'info' => 'GAM Superslot: ' . $name,
        'cache' => BLOCK_NO_CACHE,
      );
    }
    return $blocks;
  }
  else {
    if ($op == 'view') {
      $ad_slots = _google_admanager_get_ad_slots();
      $block = array(
        'subject' => '',
        'content' => '',
      );
      if ($id = variable_get('google_admanager_account', '')) {
        if (isset($ad_slots[$delta])) {
          $block['content'] = theme('google_admanager_block', $id, $ad_slots[$delta]);
        }
        elseif (substr($delta, 0, 10) == 'superslot:') {
          $superslots = variable_get('google_admanager_superslots', array());
          if ($superslot = $superslots[substr($delta, 10)]) {
            foreach ($superslot as $ad_slot => $php) {
              if (eval($php)) {
                $block['content'] .= theme('google_admanager_block', $id, $ad_slot);
              }
            }
          }
        }
      }
      return $block;
    }
    else {
      if ($op == 'configure') {

        // Reuse the 'use PHP for block visibility' from block.module
        if (!user_access('use PHP for block visibility') && substr($delta, 0, 10) !== 'superslot:') {
          return;
        }
        $superslots = variable_get('google_admanager_superslots', array());
        $name = substr($delta, 10);
        if (!isset($superslots[$name])) {
          return;
        }
        $form = array();
        $form['visibility'] = array(
          '#type' => 'fieldset',
          '#title' => t('Ad slots visibility'),
          '#description' => t('Use PHP code to define ad slot visibility. For example, to display an ad slot only to anonymous user, use <em>return empty($GLOBALS[\'user\']->uid);</em>. Or, to simple enable an ad slot, use <em>return TRUE;</em>'),
        );
        $ad_slots = array_values(_google_admanager_get_ad_slots());
        $ad_slots = array_combine($ad_slots, $ad_slots);
        $superslot = $superslots[$name];

        // Create 5 empty slots configuration
        // @TODO: It could be better to implement AHAH form
        $superslot += array(
          'fake slot1' => '',
          'fake slot2' => '',
          'fake slot3' => '',
        );
        $i = 1;
        foreach ($superslot as $ad_slot => $php) {
          $form['visibility']['superslot_' . $i . '_adslot'] = array(
            '#type' => 'select',
            '#title' => t('Ad slot'),
            '#default_value' => $ad_slot,
            '#options' => $ad_slots,
          );
          $form['visibility']['superslot_' . $i++ . '_php'] = array(
            '#type' => 'textfield',
            '#title' => t('PHP code for visibility condition'),
            '#default_value' => $php,
          );
        }
        return $form;
      }
      else {
        if ($op = 'save') {
          if (!user_access('use PHP for block visibility') && substr($delta, 0, 10) !== 'superslot:') {
            return;
          }
          $superslot = array();
          foreach ($edit as $key => $value) {
            if (preg_match('/superslot_(\\d+)_adslot/', $key)) {
              $php = $edit[str_replace('adslot', 'php', $key)];
              drupal_set_message($value . ': ' . $php);
              if (!empty($php)) {
                $superslot[$value] = $php;
              }
            }
          }
          $superslots = variable_get('google_admanager_superslots', array());
          $superslots[substr($delta, 10)] = $superslot;
          variable_set('google_admanager_superslots', $superslots);
        }
      }
    }
  }
}

/**
 * Implementing hook_perm
 */
function google_admanager_perm() {
  return array(
    'administer google admanager',
  );
}

/**
 * Implementing hook_menu
 */
function google_admanager_menu() {
  $items = array();
  $items['admin/settings/google_admanager'] = array(
    'title' => 'Google Admanager',
    'description' => 'Configure the settings used to generate the Google Admanager Slot Ad code.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'google_admanager_admin_settings_form',
    ),
    'access arguments' => array(
      'administer google admanager',
    ),
  );
  $items['admin/settings/google_admanager/account'] = array(
    'title' => 'Account',
    'access arguments' => array(
      'administer google admanager',
    ),
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );
  $items['admin/settings/google_admanager/superslot'] = array(
    'title' => 'Superslot',
    'description' => 'Manage superslot',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'google_admanager_admin_superslot_form',
    ),
    'access arguments' => array(
      'administer google admanager',
    ),
    'type' => MENU_LOCAL_TASK,
  );
  return $items;
}

/**
 * Implementation of hook_init()
 */
function google_admanager_init() {
  drupal_add_css(drupal_get_path('module', 'google_admanager') . '/google_admanager.css');
  if (variable_get('google_admanager_lazy', FALSE)) {
    drupal_add_js(drupal_get_path('module', 'google_admanager') . '/google_admanager.js');
  }
}

/**
 * Implementation of hook_admin_settings() for configuring the module
 */
function google_admanager_admin_settings_form() {
  $form = array();
  $form['google_admanager_account'] = array(
    '#type' => 'textfield',
    '#title' => t('DFP Property Code'),
    '#default_value' => variable_get('google_admanager_account', 'ca-pub-'),
    '#size' => 30,
    '#maxlength' => 40,
    '#required' => TRUE,
    '#description' => t('See detailed instruction in README.txt'),
  );
  $form['google_admanager_ad_slots'] = array(
    '#type' => 'textarea',
    '#title' => t('Ad slots'),
    '#default_value' => variable_get('google_admanager_ad_slots', ''),
    '#description' => t('Enter one Ad Slot name per line.'),
  );
  $form['google_admanager_noblock'] = array(
    '#type' => 'checkbox',
    '#title' => t('Don\'t create blocks'),
    '#default_value' => variable_get('google_admanager_noblock', FALSE),
    '#description' => t('This option allow you to use only superslot. Handful when you have dozens of ad slots or more. <strong>Switch on/off this option may reset blocks positions.</strong>'),
  );
  $form['google_admanager_lazy'] = array(
    '#type' => 'checkbox',
    '#title' => t('Lazy loading'),
    '#default_value' => variable_get('google_admanager_lazy', FALSE),
    '#description' => t('(Experimental) Insert DFP code before &lt;/body&gt; instead of in header (not work with inline ad). Read more in README.txt'),
  );
  return system_settings_form($form);
}

/**
 * Implementation of hook_admin_settings_form_validate()
 */
function google_admanager_admin_settings_form_validate($form, &$form_state) {
  if (!preg_match('/^ca-pub-\\d+$/', $form_state['values']['google_admanager_account'])) {
    form_set_error('google_admanager_account', t('A valid DFP Property Code is case sensitive and formatted like ca-pub-nnnnnnnnnnnnnnnn.'));
  }
}

/**
 * Implementation of hook_admin_settings_form_submit()
 */
function google_admanager_admin_settings_form_submit($form, &$form_state) {
  $ad_slots = _google_admanager_get_ad_slots();
  $result = db_query("SELECT bid, delta FROM {blocks} WHERE module = 'google_admanager'");
  while ($block = db_fetch_object($result)) {

    //remove the block when it is not in the list anymore
    if (!isset($ad_slots[$block->delta]) && substr($block->delta, 0, 10) !== 'superslot:') {
      db_query("DELETE FROM {blocks} WHERE bid = %d", $block->bid);
    }
  }
}

/**
 * Form to manage (add/remove) superslot
 */
function google_admanager_admin_superslot_form() {
  $form = array();
  $superslots = variable_get('google_admanager_superslots', array());
  $superslot_list = array();
  foreach ($superslots as $name => $slots) {
    $superslot_list[] = '<li>' . l($name, 'admin/build/block/configure/google_admanager/superslot:' . $name) . '</li>';
  }
  $form['google_admanager_superslot'] = array(
    '#value' => t('A superslot is a block containing many slots, each slot has its own visibility criteria'),
  );
  $form['google_admanager_superslot_current'] = array(
    '#type' => 'fieldset',
    '#title' => t('Current superslot(s)'),
  );
  $form['google_admanager_superslot_current']['list'] = array(
    '#value' => '<ul>' . implode('', $superslot_list) . '</ul>',
  );
  $form['google_admanager_superslot_new'] = array(
    '#type' => 'fieldset',
    '#title' => t('Create new superslot'),
  );
  $form['google_admanager_superslot_new']['google_admanager_superslot_name'] = array(
    '#type' => 'textfield',
    '#title' => t('Superslot name'),
    '#description' => t('Enter a unique name (only alphanumeric and underscore, 1-20 characters)'),
    '#size' => 30,
  );
  $form['google_admanager_superslot_new']['google_admanager_superslot_create'] = array(
    '#type' => 'submit',
    '#value' => t('Create'),
  );
  return $form;
}

/**
 * Validator for google_admanager_admin_superslot_form
 */
function google_admanager_admin_superslot_form_validate($form, &$form_state) {
  $superslots = variable_get('google_admanager_superslots', array());
  if (!preg_match('/^[a-zA-Z0-9_]{1,20}$/', $form_state['values']['google_admanager_superslot_name'])) {
    form_set_error('google_admanager_superslot_name', t('Superslot name can contain only alphanumeric and underscore, 1-20 characters.'));
  }
  if (isset($superslots[$form_state['values']['google_admanager_superslot_name']])) {
    form_set_error('google_admanager_superslot_name', t('Duplicate superslot name.'));
  }
}

/**
 * Submitter for google_admanager_admin_superslot_form
 */
function google_admanager_admin_superslot_form_submit($form, &$form_state) {
  $superslots = variable_get('google_admanager_superslots', array());
  $superslots[$form_state['values']['google_admanager_superslot_name']] = array();
  variable_set('google_admanager_superslots', $superslots);
}

/**
 * Implementation of hook_form_alter().
 */
function google_admanager_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'google_admanager_admin_settings_form') {
    $form['#submit'][] = 'google_admanager_admin_settings_form_submit';
  }
}

/**
 * Implemention of hook_theme()
 */
function google_admanager_theme() {
  return array(
    'google_admanager_block' => array(
      'arguments' => array(
        'id' => NULL,
        'ad_slot' => NULL,
      ),
    ),
  );
}

/**
 * Theme function the Ad Slot code
 * @param $id google admanager account id
 * @param $id google admanager slot name
 * @return google admanager slot script 
 */
function theme_google_admanager_block($id, $ad_slot, $cache = FALSE) {
  $script = '<script type="text/javascript">GA_googleFillSlot("' . $ad_slot . '");</script>';
  if ($cache) {
    $script = '<script type="text/javascript">GA_googleAddSlot("' . $id . '", "' . $ad_slot . '");</script>' . $script;
  }
  else {
    google_admanager_add_js('GA_googleAddSlot("' . $id . '", "' . $ad_slot . '");');
  }
  if (variable_get('google_admanager_lazy', FALSE)) {
    google_admanager_add_block('<div id="gam-content-' . $ad_slot . '" class="gam-banner">' . $script . '</div>');
    $script = '';
  }
  return '<div id="gam-holder-' . $ad_slot . '" class="gam-holder">' . $script . '</div>';
}

/**
 * Store ad slots js and when called with no slot, return the whole ad manager javascript
 * 
 * @param $js (optional) string with the slot script to add to the array.
 * @param $type (optional) scripts have to be split up into 4 types and are output
 *   in order ['init', 'service', 'slot', 'close'].
 * @return if $js is empty, then an array of stored google_admanager javascript 
 */
function google_admanager_add_js($js = NULL, $type = 'slot') {
  static $ga_js = array();

  // add the js to a type
  if (isset($js) && isset($type)) {
    $ga_js[$type][] = $js;

    //add the init and service scripts the first time this is run
    if (!isset($ga_js['init'])) {

      //drupal_add_js can't load externaljs in 6, but it will in 7. this is a workaround.
      $external_js = 'http://partner.googleadservices.com/gampad/google_service.js';
      google_admanager_add_js('document.write(unescape("%3Cscript src=\'' . $external_js . '\' type=\'text/javascript\'%3E%3C/script%3E"));', 'init');
      $id = variable_get('google_admanager_account', '');
      google_admanager_add_js('GS_googleAddAdSenseService("' . $id . '");', 'service');
      google_admanager_add_js('GS_googleEnableAllServices();', 'service');

      // set the close script to fetch the ads.
      google_admanager_add_js('GA_googleFetchAds();', 'close');
    }
    return;
  }

  //check that there is something to return
  if (!isset($ga_js['init'])) {
    return;
  }

  // $ga_js['init'] must have been set since we didn't return, so if js isn't set then return
  // the whole array, just like drupal_add_js().
  if (!isset($js)) {
    return $ga_js;
  }
}
function google_admanager_add_block($text = NULL) {
  static $ga_block = array();
  if (!$text) {
    return $ga_block;
  }
  $ga_block[] = $text;
}

/** 
* Output the Google Admanager scripts by way of drupal_add_js().
*  
* @param $scope (optional) the scope to output the javascript. see drupal_add_js().
*/
function google_admanager_get_js($scope = 'header') {

  //get the js for this page if it exists
  $ga_js = google_admanager_add_js();
  if (isset($ga_js)) {
    $output_order = array(
      'init',
      'service',
      'slot',
      'close',
    );
    foreach ($output_order as $type) {
      $output = '';
      foreach ($ga_js[$type] as $js) {
        $output .= $js . "\n";
      }
      drupal_add_js($output, 'inline', $scope);
    }
  }
}

/**
 * Implementation of hook_preprocess_page().
 */
function google_admanager_preprocess_page(&$vars) {
  if (variable_get('google_admanager_lazy', FALSE)) {
    return;
  }

  //output the scripts through drupal_add_js()
  google_admanager_get_js();

  //this doesn't have any effect if another module/theme later overides it.
  $vars['scripts'] = drupal_get_js();
}

/**
 * Implementation of hook_footer().
 */
function google_admanager_footer($main) {
  if ($lazy = google_admanager_add_block()) {
    if ($ga_js = google_admanager_add_js()) {
      $output_order = array(
        'init',
        'service',
        'slot',
        'close',
      );
      $gam_script = '';
      foreach ($output_order as $type) {
        $output = "\n";
        foreach ($ga_js[$type] as $js) {
          $output .= $js . "\n";
        }
        $gam_script .= '<script type="text/javascript">' . $output . '</script>';
      }
      array_unshift($lazy, $gam_script);
    }
    return implode("\n", $lazy);
  }
}

/**
 * Implementation of hook_filter().
 *
 * Filter option to enable Google Admanager filter [google_ad:ad_slot]
 * @see google_admanager_nodeapi()
 */
function google_admanager_filter($op, $delta = 0, $format = -1, $text = '') {
  switch ($op) {
    case 'list':
      return array(
        0 => t('Google Admanager filter'),
      );
    case 'description':
      return t('Substitutes [google_ad:ad_slot] tags with the Google Admanager script.');
    case 'prepare':
      return $text;
    case 'process':
      return _google_admanager_substitute_tags($text);
  }
}

/**
 * Implementation of hook_filter_tips().
 */
function google_admanager_filter_tips($delta, $format, $long = FALSE) {
  return t('You may use [google_ad:ad_slot] to display Google Admanager ads within your content.');
}

/**
 * Replace all Admanager tags with their corresponding files or images.
 *
 * @param object $text
 *   The text to process.
 *
 * @return string
 *   The processed content of the given text.
 */
function _google_admanager_substitute_tags($text) {
  if (preg_match_all("/\\[(google_ad):([^=\\]]+)=?([^\\]]*)?\\]/i", $text, $match)) {
    $id = variable_get('google_admanager_account', '');
    $s = $r = array();
    foreach ($match[2] as $key => $ad_slot) {
      $s[] = $match[0][$key];
      $r[] = theme_google_admanager_block($id, $ad_slot, TRUE);
    }

    // Perform the replacements and return processed field.
    return str_replace($s, $r, $text);
  }
  return $text;
}

/**
 * Get all ad slots each correspond to block (with delta/name)
 */
function _google_admanager_get_ad_slots() {
  $ad_slots = array();
  $list = array_filter(explode("\n", str_replace(array(
    "\r",
    "\t",
    "\0",
    "\v",
    " ",
  ), '', variable_get('google_admanager_ad_slots', ''))));
  foreach ($list as $ad_slot) {
    $ad_slots[md5(trim($ad_slot))] = $ad_slot;
  }
  return $ad_slots;
}

Functions

Namesort descending Description
google_admanager_add_block
google_admanager_add_js Store ad slots js and when called with no slot, return the whole ad manager javascript
google_admanager_admin_settings_form Implementation of hook_admin_settings() for configuring the module
google_admanager_admin_settings_form_submit Implementation of hook_admin_settings_form_submit()
google_admanager_admin_settings_form_validate Implementation of hook_admin_settings_form_validate()
google_admanager_admin_superslot_form Form to manage (add/remove) superslot
google_admanager_admin_superslot_form_submit Submitter for google_admanager_admin_superslot_form
google_admanager_admin_superslot_form_validate Validator for google_admanager_admin_superslot_form
google_admanager_block Implementing hook_block
google_admanager_filter Implementation of hook_filter().
google_admanager_filter_tips Implementation of hook_filter_tips().
google_admanager_footer Implementation of hook_footer().
google_admanager_form_alter Implementation of hook_form_alter().
google_admanager_get_js Output the Google Admanager scripts by way of drupal_add_js().
google_admanager_init Implementation of hook_init()
google_admanager_menu Implementing hook_menu
google_admanager_perm Implementing hook_perm
google_admanager_preprocess_page Implementation of hook_preprocess_page().
google_admanager_theme Implemention of hook_theme()
theme_google_admanager_block Theme function the Ad Slot code
_google_admanager_get_ad_slots Get all ad slots each correspond to block (with delta/name)
_google_admanager_substitute_tags Replace all Admanager tags with their corresponding files or images.