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 |
pierre@1
|
17 $channels = adserve_cache('get_cache', 'channel'); |
pierre@1
|
18 $valid = array(); |
pierre@1
|
19 $nochannel = array(); |
sly@2
|
20 $nochannel_weight = array(); |
sly@2
|
21 $matched_channel = array(); |
pierre@1
|
22 foreach ($ads as $aid) { |
pierre@1
|
23 _debug_echo("ad_channel_cache: checking aid($aid)"); |
pierre@1
|
24 if (is_array($channels['ads']) && isset($channels['ads'][$aid]) && |
pierre@1
|
25 is_array($channels['ads'][$aid])) { |
pierre@1
|
26 foreach ($channels['ads'][$aid] as $chid) { |
pierre@1
|
27 $channel = $channels['channels'][$chid]; |
pierre@1
|
28 $display = $channel->display; |
pierre@1
|
29 $urls = unserialize($channel->urls); |
pierre@1
|
30 $frontpage = adserve_variable('site_frontpage') ? adserve_variable('site_frontpage') : 'node'; |
pierre@1
|
31 $regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote($frontpage, '/') .'\2'), preg_quote($urls, '/')) .')$/'; |
pierre@1
|
32 $match = preg_match($regexp, adserve_variable('url')); |
pierre@1
|
33 _debug_echo("ad_channel_cache: checking aid($aid) against channel($chid) path(". adserve_variable('url') .") regexp($regexp) match($match)"); |
pierre@1
|
34 if ($display == 0) { // display on all except listed urls |
pierre@1
|
35 if (empty($urls) || !$match) { |
pierre@1
|
36 _debug_echo("ad_channel_cache: aid($aid) is valid"); |
pierre@1
|
37 $valid[] = $aid; |
sly@2
|
38 if ($display == 1) { |
sly@2
|
39 $nochannel_weight[$chid] = $channel->no_channel_weight; |
sly@2
|
40 } |
sly@2
|
41 $matched_channel[$aid] = $chid; |
sly@2
|
42 _debug_echo("ad_channel_cache: channel($channel->chid) no_channel_weight(". $nochannel_weight[$chid] .')'); |
pierre@1
|
43 break; |
pierre@1
|
44 } |
pierre@1
|
45 } |
pierre@1
|
46 else { // display only on listed urls |
pierre@1
|
47 if (!empty($urls) && $match) { |
pierre@1
|
48 _debug_echo("ad_channel_cache: aid($aid) is valid"); |
pierre@1
|
49 $valid[] = $aid; |
sly@2
|
50 if ($display == 1) { |
sly@2
|
51 $nochannel_weight[$chid] = $channel->no_channel_weight; |
sly@2
|
52 } |
sly@2
|
53 $matched_channel[$aid] = $chid; |
pierre@1
|
54 break; |
pierre@1
|
55 } |
pierre@1
|
56 } |
pierre@1
|
57 _debug_echo("ad_channel_cache: aid($aid) is not valid"); |
pierre@1
|
58 } |
pierre@1
|
59 } |
pierre@1
|
60 else { |
pierre@1
|
61 // no channel information for ad, it's valid |
pierre@1
|
62 $display = $channels['display']; |
pierre@1
|
63 _debug_echo("ad_channel_cache: aid($aid) has no channel info [$display]"); |
pierre@1
|
64 switch ($display) { |
pierre@1
|
65 case 0: |
pierre@1
|
66 $nochannel[] = $aid; |
pierre@1
|
67 _debug_echo("ad_channel_cache: aid($aid) is valid if no valid ads found in current channel"); |
pierre@1
|
68 break; |
pierre@1
|
69 case 1: |
pierre@1
|
70 $valid[] = $aid; |
pierre@1
|
71 _debug_echo("ad_channel_cache: aid($aid) is valid"); |
pierre@1
|
72 break; |
pierre@1
|
73 case 2: |
pierre@1
|
74 _debug_echo("ad_channel_cache: aid($aid) is not valid"); |
pierre@1
|
75 break; |
pierre@1
|
76 } |
pierre@1
|
77 } |
pierre@1
|
78 } |
pierre@1
|
79 |
sly@2
|
80 // Apply weights, applicable for advertisements that are not assigned to any |
sly@2
|
81 // channel. |
sly@2
|
82 if (!empty($valid) && !empty($nochannel_weight)) { |
sly@2
|
83 $weights = array(); |
sly@2
|
84 foreach ($valid as $aid) { |
sly@2
|
85 if (isset($matched_channel[$aid])) { |
sly@2
|
86 $chid = $matched_channel[$aid]; |
sly@2
|
87 if (isset($nochannel_weight[$chid])) { |
sly@2
|
88 $weights[$aid] = $nochannel_weight[$chid]; |
sly@2
|
89 _debug_echo("ad_channel_cache: ad $aid in channel $chid with weight ". $nochannel_weight[$chid]); |
sly@2
|
90 } |
sly@2
|
91 else { |
sly@2
|
92 // by default, ads are assigned a weight of 100% |
sly@2
|
93 $weights[$aid] = 100; |
sly@2
|
94 _debug_echo("ad_channel_cache: ad $aid in channel $chid with default weight of 100"); |
sly@2
|
95 } |
sly@2
|
96 } |
sly@2
|
97 else { |
sly@2
|
98 // by default, ads are assigned a weight of 100% |
sly@2
|
99 $weights[$aid] = 100; |
sly@2
|
100 _debug_echo("ad_channel_cache: ad $aid in no channel with default weight of 100"); |
sly@2
|
101 } |
sly@2
|
102 } |
sly@2
|
103 if (!empty($weights)) { |
sly@2
|
104 $gcd = ad_channel_probability_gcd($weights); |
sly@2
|
105 $display = array(); |
sly@2
|
106 _debug_echo("ad_channel_cache: adjusting channel weights, gcd ($gcd)"); |
sly@2
|
107 foreach ($valid as $aid) { |
sly@2
|
108 $weight = $weights[$aid] / $gcd; |
sly@2
|
109 for ($i = 1; $i <= $weight; $i++) { |
sly@2
|
110 $display[] = $aid; |
sly@2
|
111 } |
sly@2
|
112 } |
sly@2
|
113 $valid = $display; |
sly@2
|
114 } |
sly@2
|
115 } |
sly@2
|
116 else if (empty($valid) && !empty($nochannel)) { |
pierre@1
|
117 _debug_echo("ad_channel_cache: using ads with no channel info"); |
pierre@1
|
118 $valid = $nochannel; |
pierre@1
|
119 } |
pierre@1
|
120 |
pierre@1
|
121 $premiere = adserve_cache('get_cache', 'premiere'); |
pierre@1
|
122 $premieres = array(); |
pierre@1
|
123 if (is_array($premiere)) { |
pierre@1
|
124 foreach ($valid as $aid) { |
pierre@1
|
125 if (in_array($aid, $premiere)) { |
pierre@1
|
126 _debug_echo("ad_channel_cache: aid($aid) is premiere advertisement"); |
pierre@1
|
127 $premieres[$aid] = $aid; |
pierre@1
|
128 } |
pierre@1
|
129 else { |
pierre@1
|
130 _debug_echo("ad_channel_cache: aid($aid) is not a premiere advertisement"); |
pierre@1
|
131 } |
pierre@1
|
132 } |
pierre@1
|
133 if (!empty($premieres)) { |
pierre@1
|
134 _debug_echo("ad_channel_cache: returning premiere advertisements"); |
pierre@1
|
135 return $premieres; |
pierre@1
|
136 } |
pierre@1
|
137 } |
pierre@1
|
138 _debug_echo("ad_channel_cache: returning non-premiere advertisements"); |
pierre@1
|
139 return $valid; |
pierre@1
|
140 } |
sly@2
|
141 |
sly@2
|
142 /** |
sly@2
|
143 * Returns the greatest common divisor of an array of integers. |
sly@2
|
144 */ |
sly@2
|
145 function ad_channel_probability_gcd($integers) { |
sly@2
|
146 $gcd = array_shift($integers); |
sly@2
|
147 |
sly@2
|
148 while (!empty($integers)) { |
sly@2
|
149 $gcd = _ad_channel_probability_gcd($gcd, array_shift($integers)); |
sly@2
|
150 } |
sly@2
|
151 return $gcd; |
sly@2
|
152 } |
sly@2
|
153 |
sly@2
|
154 /** |
sly@2
|
155 * Helper function to calculate the greatest common divisor using the Euclidean |
sly@2
|
156 * algorithm (http://en.wikipedia.org/wiki/Euclidean_algorithm). |
sly@2
|
157 */ |
sly@2
|
158 function _ad_channel_probability_gcd($a, $b) { |
sly@2
|
159 if ($b == 0) { |
sly@2
|
160 return $a; |
sly@2
|
161 } |
sly@2
|
162 else { |
sly@2
|
163 return _ad_channel_probability_gcd($b, $a % $b); |
sly@2
|
164 } |
sly@2
|
165 } |