diff channel/ad_channel.inc @ 2:e5584a19768b ad

maj module ad
author sly
date Wed, 15 Apr 2009 07:58:32 +0000
parents 948362c2a207
children 6aeff3329e01
line wrap: on
line diff
--- a/channel/ad_channel.inc	Thu Apr 02 15:28:21 2009 +0000
+++ b/channel/ad_channel.inc	Wed Apr 15 07:58:32 2009 +0000
@@ -17,6 +17,8 @@
   $channels = adserve_cache('get_cache', 'channel');
   $valid = array();
   $nochannel = array();
+  $nochannel_weight = array();
+  $matched_channel = array();
   foreach ($ads as $aid) {
     _debug_echo("ad_channel_cache: checking aid($aid)");
     if (is_array($channels['ads']) && isset($channels['ads'][$aid]) &&
@@ -33,6 +35,11 @@
           if (empty($urls) || !$match) {
             _debug_echo("ad_channel_cache: aid($aid) is valid");
             $valid[] = $aid;
+            if ($display == 1) {
+              $nochannel_weight[$chid] = $channel->no_channel_weight;
+            }
+            $matched_channel[$aid] = $chid;
+            _debug_echo("ad_channel_cache: channel($channel->chid) no_channel_weight(". $nochannel_weight[$chid] .')');
             break;
           }
         }
@@ -40,6 +47,10 @@
           if (!empty($urls) && $match) {
             _debug_echo("ad_channel_cache: aid($aid) is valid");
             $valid[] = $aid;
+            if ($display == 1) {
+              $nochannel_weight[$chid] = $channel->no_channel_weight;
+            }
+            $matched_channel[$aid] = $chid;
             break;
           }
         }
@@ -66,7 +77,43 @@
     }
   }
 
-  if (empty($valid) && !empty($nochannel)) {
+  // Apply weights, applicable for advertisements that are not assigned to any
+  // channel.
+  if (!empty($valid) && !empty($nochannel_weight)) {
+    $weights = array();
+    foreach ($valid as $aid) {
+      if (isset($matched_channel[$aid])) {
+        $chid = $matched_channel[$aid];
+        if (isset($nochannel_weight[$chid])) {
+          $weights[$aid] = $nochannel_weight[$chid];
+          _debug_echo("ad_channel_cache: ad $aid in channel $chid with weight ". $nochannel_weight[$chid]);
+        }
+        else {
+          // by default, ads are assigned a weight of 100%
+          $weights[$aid] = 100;
+          _debug_echo("ad_channel_cache: ad $aid in channel $chid with default weight of 100");
+        }
+      }
+      else {
+        // by default, ads are assigned a weight of 100%
+        $weights[$aid] = 100;
+        _debug_echo("ad_channel_cache: ad $aid in no channel with default weight of 100");
+      }
+    }
+    if (!empty($weights)) {
+      $gcd = ad_channel_probability_gcd($weights);
+      $display = array();
+      _debug_echo("ad_channel_cache: adjusting channel weights, gcd ($gcd)");
+      foreach ($valid as $aid) {
+        $weight = $weights[$aid] / $gcd;
+        for ($i = 1; $i <= $weight; $i++) {
+          $display[] = $aid;
+        }
+      }
+      $valid = $display;
+    }
+  }
+  else if (empty($valid) && !empty($nochannel)) {
     _debug_echo("ad_channel_cache: using ads with no channel info");
     $valid = $nochannel;
   }
@@ -91,3 +138,28 @@
   _debug_echo("ad_channel_cache: returning non-premiere advertisements");
   return $valid;
 }
+
+/**
+ * Returns the greatest common divisor of an array of integers.
+ */
+function ad_channel_probability_gcd($integers) {
+  $gcd = array_shift($integers);
+
+  while (!empty($integers)) {
+    $gcd = _ad_channel_probability_gcd($gcd, array_shift($integers));
+  }
+  return $gcd;
+}
+
+/**
+ * Helper function to calculate the greatest common divisor using the Euclidean
+ * algorithm (http://en.wikipedia.org/wiki/Euclidean_algorithm).
+ */
+function _ad_channel_probability_gcd($a, $b) {
+  if ($b == 0) {
+    return $a;
+  }
+  else {
+    return _ad_channel_probability_gcd($b, $a % $b);
+  }
+}