annotate channel/ad_channel.inc @ 8:32c1a7d9e1fa ad tip

maj module ad en 2.1
author sly
date Fri, 11 Sep 2009 11:10:20 +0000
parents 6aeff3329e01
children
rev   line source
pierre@1 1 <?php
pierre@1 2
pierre@1 3 /**
pierre@1 4 * @file
pierre@1 5 * Ad Channel include file.
pierre@1 6 *
pierre@1 7 * Copyright (c) 2008-2009.
pierre@1 8 * Jeremy Andrews <jeremy@tag1consulting.com>.
pierre@1 9 */
pierre@1 10
pierre@1 11 /**
pierre@1 12 * Filter advertisements not in an appropriate channel, from cache.
pierre@1 13 */
pierre@1 14 function ad_channel_cache_filter($ads) {
pierre@1 15 _debug_echo("ad_channel_cache: adserve_cache_filter");
pierre@1 16
piotre@7 17 // get channel array from cache
pierre@1 18 $channels = adserve_cache('get_cache', 'channel');
piotre@7 19 // 0 = only display advertisements not assigned to any channel if no matching
piotre@7 20 // ads in selected channel; 1 = always display advertisements not assigned to
piotre@7 21 // any channel; 2 = never display advertisements not assigned to any channel
piotre@7 22 $nochannel_display = $channels['display'];
piotre@7 23 $valid_ads = array();
piotre@7 24 $nochannel_fallback_ads = array();
piotre@7 25 $nochannel_percent = array();
piotre@7 26 // determine which channels each advertisement is assigned to
pierre@1 27 foreach ($ads as $aid) {
pierre@1 28 _debug_echo("ad_channel_cache: checking aid($aid)");
pierre@1 29 if (is_array($channels['ads']) && isset($channels['ads'][$aid]) &&
pierre@1 30 is_array($channels['ads'][$aid])) {
pierre@1 31 foreach ($channels['ads'][$aid] as $chid) {
pierre@1 32 $channel = $channels['channels'][$chid];
piotre@7 33 $display_by_url = $channel->display;
pierre@1 34 $urls = unserialize($channel->urls);
pierre@1 35 $frontpage = adserve_variable('site_frontpage') ? adserve_variable('site_frontpage') : 'node';
pierre@1 36 $regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote($frontpage, '/') .'\2'), preg_quote($urls, '/')) .')$/';
pierre@1 37 $match = preg_match($regexp, adserve_variable('url'));
piotre@7 38 _debug_echo("ad_channel_cache: checking aid($aid) against channel($chid) path(". adserve_variable('url') .") regexp($regexp) match($match) display[$display_by_url]");
piotre@7 39 // display ad on all except matching urls
piotre@7 40 if ($display_by_url == 0) {
pierre@1 41 if (empty($urls) || !$match) {
pierre@1 42 _debug_echo("ad_channel_cache: aid($aid) is valid");
piotre@7 43 $valid_ads[$chid][] = $aid;
piotre@7 44 if ($nochannel_display == 1) {
piotre@7 45 $nochannel_percent[$chid] = $channel->no_channel_percent;
piotre@7 46 _debug_echo("ad_channel_cache: channel($chid) no_channel_percent($nochannel_percent[$chid])");
sly@2 47 }
piotre@7 48 else {
piotre@7 49 _debug_echo("ad_channel_cache: channel($chid)");
piotre@7 50 }
pierre@1 51 break;
pierre@1 52 }
pierre@1 53 }
piotre@7 54 // display ad on matching urls
piotre@7 55 else {
pierre@1 56 if (!empty($urls) && $match) {
pierre@1 57 _debug_echo("ad_channel_cache: aid($aid) is valid");
piotre@7 58 $valid_ads[$chid][] = $aid;
piotre@7 59 if ($nochannel_display == 1) {
piotre@7 60 $nochannel_percent[$chid] = $channel->no_channel_percent;
piotre@7 61 _debug_echo("ad_channel_cache: channel($chid) no_channel_percent($nochannel_percent[$chid])");
sly@2 62 }
piotre@7 63 else {
piotre@7 64 _debug_echo("ad_channel_cache: channel($chid)");
piotre@7 65 }
pierre@1 66 break;
pierre@1 67 }
pierre@1 68 }
piotre@7 69 // no match so we didn't hit a break, ad is not valid
pierre@1 70 _debug_echo("ad_channel_cache: aid($aid) is not valid");
pierre@1 71 }
pierre@1 72 }
pierre@1 73 else {
piotre@7 74 // no channel information for ad
piotre@7 75 _debug_echo("ad_channel_cache: aid($aid) has no channel info, nochannel_display($nochannel_display)");
piotre@7 76 switch ($nochannel_display) {
pierre@1 77 case 0:
piotre@7 78 $nochannel_fallback_ads[] = $aid;
piotre@7 79 _debug_echo("ad_channel_cache: non-channel aid($aid) is valid if no valid ads are assigned to current channel");
pierre@1 80 break;
pierre@1 81 case 1:
piotre@7 82 $valid_ads[0][] = $aid;
piotre@7 83 _debug_echo("ad_channel_cache: non-channel aid($aid) is valid");
pierre@1 84 break;
pierre@1 85 case 2:
pierre@1 86 _debug_echo("ad_channel_cache: aid($aid) is not valid");
pierre@1 87 break;
pierre@1 88 }
pierre@1 89 }
pierre@1 90 }
pierre@1 91
piotre@7 92 // Apply frequencies, applicable to all channels
piotre@7 93 if (!empty($valid_ads) && !empty($nochannel_percent)) {
piotre@7 94 $frequencies = array();
piotre@7 95 foreach (array_keys($valid_ads) as $chid) {
piotre@7 96 if ($chid) {
piotre@7 97 if (isset($nochannel_percent[$chid]) && $nochannel_percent[$chid]) {
piotre@7 98 $frequencies[$chid] = $nochannel_percent[$chid];
piotre@7 99 _debug_echo("ad_channel_cache: channel $chid has a non-channel ad frequency of ". $nochannel_percent[$chid]."%");
sly@2 100 }
sly@2 101 else {
piotre@7 102 // by default, channels return 'non-channel ads' with a frequency
piotre@7 103 // of 10%
piotre@7 104 $frequencies[$chid] = 10;
piotre@7 105 _debug_echo("ad_channel_cache: channel $chid assigned a default non-channel ad frequency of 10%");
sly@2 106 }
sly@2 107 }
sly@2 108 else {
piotre@7 109 // frequency for non-channel ads is not meaningful
sly@2 110 }
sly@2 111 }
piotre@7 112 if (!empty($frequencies)) {
piotre@7 113 $balanced_channels = array();
piotre@7 114 $num_channels = sizeof($valid_ads);
piotre@7 115
piotre@7 116 foreach (array_keys($valid_ads) as $chid) {
piotre@7 117 if (isset($frequencies[$chid])) {
piotre@7 118 // for a given channel, ensure the proper ratio to non-channel ads
piotre@7 119 if ($frequencies[$chid] <= 50) { // increase occurrences of $chid
piotre@7 120 $balanced_channels[] = 0;
piotre@7 121 $frequency = round(100 / $frequencies[$chid]) - 1;
piotre@7 122 _debug_echo("ad_channel_cache: adjusting ratio of channel($chid) to $frequency:1 relative non-channel ads");
piotre@7 123 for ($i = 1; $i <= $frequency; $i++) {
piotre@7 124 $balanced_channels[] = $chid;
piotre@7 125 }
piotre@7 126 }
piotre@7 127 else { // add $chid and additional non-channel ads
piotre@7 128 $balanced_channels[] = $chid;
piotre@7 129 $frequency = round(100 / (100 - $frequencies[$chid])) - 1;
piotre@7 130 _debug_echo("ad_channel_cache: adjusting ratio of channel($chid) to 1:$frequency relative non-channel ads");
piotre@7 131 for ($i = 1; $i <= $frequency; $i++) {
piotre@7 132 $balanced_channels[] = 0;
piotre@7 133 }
piotre@7 134 }
sly@2 135 }
sly@2 136 }
piotre@7 137 _debug_echo('ad_channel_cache: channel 0 contains all non-channel ads');
piotre@7 138 if (adserve_variable('debug') >= 2) {
piotre@7 139 foreach ($balanced_channels as $key => $chid) {
piotre@7 140 _debug_echo("ad_channel_cache: channel $chid => index $key");
piotre@7 141 }
piotre@7 142 }
sly@2 143 }
piotre@7 144 $random_channel = _select_channel_id($balanced_channels);
sly@2 145 }
piotre@7 146 else if (!empty($valid_ads)) {
piotre@7 147 foreach ($valid_ads as $chid => $ads) {
piotre@7 148 $chids[$chid] = $chid;
piotre@7 149 }
piotre@7 150 shuffle($chids);
piotre@7 151 $random_channel = array_pop($chids);
piotre@7 152 }
piotre@7 153 else if (empty($valid_ads) && !empty($nochannel_fallback_ads)) {
pierre@1 154 _debug_echo("ad_channel_cache: using ads with no channel info");
piotre@7 155 $valid_ads[0] = $nochannel_fallback_ads;
piotre@7 156 $random_channel = 0;
pierre@1 157 }
pierre@1 158
pierre@1 159 $premiere = adserve_cache('get_cache', 'premiere');
pierre@1 160 if (is_array($premiere)) {
piotre@7 161 $premieres = array();
piotre@7 162 foreach (array_keys($valid_ads) as $chid) {
piotre@7 163 foreach ($valid_ads[$chid] as $aid) {
piotre@7 164 if (in_array($aid, $premiere)) {
piotre@7 165 _debug_echo("ad_channel_cache: aid($aid) is premiere advertisement");
piotre@7 166 $premieres[$aid] = $aid;
piotre@7 167 }
piotre@7 168 else {
piotre@7 169 _debug_echo("ad_channel_cache: aid($aid) is not a premiere advertisement");
piotre@7 170 }
pierre@1 171 }
pierre@1 172 }
pierre@1 173 if (!empty($premieres)) {
pierre@1 174 _debug_echo("ad_channel_cache: returning premiere advertisements");
pierre@1 175 return $premieres;
pierre@1 176 }
pierre@1 177 }
piotre@7 178 _debug_echo("ad_channel_cache: returning non-premiere advertisements from randomly selected channel $random_channel");
piotre@7 179
piotre@7 180 if (isset($valid_ads[$random_channel])) {
piotre@7 181 return ad_channel_enforce_inventory_level($random_channel, $valid_ads[$random_channel]);
piotre@7 182 }
pierre@1 183 }
sly@2 184
sly@2 185 /**
piotre@7 186 * Randomly select a valid channel id from an array channel ids
piotre@7 187 * @param array, valid array.
sly@2 188 */
piotre@7 189 function _select_channel_id($choices) {
piotre@7 190 $selected = 0;
piotre@7 191 if (is_array($choices)) {
piotre@7 192 $available = sizeof($choices);
piotre@7 193 _debug_echo("ad_channel_cache: randomly selecting from $available indexes.");
piotre@7 194 $selected = $available > 1 ? $choices[mt_rand(0, $available - 1)] : $choices[0];
piotre@7 195 _debug_echo("ad_channel_cache: randomly selected channel $selected.");
piotre@7 196 }
sly@2 197
piotre@7 198 return $selected;
sly@2 199 }
sly@2 200
piotre@7 201 /*
piotre@7 202 * Augment the selected channel with 'remnant' ads to ensure that any specified
piotre@7 203 * inventory level is honored
piotre@7 204 * @param int, channel id
piotre@7 205 * @param array, valid array.
sly@2 206 */
piotre@7 207 function ad_channel_enforce_inventory_level($chid, $ads) {
piotre@7 208 if ($chid > 0) {
piotre@7 209 $channels = adserve_cache('get_cache', 'channel');
piotre@7 210 $channel = $channels['channels'][$chid];
piotre@7 211 $level = $channel->inventory;
piotre@7 212 $num_ads = count($ads);
piotre@7 213 if ($num_ads < $level) {
piotre@7 214 _debug_echo("ad_channel_enforce_inventory_level: channel($chid) has $num_ads and needs $level");
piotre@7 215 $remnants = array_values(adserve_cache('get_cache', 'remnant'));
piotre@7 216 $available = count($remnants);
piotre@7 217 if ($available > 0) {
piotre@7 218 _debug_echo("ad_channel_enforce_inventory_level: randomly selecting from $available remnants.");
piotre@7 219 while (count($ads) < $level) {
piotre@7 220 shuffle($remnants);
piotre@7 221 $selected = array_pop($remnants);
piotre@7 222 _debug_echo("ad_channel_enforce_inventory_level: selected $selected.");
piotre@7 223 $ads[] = $selected;
piotre@7 224 }
piotre@7 225 }
piotre@7 226 else {
piotre@7 227 _debug_echo("ad_channel_enforce_inventory_level: no remnants to choose from.");
piotre@7 228 }
piotre@7 229 }
piotre@7 230 else {
piotre@7 231 _debug_echo("ad_channel_enforce_inventory_level: channel($chid) no inventory level assigned");
piotre@7 232 }
sly@2 233 }
sly@2 234 else {
piotre@7 235 _debug_echo("ad_channel_enforce_inventory_level: not needed for channel($chid)");
sly@2 236 }
piotre@7 237 return $ads;
sly@2 238 }
piotre@7 239