diff channel/ad_channel.module @ 7:6aeff3329e01 ad

maj module ad 2.1rc1
author piotre
date Mon, 20 Jul 2009 13:54:40 +0000
parents 0d1c70d51fbe
children 32c1a7d9e1fa
line wrap: on
line diff
--- a/channel/ad_channel.module	Thu May 28 14:53:07 2009 +0000
+++ b/channel/ad_channel.module	Mon Jul 20 13:54:40 2009 +0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: ad_channel.module,v 1.1.4.21 2009/04/22 15:14:46 jeremy Exp $
+// $Id: ad_channel.module,v 1.1.4.26 2009/07/17 21:29:37 jeremy Exp $
 
 /**
  * @file
@@ -142,16 +142,26 @@
         foreach ($channels as $channel) {
           if (is_object($form['#node'])) {
             $node = $form['#node'];
-            $default = isset($node->channel[$channel->chid]);
+            $default_value = isset($node->channel[$channel->chid]);
           }
           else {
-            $default = 0;
+            $default_value = 0;
+          }
+          if (!$default_value) {
+            $channel = _ad_channel_get_channels($channel->chid);
+            if (isset($channel->inventory) && $channel->inventory > 0) {
+              $num_ads = _ad_channel_get_channel_active_ad_count($channel->chid);
+              if($num_ads + 1 > $channel->inventory) {
+                 $disabled = TRUE;
+              }
+            }
           }
           $form['channel'][$container->conid]["channel-$channel->chid"] = array(
             '#type' => 'checkbox',
             '#title' => $channel->name,
             '#description' => $channel->description,
-            '#default_value' => $default,
+            '#default_value' => $default_value,
+            '#disabled' => isset($disabled) ? $disabled : FALSE,
           );
         }
       }
@@ -182,6 +192,20 @@
       '#default_value' => isset($node->premiere) ? $node->premiere : FALSE,
     );
     $form['priority']['#weight'] = -1;
+
+    $form['inventory'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Inventory'),
+      '#collapsible' => TRUE,
+      '#collapsed' => FALSE,
+    );
+
+    $form['inventory']['remnant'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Remnant'),
+      '#description' => t('An advertisement marked as a remnant is eligible for display in any channel where the number of assigned advertisements for the channel is less than the inventory level specified.'),
+      '#default_value' => isset($node->remnant) ? $node->remnant : FALSE,
+    );
   }
   else if ($form_id == 'ad_filter_form') {
     $session = &$_SESSION['ad_overview_filter'];
@@ -241,7 +265,8 @@
         '#title' => t('Channels'),
       );
       $options = array();
-      $options['any'] = t('- Any -');
+      $options['any'] = t('<any>');
+      $options['none'] = t('<none>');
       foreach ($channels as $chan) {
         $options[$chan->chid] = $chan->name;
       }
@@ -302,14 +327,26 @@
 function ad_channel_ad_admin_ads($form) {
   $list = variable_get('ad_channel_admin_list', AD_CHANNEL_LIST_CHANNEL);
 
+  // Conditionally build the header based on list type and
+  // the availability of probability values from the 
+  // ad_weight_probability module
+  $header = array(theme('table_select_header_cell'), t('Title'));
+
   // Overview table:
-  if ($list == AD_CHANNEL_LIST_CHANNEL) {
-    $header = array(theme('table_select_header_cell'), t('Title'), t('Channel'), t('Type'), t('Status'), t('Operations'));
+  if ($list != AD_CHANNEL_LIST_CHANNEL) {
+    $header[] = t('Group');
   }
-  else {
-    $header = array(theme('table_select_header_cell'), t('Title'), t('Group'), t('Channel'), t('Type'), t('Status'), t('Operations'));
+
+  $header = array_merge($header, array(t('Channel')));
+
+  if (isset($form['probability']) && is_array($form['probability'])) {
+    $header[] = t('Probability');
   }
 
+  $header[] = t('Type');
+  $header[] = t('Status');
+  $header[] = t('Operations');
+
   $output = drupal_render($form['options']);
   if (isset($form['title']) && is_array($form['title'])) {
     foreach (element_children($form['title']) as $key) {
@@ -320,6 +357,9 @@
         $row[] = drupal_render($form['group'][$key]);
       }
       $row[] = drupal_render($form['channel'][$key]);
+      if (isset($form['probability']) && is_array($form['probability'])) {
+        $row[] = drupal_render($form['probability'][$key]);
+      }
       $row[] = drupal_render($form['adtype'][$key]);
       $row[] = drupal_render($form['adstatus'][$key]);
       $row[] = drupal_render($form['operations'][$key]);
@@ -361,6 +401,9 @@
         if (is_numeric($chid)) {
           $channels[] = $chid;
         }
+        else if ($chid == 'none') {
+          $channels[-1] = 'none';
+        }
         else {
           $any = TRUE;
         }
@@ -382,10 +425,28 @@
  */
 function ad_channel_adreport($join, $where, $args, $select) {
   if (isset($_SESSION['ad_report_channel']) && is_array($_SESSION['ad_report_channel']) && !empty($_SESSION['ad_report_channel'])) {
-    $join = array('LEFT JOIN {ad_channel_node} acn ON acn.nid = a.aid');
-    $where = array('acn.chid IN (%s)');
-    $args = array(implode(',', $_SESSION['ad_report_channel']));
-    return array('join' => $join, 'where' => $where, 'args' => $args);
+    // Check if we're filtering by <none>
+    if (isset($_SESSION['ad_report_channel'][-1])) {
+      $join = array('LEFT JOIN {ad_channel_node} acn ON acn.nid = a.aid');
+      $channels = $_SESSION['ad_report_channel'];
+      unset($channels[-1]);
+      // Check if we're filtering on <none> and one or more channels
+      if (count($channels)) {
+        $where = array('(ISNULL(acn.chid) OR acn.chid IN (%s))');
+        $args = array(implode(',', $channels));
+      }
+      else {
+        $where = array('ISNULL(acn.chid)');
+      }
+      return array('join' => $join, 'where' => $where, 'args' => $args);
+    }
+    // Filtering by one or more channels
+    else {
+      $join = array('LEFT JOIN {ad_channel_node} acn ON acn.nid = a.aid');
+      $where = array('acn.chid IN (%s)');
+      $args = array(implode(',', $_SESSION['ad_report_channel']));
+      return array('join' => $join, 'where' => $where, 'args' => $args);
+    }
   }
 }
 
@@ -412,6 +473,10 @@
         'title' => t('premiere'),
         'options' => $options,
       );
+      $filters['remnant'] = array(
+        'title' => t('remnant'),
+        'options' => $options,
+      );
       return $filters;
     case 'admin_filter_query':
       if (is_array($node)) {
@@ -433,6 +498,14 @@
               'value' => $value,
             ));
         }
+        else if ($key == 'remnant') {
+          return array(
+            'remnant' => array(
+              'where' => 'r.remnant = %d',
+              'join' => 'INNER JOIN {ad_channel_remnant} r ON n.nid = r.aid ',
+              'value' => $value,
+            ));
+        }
       }
       break;
   }
@@ -449,8 +522,7 @@
       return _ad_channel_load_node($node);
     case 'insert':
     case 'update':
-      if (is_object($node) && isset($node->adtype) &&
-          isset($node->probability) && isset($node->nid)) {
+      if (is_object($node) && isset($node->adtype) && isset($node->nid)) {
         return _ad_channel_save_node($node);
       }
       break;
@@ -477,7 +549,7 @@
     }
   }
   $channels = array();
-  $result = db_query('SELECT chid, display, urls, no_channel_weight FROM {ad_channel}');
+  $result = db_query('SELECT chid, display, urls, no_channel_percent, inventory FROM {ad_channel}');
   while ($channel = db_fetch_object($result)) {
     $channels[$channel->chid] = $channel;
   }
@@ -486,10 +558,16 @@
   while ($priority = db_fetch_object($result)) {
     $premiere[$priority->aid] = $priority->aid;
   }
+  $result = db_query("SELECT r.aid, r.remnant FROM {ads} a LEFT JOIN {ad_channel_remnant} r ON a.aid = r.aid WHERE a.adstatus = 'active' AND r.remnant = 1");
+  $remnants = array();
+  while ($remnant = db_fetch_object($result)) {
+    $remnants[$remnant->aid] = $remnant->aid;
+  }
   $cache['channel']['ads'] = $ads;
   $cache['channel']['channels'] = $channels;
   $cache['channel']['display'] = variable_get('ad_channel_display', 0);
   $cache['premiere'] = $premiere;
+  $cache['remnant'] = $remnants;
 
   $cache['channel']['hook_filter'] = array(
     'weight' => 0,
@@ -562,6 +640,15 @@
         '#weight' => 1,
       );
     }
+    if (isset($node->remnant)) {
+      if (isset($node->remnant) && $node->remnant == 1) {
+        $output = t('This is a remnant advertisement.');
+        $node->content['remnant'] = array(
+          '#value' => theme('box', t('Remnant'), $output),
+          '#weight' => 1,
+        );
+      }
+    }
   }
 }
 
@@ -576,6 +663,7 @@
   }
   // currently 0 or 1, with one being a 'premiere' advertisement.
   $output['premiere'] = (int)db_result(db_query('SELECT priority FROM {ad_priority} WHERE aid = %d', $node->nid));
+  $output['remnant'] = (int)db_result(db_query('SELECT remnant FROM {ad_channel_remnant} WHERE aid = %d', $node->nid));
   return $output;
 }
 
@@ -595,6 +683,10 @@
       db_query('INSERT INTO {ad_priority} (aid, priority) VALUES(%d, %d)', $node->nid, isset($node->premiere) ? $node->premiere : 0);
     }
   }
+    db_query('UPDATE {ad_channel_remnant} SET remnant = %d WHERE aid = %d', isset($node->remnant) ? $node->remnant : 0, $node->nid);
+    if (!db_affected_rows()) {
+      db_query('INSERT INTO {ad_channel_remnant} (aid, remnant) VALUES(%d, %d)', $node->nid, isset($node->remnant) ? $node->remnant : 0);
+    }
 }
 
 /**
@@ -612,6 +704,17 @@
  */
 function _ad_channel_validate_nodes($node) {
   $channels = _ad_channel_get_enabled($node);
+
+  foreach ($channels as $chid) {
+    $channel = _ad_channel_get_channels($chid);
+    if(isset($channel->inventory) && $channel->inventory > 0) {
+      $num_ads = _ad_channel_get_channel_active_ad_count($chid);
+      if ($num_ads + 1 >= $channel->inventory) {
+        form_set_error("channel[$channel->conid][channel-$chid]", t('You may not assign more than !inventory to %name.', array('!inventory' => format_plural($channel->inventory, '1 advertisement', '@count advertisements'),  '%name' => $channel->name)));
+      }
+    }
+  }
+
   $limit = variable_get('ad_channel_ad_limit', 0);
   if ($limit && sizeof($channels) > $limit) {
     $quantity_error = TRUE;
@@ -680,7 +783,7 @@
   $containers = _ad_channel_get_containers();
   $rows = array();
   if (count($containers)) {
-    $header = array(t('Name'), t('Options'));
+    $header = array(t('Name'), t('Inventory'), t('Options'));
     $output  = '<div id="ad-channel">';
     foreach ($containers as $conid => $container) {
       $channels = _ad_channel_get_container_channels($conid);
@@ -694,7 +797,7 @@
         if ($container->description) {
           $description .= '<div class="description">'. filter_xss_admin($container->description) ."</div>\n";
         }
-        $rows[] = array(array('data' => $description, 'class' => 'container', 'colspan' => 2));
+        $rows[] = array(array('data' => $description, 'class' => 'container', 'colspan' => 3));
       }
       foreach ($channels as $chid => $channel) {
         $description  = "<div style=\"margin-left: 30px;\">\n";
@@ -703,8 +806,10 @@
           $description .= ' <div class="description">'. filter_xss_admin($channel->description) ."</div>\n";
         }
         $description .= "</div>\n";
+        $inventory = ' <div class="inventory">' . $channel->inventory . "</div>\n";
         $rows[] = array(
           array('data' => $description, 'class' => 'channel'),
+          array('data' => $inventory, 'class' => 'channel'),
           l(t('edit'), "admin/content/ad/channel/channel/$channel->chid/edit") .'&nbsp;&nbsp;&nbsp;'. l(t('delete'), "admin/content/ad/channel/channel/$channel->chid/delete"),
         );
       }
@@ -749,7 +854,7 @@
   static $cache;
   if (!isset($cache[$conid])) {
     $channels = array();
-    $result = db_query('SELECT chid, name, description, weight FROM {ad_channel} WHERE conid = %d ORDER BY weight ASC', $conid);
+    $result = db_query('SELECT chid, name, description, weight, inventory FROM {ad_channel} WHERE conid = %d ORDER BY weight ASC', $conid);
     while ($channel = db_fetch_object($result)) {
       $channels[$channel->chid] = $channel;
     }
@@ -956,6 +1061,23 @@
     '#default_value' => $chid ? $channel->weight : 0,
   );
 
+  // Inventory for remnant management
+  $form['channel_inventory'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Inventory'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE
+  );
+  $form['channel_inventory']['inventory'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Level'),
+    '#size' => 10,
+    '#maxlength' => 10,
+    '#required' => FALSE,
+    '#description' => t('Entering an inventory value will limit the number of advertisements that may be assigned to this channel. As well, if fewer advertisements than the inventory value are assigned to this channel, advertisements marked as remnants will be used to reach the assigned inventory level.'),
+    '#default_value' => $chid ? $channel->inventory : 0,
+  );
+
   // URL rules
   $form['URL_rules'] = array(
     '#type' => 'fieldset',
@@ -972,7 +1094,7 @@
   $form['URL_rules']['urls'] = array(
     '#type' => 'textarea',
     '#title' => t('Paths'),
-    '#description' => t("Enter one URL per line, including the 'http://' or 'https:/'.  The '*' character is a wildcard.  Example URLs are <em>http://www.example.com/blog</em> for the blog page and <em>http://www.example.com/blog/*</em> for every personal blog."),
+    '#description' => t("Enter one URL per line.  If serving ads locally use Drupal relative paths.  If serving ads remotely include the 'http://' or 'https:/'.  Use '&lt;front&gt;' to specify the front page.  The '*' character is a wildcard.  Example URLs are <em>blog</em> for the blog page and <em>blog/*</em> for every personal blog on your local website."),
     '#default_value' => $chid ? unserialize($channel->urls) : '',
   );
 
@@ -1023,14 +1145,13 @@
       '#value' => t('You will need to set "!variable" to %value for these %type ad rules to be applicable.  Currently these settings are doing nothing.', array('!variable' => l(t('display advertisements not assigned to any channel'), 'admin/content/ad/channel/settings'), '%value' => t('always'), '%type' => 'not-in-channel')),
     );
   }
-  $form['nonchannel_rules']['no_channel_weight'] = array(
+  $form['nonchannel_rules']['no_channel_percent'] = array(
     '#type' => 'select',
-    '#title' => t('Probability'),
-    '#options' => _ad_channel_probabilities(),
-    '#default_value' => $channel->no_channel_weight ? $channel->no_channel_weight : 100,
-    '#description' => t('The greater the probability, the more frequently advertisements that aren\'t in any channel will be displayed along with ads in this channel.  For example, if set to 2, advertisements without any channel will be displayed twice as often as advertisements assigned to this channel.  If set to 1/2, advertisements without any channel will be displayed half as often as advertisements assigned to this channel.  If set to 1, advertisements without any channel will be displayed as often as advertisements assigned to this channel.'),
+    '#title' => t('Percentage'),
+    '#options' => _ad_channel_percentages(),
+    '#default_value' => $chid ? $channel->no_channel_percent : 10,
+    '#description' => t('Choose the maximum percentage of not-in-channel advertisements allowable for display. For instance, selecting 10% indicates that 1 out of 10 advertisements will be selected from those not assigned to this channel.'),
   );
-
   if ($chid) {
     $form['update'] = array(
       '#type' => 'submit',
@@ -1088,7 +1209,7 @@
   }
   switch ($form_state['values']['op']) {
     case t('Create'):
-      db_query("INSERT INTO {ad_channel} (name, description, conid, weight, display, urls, groups, no_channel_weight) VALUES('%s', '%s', %d, %d, %d, '%s', '%s', %d)", $form_state['values']['name'], $form_state['values']['description'], $form_state['values']['conid'], $form_state['values']['weight'], $form_state['values']['display'], serialize($urls), serialize($form_state['values']['groups']), $form_state['values']['no_channel_weight']);
+      db_query("INSERT INTO {ad_channel} (name, description, conid, weight, display, no_channel_percent, urls, groups, inventory) VALUES('%s', '%s', %d, %d, %d, '%s', '%s', %d, %d)", $form_state['values']['name'], $form_state['values']['description'], $form_state['values']['conid'], $form_state['values']['weight'], $form_state['values']['display'], $form_state['values']['no_channel_percent'], serialize($urls), serialize($form_state['values']['groups']), $form_state['values']['inventory']);
       drupal_set_message(t('The %name channel has been created.', array('%name' => $form_state['values']['name'])));
       break;
     case t('Update'):
@@ -1102,7 +1223,7 @@
           }
         }
       }
-      db_query("UPDATE {ad_channel} SET name = '%s', description = '%s', conid = %d, weight = %d, display = %d, urls = '%s', groups = '%s', no_channel_weight = %d WHERE chid = %d", $form_state['values']['name'], $form_state['values']['description'], $form_state['values']['conid'], $form_state['values']['weight'], $form_state['values']['display'], serialize($urls), serialize($groups), $form_state['values']['no_channel_weight'], $form_state['values']['chid']);
+      db_query("UPDATE {ad_channel} SET name = '%s', description = '%s', conid = %d, weight = %d, display = %d, urls = '%s', groups = '%s', no_channel_percent = %d, inventory = %d WHERE chid = %d", $form_state['values']['name'], $form_state['values']['description'], $form_state['values']['conid'], $form_state['values']['weight'], $form_state['values']['display'], serialize($urls), serialize($groups), $form_state['values']['no_channel_percent'], $form_state['values']['inventory'], $form_state['values']['chid']);
       drupal_set_message(t('The %name channel has been updated.', array('%name' => $form_state['values']['name'])));
       break;
     case t('Delete'):
@@ -1157,3 +1278,21 @@
     400 => t('4'),
   );
 }
+
+/**
+ * Available percentages
+ */
+function _ad_channel_percentages() {
+  $options = array();
+  for($i = 5; $i <= 95; $i += 5) {
+    $options[$i] = t($i.'%');
+  }
+  return $options;
+}
+
+function _ad_channel_get_channel_active_ad_count($chid) {
+  if ($chid) {
+    $count = db_result(db_query("SELECT COUNT(nid) AS count FROM {ad_channel_node} acn LEFT JOIN {ads} a ON acn.nid = a.aid WHERE acn.chid = %d AND a.adstatus = 'active'", $chid));
+  }
+  return $count;
+}