pierre@0
|
1 <?php |
pierre@1
|
2 // $Id: ad.module,v 1.2.2.29.2.83.2.16.2.12 2009/03/31 04:41:03 jeremy Exp $ |
pierre@0
|
3 |
pierre@0
|
4 /** |
pierre@0
|
5 * @file |
pierre@0
|
6 * An advertising system for Drupal powered websites. |
pierre@0
|
7 * |
pierre@0
|
8 * Copyright (c) 2005-2009. |
pierre@0
|
9 * Jeremy Andrews <jeremy@tag1consulting.com>. |
pierre@0
|
10 */ |
pierre@0
|
11 |
pierre@1
|
12 require_once('ad_token.inc'); |
pierre@0
|
13 |
pierre@0
|
14 /** |
pierre@0
|
15 * Implementation of hook_theme(). |
pierre@0
|
16 */ |
pierre@0
|
17 function ad_theme() { |
pierre@0
|
18 return array( |
pierre@0
|
19 'ad_display' => array( |
pierre@0
|
20 'file' => 'ad.module', |
pierre@0
|
21 'arguments' => array( |
pierre@0
|
22 'group' => NULL, |
pierre@0
|
23 'display' => NULL, |
pierre@0
|
24 'method' => 'javascript', |
pierre@0
|
25 ), |
pierre@0
|
26 ), |
pierre@0
|
27 'ad_status_display' => array( |
pierre@0
|
28 'file' => 'ad.module', |
pierre@0
|
29 'arguments' => array( |
pierre@0
|
30 'node' => NULL, |
pierre@0
|
31 ), |
pierre@0
|
32 ), |
pierre@0
|
33 'ad_statistics_display' => array( |
pierre@0
|
34 'file' => 'ad.pages.inc', |
pierre@0
|
35 'arguments' => array( |
pierre@0
|
36 'statistics' => NULL, |
pierre@0
|
37 ), |
pierre@0
|
38 ), |
pierre@0
|
39 'node_ad' => array( |
pierre@0
|
40 'file' => 'ad.pages.inc', |
pierre@0
|
41 'arguments' => array( |
pierre@0
|
42 'node' => NULL, |
pierre@0
|
43 'yield_form' => TRUE, |
pierre@0
|
44 ), |
pierre@0
|
45 ), |
pierre@0
|
46 'ad_admin_ads' => array( |
pierre@0
|
47 'file' => 'ad.admin.inc', |
pierre@0
|
48 'arguments' => array( |
pierre@0
|
49 'form' => NULL, |
pierre@0
|
50 ), |
pierre@0
|
51 ), |
pierre@0
|
52 'ad_filters' => array( |
pierre@0
|
53 'file' => 'ad.admin.inc', |
pierre@0
|
54 'arguments' => array( |
pierre@0
|
55 'form' => NULL, |
pierre@0
|
56 ), |
pierre@0
|
57 ), |
pierre@0
|
58 'ad_filter_form' => array( |
pierre@0
|
59 'file' => 'ad.admin.inc', |
pierre@0
|
60 'arguments' => array( |
pierre@0
|
61 'form' => NULL, |
pierre@0
|
62 ), |
pierre@0
|
63 ), |
pierre@0
|
64 ); |
pierre@0
|
65 }; |
pierre@0
|
66 |
pierre@0
|
67 /** |
pierre@0
|
68 * Use this function to display ads from a specified group. |
pierre@0
|
69 * |
pierre@0
|
70 * @param $group |
pierre@0
|
71 * The ad group tid to display ads from. |
pierre@0
|
72 * @param $quantity |
pierre@0
|
73 * Optionally specify the number of unique ads to display. |
pierre@0
|
74 * @param $options |
pierre@0
|
75 * Any number of options from this list: hostid, nids. |
pierre@0
|
76 */ |
pierre@0
|
77 function ad($group = FALSE, $quantity = 1, $options = array()) { |
pierre@0
|
78 global $base_url; |
pierre@0
|
79 |
pierre@0
|
80 $adserve = variable_get('adserve', ''); |
pierre@0
|
81 $adserveinc = variable_get('adserveinc', ''); |
pierre@0
|
82 if (empty($adserve) || empty($adserveinc)) { |
pierre@0
|
83 // This is probably the first time ad() has been called. |
pierre@0
|
84 _ad_check_installation(); |
pierre@0
|
85 $adserve = variable_get('adserve', ''); |
pierre@0
|
86 $adserveinc = variable_get('adserveinc', ''); |
pierre@0
|
87 } |
pierre@0
|
88 if (!file_exists($adserve) || !file_exists($adserveinc)) { |
pierre@0
|
89 drupal_set_message(t('Ads cannot be displayed. The ad module is <a href="@misconfigured">misconfigured</a>, failed to locate the required <em>serve.php</em> ond/or <em>adserve.inc</em> file.', array('@misconfigured' => url('admin/content/ad/configure'))), 'error'); |
pierre@0
|
90 _ad_check_installation(); |
pierre@0
|
91 return (t('The ad module is <a href="@misconfigured">misconfigured</a>.', array('@misconfigured' => url('admin/content/ad/configure')))); |
pierre@0
|
92 } |
pierre@0
|
93 |
pierre@0
|
94 // Be sure a display method has been chosen. |
pierre@0
|
95 if (!isset($options['ad_display'])) { |
pierre@0
|
96 $options['ad_display'] = variable_get('ad_display', 'javascript'); |
pierre@0
|
97 } |
pierre@0
|
98 $options['quantity'] = isset($quantity) ? $quantity : 1; |
pierre@0
|
99 if (!isset($options['tids'])) { |
pierre@0
|
100 $options['tids'] = $group; |
pierre@0
|
101 } |
pierre@0
|
102 $options['cache'] = variable_get('ad_cache', 'none'); |
pierre@0
|
103 |
pierre@0
|
104 switch ($options['ad_display']) { |
pierre@0
|
105 case 'raw': |
pierre@0
|
106 require_once(drupal_get_path('module', 'ad') .'/adserve.inc'); |
pierre@1
|
107 require_once(drupal_get_path('module', 'ad') .'/adcache.inc'); |
pierre@0
|
108 $output = adserve_ad($options); |
pierre@0
|
109 break; |
pierre@0
|
110 case 'iframe': |
pierre@0
|
111 case 'jquery': |
pierre@0
|
112 $query['m'] = $options['ad_display']; |
pierre@0
|
113 // Fall through... |
pierre@0
|
114 case 'javascript': |
pierre@0
|
115 default: |
pierre@0
|
116 $query['q'] = $quantity; |
pierre@0
|
117 if (isset($options['hostid'])) { |
pierre@0
|
118 $query['k'] = $options['hostid']; |
pierre@0
|
119 } |
pierre@0
|
120 // Allow external cache files to define additional display variables. |
pierre@0
|
121 if ($options['cache'] != 'none') { |
pierre@0
|
122 $query['c'] = $options['cache']; |
pierre@0
|
123 $cache_variables = module_invoke('ad_cache_'. $options['cache'], 'adcacheapi', 'display_variables', array()); |
pierre@0
|
124 if (is_array($cache_variables)) { |
pierre@0
|
125 foreach ($cache_variables as $key => $value) { |
pierre@0
|
126 $query[$key] = $value; |
pierre@0
|
127 } |
pierre@0
|
128 } |
pierre@0
|
129 } |
pierre@0
|
130 // Allow ad_type modules to define additional display variables. |
pierre@0
|
131 $type_variables = module_invoke_all('adapi', 'display_variables', array()); |
pierre@0
|
132 if (is_array($type_variables)) { |
pierre@0
|
133 foreach ($type_variables as $key => $value) { |
pierre@0
|
134 $query[$key] = $value; |
pierre@0
|
135 } |
pierre@0
|
136 } |
pierre@0
|
137 if (isset($options['nids'])) { |
pierre@0
|
138 // Choose ads from the provided list of node Id's. |
pierre@0
|
139 $nids = $options['nids']; |
pierre@0
|
140 $query['n'] = $nids; |
pierre@0
|
141 $group = "nids-$nids"; |
pierre@0
|
142 } |
pierre@0
|
143 else if (isset($options['tids'])) { |
pierre@0
|
144 // Choose ads from the provided list of taxonomy terms. |
pierre@0
|
145 $tids = $options['tids']; |
pierre@0
|
146 $query['t'] = $tids; |
pierre@0
|
147 $group = "tids-$tids"; |
pierre@0
|
148 } |
pierre@0
|
149 else { |
pierre@0
|
150 // Choose ads from the specified group. |
pierre@0
|
151 $query['t'] = $group; |
pierre@0
|
152 $options['tids'] = $group; |
pierre@0
|
153 } |
pierre@1
|
154 if (isset($options['url'])) { |
pierre@1
|
155 $query['u'] = $options['url']; |
pierre@1
|
156 } |
pierre@1
|
157 else { |
pierre@1
|
158 $query['u'] = $_GET['q']; |
pierre@1
|
159 } |
pierre@0
|
160 $src = url($base_url .'/'. $adserve, array('query' => $query)); |
pierre@0
|
161 if ($options['ad_display'] == 'iframe') { |
pierre@0
|
162 // TODO: We need to know the IFrame size before it is displayed. This |
pierre@0
|
163 // limits the flexibility of what can be displayed in these frames. |
pierre@0
|
164 // For now we'll have a global value, later we'll add per-group |
pierre@0
|
165 // over-rides. |
pierre@0
|
166 $append = 'frameborder="'. variable_get('ad_iframe_frameborder', 0) .'" '; |
pierre@0
|
167 $append .= 'scrolling="'. variable_get('ad_iframe_scroll', 'auto') .'" '; |
pierre@0
|
168 $append .= 'name="'. $group .'" '; |
pierre@0
|
169 if ($height = variable_get('ad_iframe_height', '')) { |
pierre@0
|
170 $append .= 'height="'. $height .'" '; |
pierre@0
|
171 } |
pierre@0
|
172 if ($width = variable_get('ad_iframe_width', '')) { |
pierre@0
|
173 $append .= 'width="'. $width .'" '; |
pierre@0
|
174 } |
pierre@0
|
175 $output = '<iframe src="'. $src ."\" $append></iframe>"; |
pierre@0
|
176 } |
pierre@0
|
177 else if ($options['ad_display'] == 'jquery') { |
pierre@0
|
178 // The theme function uses this to generate a CSS id for jQuery to use. |
pierre@0
|
179 $output = $src; |
pierre@0
|
180 } |
pierre@0
|
181 else { |
pierre@1
|
182 $output = "<script type='text/javascript' src='$src'></script>"; |
pierre@0
|
183 } |
pierre@0
|
184 break; |
pierre@0
|
185 } |
pierre@0
|
186 |
pierre@0
|
187 if (user_access('show advertisements')) { |
pierre@1
|
188 if (isset($options['div']) && $options['div'] !== FALSE) { |
pierre@1
|
189 return theme('ad_display', $group, $output, $options['ad_display']); |
pierre@1
|
190 } |
pierre@1
|
191 else { |
pierre@1
|
192 return theme('ad_display', $group, $output, 'raw'); |
pierre@1
|
193 } |
pierre@0
|
194 } |
pierre@0
|
195 else { |
pierre@0
|
196 return theme('ad_display', 'none', "<!-- Enable 'show advertisements' permission if you wish to display ads here. -->"); |
pierre@0
|
197 } |
pierre@0
|
198 } |
pierre@0
|
199 |
pierre@0
|
200 /** |
pierre@0
|
201 * Function to display the actual advertisement to the screen. Wrap it in a |
pierre@0
|
202 * theme function to make it possible to customize in your own theme. |
pierre@0
|
203 */ |
pierre@0
|
204 function theme_ad_display($group, $display, $method = 'javascript') { |
pierre@1
|
205 static $id = -1; |
pierre@1
|
206 |
pierre@1
|
207 // Increment counter for displaying multiple advertisements on the page. |
pierre@1
|
208 $id++; |
pierre@0
|
209 |
pierre@0
|
210 // The naming convention for the id attribute doesn't allow commas. |
pierre@0
|
211 $group = preg_replace('/[,]/', '+', $group); |
pierre@0
|
212 |
pierre@0
|
213 if ($method == 'jquery') { |
pierre@0
|
214 drupal_add_js('misc/jquery.js', 'core'); |
pierre@1
|
215 return "\n<div class=\"advertisement group-$group\" id=\"group-id-$id\">\n <script type=\"text/javascript\">\n//<![CDATA[\n $(document).ready(function(){ jQuery(\"div#group-id-$id\").load(\"$display\"); });\n //]]>\n </script>\n</div>\n"; |
pierre@1
|
216 } |
pierre@1
|
217 else if ($method == 'raw') { |
pierre@1
|
218 return $display; |
pierre@0
|
219 } |
pierre@0
|
220 else { |
pierre@0
|
221 return "\n<div class=\"advertisement group-$group\" id=\"group-id-$group\">$display</div>\n"; |
pierre@0
|
222 } |
pierre@0
|
223 } |
pierre@0
|
224 |
pierre@0
|
225 /** |
pierre@0
|
226 * Update click counter then redirect host to ad's target URL. |
pierre@0
|
227 */ |
pierre@1
|
228 function ad_redirect($aid, $group = NULL) { |
pierre@0
|
229 global $user; |
pierre@1
|
230 $hostid = isset($_GET['hostid']) ? $_GET['hostid'] : ''; |
pierre@1
|
231 $extra = isset($_GET['extra']) ? $_GET['extra'] : ''; |
pierre@0
|
232 if (function_exists('click_filter_status')) { |
pierre@0
|
233 $status = click_filter_status($aid, $hostid); |
pierre@0
|
234 if ($status == CLICK_VALID) { |
pierre@0
|
235 ad_statistics_increment($aid, 'click', $group, $hostid); |
pierre@0
|
236 } |
pierre@0
|
237 } |
pierre@0
|
238 else { |
pierre@0
|
239 // We're not filtering clicks, so all clicks are valid. |
pierre@0
|
240 ad_statistics_increment($aid, 'click', $group, $hostid); |
pierre@0
|
241 $status = 0; |
pierre@0
|
242 } |
pierre@0
|
243 // Allow source url to be passed in. |
pierre@0
|
244 $url = isset($_GET['u']) ? $_GET['u'] : ''; |
pierre@0
|
245 if (!isset($url) || !valid_url($url)) { |
pierre@0
|
246 $url = referer_uri(); |
pierre@0
|
247 } |
pierre@1
|
248 db_query("INSERT INTO {ad_clicks} (aid, uid, status, hostname, user_agent, adgroup, extra, hostid, url, timestamp) VALUES (%d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', %d)", $aid, $user->uid, $status, ip_address(), $_SERVER['HTTP_USER_AGENT'], $group, $extra, $hostid, $url, time()); |
pierre@0
|
249 |
pierre@0
|
250 // Determine where we're supposed to redirect the user. |
pierre@0
|
251 $adtype = db_result(db_query('SELECT adtype FROM {ads} WHERE aid = %d', $aid)); |
pierre@0
|
252 |
pierre@0
|
253 $node->nid = $node->aid = $aid; |
pierre@0
|
254 $node->hostid = $hostid; |
pierre@0
|
255 $url = module_invoke('ad_'. $adtype, 'adapi', 'redirect', $node); |
pierre@0
|
256 if (isset($url)) { |
pierre@0
|
257 watchdog('ad', 'Clicked %type ad aid %aid hostid %hostid.', array('%type' => $adtype, '%aid' => $aid, '%hostid' => $hostid)); |
pierre@0
|
258 header('Location: '. $url); |
pierre@0
|
259 } |
pierre@0
|
260 else { |
pierre@0
|
261 watchdog('ad', 'Ad redirection failed for aid %aid hostid %hostid, failed to load destination URL. ', array('%aid' => $aid, '%hostid' => $hostid)); |
pierre@0
|
262 drupal_goto(''); |
pierre@0
|
263 } |
pierre@0
|
264 } |
pierre@0
|
265 |
pierre@0
|
266 /** |
pierre@0
|
267 * Ad API Helper Function: |
pierre@0
|
268 * Append all necessary attributes to <a> tags. |
pierre@0
|
269 */ |
pierre@0
|
270 function ad_link_attributes() { |
pierre@0
|
271 return array_merge(ad_link_target(TRUE), ad_link_nofollow(TRUE)); |
pierre@0
|
272 } |
pierre@0
|
273 |
pierre@0
|
274 /** |
pierre@0
|
275 * Ad API Helper Function: |
pierre@0
|
276 * Provide XHTML-strict-compatible target window onclick-handlers based on |
pierre@0
|
277 * global configuration. |
pierre@0
|
278 */ |
pierre@0
|
279 function ad_link_target() { |
pierre@0
|
280 switch (variable_get('ad_link_target', '_self')) { |
pierre@0
|
281 case '_blank': |
pierre@0
|
282 $target = array('onclick' => 'window.open(this.href); return false;'); |
pierre@0
|
283 break; |
pierre@0
|
284 case '_parent': |
pierre@0
|
285 $target = array('onclick' => 'window.parent.location = this.href; return false;'); |
pierre@0
|
286 break; |
pierre@0
|
287 case '_top': |
pierre@0
|
288 $target = array('onclick' => 'window.top.location = this.href; return false;'); |
pierre@0
|
289 break; |
pierre@0
|
290 default: |
pierre@0
|
291 $target = array(); |
pierre@0
|
292 break; |
pierre@0
|
293 } |
pierre@0
|
294 return $target; |
pierre@0
|
295 } |
pierre@0
|
296 |
pierre@0
|
297 /** |
pierre@1
|
298 * Force the cache to be flushed. |
pierre@1
|
299 */ |
pierre@1
|
300 function ad_rebuild_cache($verbose = FALSE) { |
pierre@1
|
301 $cache = variable_get('ad_cache', 'none'); |
pierre@1
|
302 $build = "ad_cache_{$cache}_build"; |
pierre@1
|
303 if (function_exists($build)) { |
pierre@1
|
304 if ($verbose) { |
pierre@1
|
305 drupal_set_message('Rebuilding ad cache.'); |
pierre@1
|
306 } |
pierre@1
|
307 $build(); |
pierre@1
|
308 } |
pierre@1
|
309 } |
pierre@1
|
310 |
pierre@1
|
311 /** |
pierre@0
|
312 * Ad API Helper Function: |
pierre@0
|
313 * Append rel="nofollow" if globally enabled. |
pierre@0
|
314 */ |
pierre@0
|
315 function ad_link_nofollow() { |
pierre@0
|
316 if (variable_get('ad_link_nofollow', 0)) { |
pierre@0
|
317 $nofollow = array('rel' => 'nofollow'); |
pierre@0
|
318 } |
pierre@0
|
319 else { |
pierre@0
|
320 $nofollow = array(); |
pierre@0
|
321 } |
pierre@0
|
322 return $nofollow; |
pierre@0
|
323 } |
pierre@0
|
324 |
pierre@0
|
325 /** |
pierre@0
|
326 * Increment action counter. |
pierre@0
|
327 */ |
pierre@0
|
328 function ad_statistics_increment($aid, $action, $group = NULL, $hostid = NULL) { |
pierre@0
|
329 // Update action statistics. |
pierre@0
|
330 db_query("UPDATE {ad_statistics} SET count = count + 1 WHERE date = %d AND aid = %d AND action = '%s' AND adgroup = '%s' AND hostid = '%s'", date('YmdH'), $aid, $action, $group, $hostid); |
pierre@0
|
331 // If column doesn't already exist, we need to add it. |
pierre@0
|
332 if (!db_affected_rows()) { |
pierre@0
|
333 db_query("INSERT INTO {ad_statistics} (aid, adgroup, hostid, date, action, count) VALUES(%d, '%s', '%s', %d, '%s', 1)", $aid, $group, $hostid, date('YmdH'), $action); |
pierre@0
|
334 // If another process already added this row our INSERT will fail, if so we |
pierre@0
|
335 // still need to increment it so we don't loose an action. |
pierre@0
|
336 if (!db_affected_rows()) { |
pierre@0
|
337 db_query("UPDATE {ad_statistics} SET count = count + 1 WHERE date = %d AND aid = %d AND action = '%s' AND adgroup = '%s' AND hostid = '%s'", date('YmdH'), $aid, $action, $group, $hostid); |
pierre@0
|
338 } |
pierre@0
|
339 } |
pierre@0
|
340 |
pierre@0
|
341 $event = array('aid' => $aid, 'action' => $action, 'hostid' => $hostid); |
pierre@0
|
342 module_invoke_all('adapi', 'statistics_increment', $event); |
pierre@0
|
343 } |
pierre@0
|
344 |
pierre@1
|
345 /** |
pierre@1
|
346 * Return an array with all status values user has permission to set. |
pierre@1
|
347 * A user with 'administer advertisements' permission can update any status. |
pierre@1
|
348 */ |
pierre@1
|
349 function ad_status_array($aid = 0, $status = NULL) { |
pierre@1
|
350 $permissions = array(); |
pierre@1
|
351 // mark status as pending |
pierre@1
|
352 if (user_access('administer advertisements') || |
pierre@1
|
353 $status == 'pending' || $status == NULL || |
pierre@1
|
354 ad_permission($aid, 'set status as pending')) { |
pierre@1
|
355 $permissions['pending'] = t('This advertisement is currently waiting for administrative approval.'); |
pierre@0
|
356 } |
pierre@1
|
357 // mark status from pending to approved |
pierre@1
|
358 if (user_access('administer advertisements') || |
pierre@1
|
359 $status == 'approved' || |
pierre@1
|
360 ($status == 'pending' && |
pierre@1
|
361 ad_permission($aid, 'set status from pending to approved'))) { |
pierre@1
|
362 $permissions['approved'] = t('This advertisement has been approved and is currently waiting to be activated.'); |
pierre@0
|
363 } |
pierre@1
|
364 // mark status as active (from pending, approved, or offline) |
pierre@1
|
365 if (user_access('administer advertisements') || |
pierre@1
|
366 $status == 'active' || |
pierre@1
|
367 ($status == 'approved' && |
pierre@1
|
368 ad_permission($aid, 'set status from approved to active')) || |
pierre@1
|
369 ($status == 'offline' && |
pierre@1
|
370 ad_permission($aid, 'set status from offline to active'))) { |
pierre@1
|
371 $permissions['active'] = t('This advertisement is actively being displayed.'); |
pierre@1
|
372 } |
pierre@1
|
373 // mark status as offline (from pending, approved, or active) |
pierre@1
|
374 if (user_access('administer advertisements') || |
pierre@1
|
375 $status == 'offline' || |
pierre@1
|
376 ($status == 'approved' && |
pierre@1
|
377 ad_permission($aid, 'set status from approved to offline')) || |
pierre@1
|
378 ($status == 'active' && |
pierre@1
|
379 ad_permission($aid, 'set status from active to offline'))) { |
pierre@1
|
380 $permissions['offline'] = t('This advertisement has been temporarily disabled by its owner and is not currently being displayed.'); |
pierre@1
|
381 } |
pierre@1
|
382 // mark status as expired (from active or offline) |
pierre@1
|
383 if (user_access('administer advertisements') || |
pierre@1
|
384 $status == 'expired' || |
pierre@1
|
385 ($status == 'active' && |
pierre@1
|
386 ad_permission($aid, 'set status from active to expired')) || |
pierre@1
|
387 ($status == 'offline' && |
pierre@1
|
388 ad_permission($aid, 'set status from offline to expired'))) { |
pierre@1
|
389 $permissions['expired'] = t('This advertisement has expired and is no longer being displayed.'); |
pierre@1
|
390 } |
pierre@1
|
391 // mark status as denied (from pending or any) |
pierre@1
|
392 if (user_access('administer advertisements') || |
pierre@1
|
393 $status == 'denied' || |
pierre@1
|
394 ($status == 'pending' && |
pierre@1
|
395 ad_permission($aid, 'set status from pending to denied')) || |
pierre@1
|
396 ad_permission($aid, 'set status as denied')) { |
pierre@1
|
397 $permissions['denied'] = t('This advertisement was refused by the site administrator and will not be displayed.'); |
pierre@1
|
398 } |
pierre@1
|
399 return $permissions; |
pierre@0
|
400 } |
pierre@0
|
401 |
pierre@0
|
402 /** |
pierre@0
|
403 * Display the status of the currently viewed ad. |
pierre@0
|
404 */ |
pierre@0
|
405 function theme_ad_status_display($node) { |
pierre@1
|
406 if (isset($node->adstatus)) { |
pierre@1
|
407 $status_array = ad_status_array($node->nid, $node->adstatus); |
pierre@1
|
408 $output = '<div class="adstatus">'; |
pierre@1
|
409 $output .= '<p>'. t($status_array[$node->adstatus]) .'</p>'; |
pierre@1
|
410 switch ($node->adstatus) { |
pierre@1
|
411 case 'approved': |
pierre@1
|
412 if ($node->autoactivate) { |
pierre@1
|
413 $output .= '<p>'. t('This advertisement will be automatically activated on %timestamp, in %time.', array('%timestamp' => format_date($node->autoactivate, 'large'), '%time' => format_interval($node->autoactivate - time()))) .'</p>'; |
pierre@1
|
414 } |
pierre@1
|
415 break; |
pierre@1
|
416 case 'active': |
pierre@1
|
417 $activated = db_result(db_query("SELECT activated FROM {ads} WHERE aid = %d", $node->nid)); |
pierre@1
|
418 if ($activated) { |
pierre@1
|
419 $output .= '<p>'. t('This advertisement has been active since %date.', array('%date' => format_date($activated, 'large'))) .'</p>'; |
pierre@1
|
420 } |
pierre@1
|
421 if ($node->autoexpire) { |
pierre@1
|
422 $output .= '<p>'. t('This advertisement will expire on %timestamp, in %time.', array('%timestamp' => format_date($node->autoexpire, 'large'), '%time' => format_interval($node->autoexpire - time()))) .'</p>'; |
pierre@1
|
423 } |
pierre@1
|
424 if ($node->maxviews) { |
pierre@1
|
425 $views = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} WHERE aid = %d AND action = 'view' AND date >= %d", $node->nid, date('YmdH', $node->activated))); |
pierre@1
|
426 $output .= '<p>'. t('This advertisement will expire after %left more impressions.', array('%left' => $node->maxviews - $views)) .'</p>'; |
pierre@1
|
427 } |
pierre@1
|
428 if ($node->maxclicks) { |
pierre@1
|
429 $clicks = (int)db_result(db_query("SELECT SUM(count) FROM {ad_statistics} WHERE aid = %d AND action = 'click' AND date >= %d", $node->nid, date('YmdH', $node->activated))); |
pierre@1
|
430 $output .= '<p>'. t('This advertisement will expire after %left more clicks.', array('%left' => $node->maxclicks - $clicks)) .'</p>'; |
pierre@1
|
431 } |
pierre@1
|
432 break; |
pierre@1
|
433 case 'expired': |
pierre@1
|
434 $expired = db_result(db_query("SELECT expired FROM {ads} WHERE aid = %d", $node->nid)); |
pierre@1
|
435 if ($expired) { |
pierre@1
|
436 $output .= '<p>'. t('This advertisement expired %date.', array('%date' => format_date($expired, 'large'))) .'</p>'; |
pierre@1
|
437 } |
pierre@1
|
438 break; |
pierre@1
|
439 } |
pierre@1
|
440 $output .= '</div>'; |
pierre@1
|
441 return theme('box', t('Status'), $output); |
pierre@0
|
442 } |
pierre@0
|
443 } |
pierre@0
|
444 |
pierre@0
|
445 /** |
pierre@0
|
446 * Implementation of hook_help(). |
pierre@0
|
447 */ |
pierre@0
|
448 function ad_help($path, $arg) { |
pierre@0
|
449 $output = ''; |
pierre@0
|
450 switch ($path) { |
pierre@0
|
451 case 'admin/help#ad': |
pierre@0
|
452 $output = '<p>'. t('The ad module provides a complete advertising system for Drupal powered websites. It does this through an API that allow other modules to handle various types of advertising content. For example, if enabled together with the ad_image module you will be able to display image based advertisements such as banner ads.') .'</p>'; |
pierre@0
|
453 break; |
pierre@0
|
454 case 'node/add/ad': |
pierre@0
|
455 $output = '<p>'. t('Advertisements can be randomly displayed to visitors of your website.') .'</p>'; |
pierre@0
|
456 break; |
pierre@0
|
457 } |
pierre@0
|
458 return $output; |
pierre@0
|
459 } |
pierre@0
|
460 |
pierre@0
|
461 /** |
pierre@0
|
462 * Implementation of hook_cron(). |
pierre@0
|
463 */ |
pierre@0
|
464 function ad_cron() { |
pierre@0
|
465 if (time() - variable_get('ad_cron_timestamp', 0) >= 60) { |
pierre@0
|
466 // Locate ads that need to be activated or expired. |
pierre@0
|
467 $result = db_query('SELECT aid, adstatus, adtype, autoactivate, autoactivated, autoexpire, autoexpired FROM {ads} WHERE autoactivate <> 0 OR autoexpire <> 0'); |
pierre@0
|
468 while ($ad = db_fetch_object($result)) { |
pierre@0
|
469 switch ($ad->adstatus) { |
pierre@0
|
470 case 'approved': { |
pierre@0
|
471 // See if this ad is ready to be activated. |
pierre@0
|
472 if ($ad->autoactivate && $ad->autoactivate <= time()) { |
pierre@0
|
473 $node = node_load($ad->aid); |
pierre@0
|
474 |
pierre@0
|
475 // Activate the ad. |
pierre@0
|
476 db_query("UPDATE {ads} SET adstatus = 'active', autoactivate = 0, autoactivated = %d, activated = %d WHERE aid = %d", time(), time(), $ad->aid); |
pierre@0
|
477 ad_statistics_increment($ad->aid, 'autoactivated'); |
pierre@0
|
478 ad_statistics_increment($ad->aid, 'active'); |
pierre@0
|
479 |
pierre@0
|
480 watchdog('ad', 'Automatically activated ad %title with nid %nid.', array('%title' => $node->title, '%nid' => $node->nid)); |
pierre@0
|
481 |
pierre@0
|
482 // Allow modules to do special processing to automatically |
pierre@0
|
483 // activated advertisements. |
pierre@0
|
484 module_invoke('ad_'. $ad->adtype, 'adapi', 'autoactivate', $node); |
pierre@0
|
485 } |
pierre@0
|
486 else if (!$ad->autoactivate) { |
pierre@0
|
487 // Once daily warn that there's an ad stuck in approved state. |
pierre@0
|
488 if (time() - variable_get("ad_autoactivate_warning_$ad->aid", 0) >= 8600) { |
pierre@0
|
489 watchdog('ad', 'Warning: ad %title with nid %nid in approved state has no autoactivate date set.', array('%title' => $node->title, '%nid' => $node->nid)); |
pierre@0
|
490 variable_set("ad_autoactivate_warning_$ad->aid", time()); |
pierre@0
|
491 } |
pierre@0
|
492 } |
pierre@0
|
493 break; |
pierre@0
|
494 } |
pierre@0
|
495 case 'active': { |
pierre@0
|
496 // See if this ad is ready to be activated. |
pierre@0
|
497 if ($ad->autoexpire && $ad->autoexpire <= time()) { |
pierre@0
|
498 $node = node_load($ad->aid); |
pierre@0
|
499 |
pierre@0
|
500 // Expire the ad. |
pierre@0
|
501 db_query("UPDATE {ads} SET adstatus = 'expired', autoexpire = 0, autoexpired = %d, expired = %d WHERE aid = %d", time(), time(), $ad->aid); |
pierre@0
|
502 ad_statistics_increment($ad->aid, 'autoexpired'); |
pierre@0
|
503 ad_statistics_increment($ad->aid, 'expired'); |
pierre@0
|
504 |
pierre@0
|
505 watchdog('ad', 'Automatically expired ad %title with nid %nid.', array('%title' => $node->title, '%nid' => $node->nid)); |
pierre@0
|
506 |
pierre@0
|
507 // Allow modules to do special processing to automatically |
pierre@0
|
508 // activated advertisements. |
pierre@0
|
509 module_invoke('ad_'. $ad->adtype, 'adapi', 'autoexpire', $node); |
pierre@0
|
510 } |
pierre@0
|
511 else if (!$ad->autoexpire) { |
pierre@0
|
512 // Ad is already activated, but has autoactivate timestamp set. |
pierre@0
|
513 db_query("UPDATE {ads} SET autoactivate = 0 WHERE aid = %d", $ad->aid); |
pierre@0
|
514 } |
pierre@0
|
515 break; |
pierre@0
|
516 } |
pierre@0
|
517 default: |
pierre@0
|
518 $node = node_load($ad->aid); |
pierre@0
|
519 db_query('UPDATE {ads} SET autoactivate = 0, autoexpire = 0 WHERE aid = %d', $ad->aid); |
pierre@0
|
520 watchdog('ad', 'Warning: reset %type timestamp on advertisement %title with nid %nid because it is in %state state.', array('%title' => $node->title, '%nid' => $node->nid, '%type' => $ad->autoactivate ? 'autoactivate' : 'autoexpire', '%state' => $ad->adstatus)); |
pierre@0
|
521 } |
pierre@0
|
522 } |
pierre@0
|
523 variable_set('ad_cron_timestamp', time()); |
pierre@0
|
524 } |
pierre@0
|
525 } |
pierre@0
|
526 |
pierre@0
|
527 /** |
pierre@0
|
528 * Implementation of hook_perm(). |
pierre@0
|
529 */ |
pierre@0
|
530 function ad_perm() { |
pierre@0
|
531 return array('administer advertisements', |
pierre@0
|
532 'create advertisements', |
pierre@0
|
533 'edit own advertisements', |
pierre@1
|
534 'edit any advertisement', |
pierre@1
|
535 'delete own advertisements', |
pierre@1
|
536 'delete any advertisement', |
pierre@0
|
537 'show advertisements'); |
pierre@0
|
538 } |
pierre@0
|
539 |
pierre@0
|
540 /** |
pierre@0
|
541 * Implementation of hook_node_info(). |
pierre@0
|
542 */ |
pierre@0
|
543 function ad_node_info() { |
pierre@0
|
544 $items['ad'] = array( |
pierre@0
|
545 'name' => t('Advertisement'), |
pierre@0
|
546 'module' => 'ad', |
pierre@0
|
547 'description' => t('Advertisements can be randomly displayed to visitors of your website.'), |
pierre@0
|
548 ); |
pierre@0
|
549 return $items; |
pierre@0
|
550 } |
pierre@0
|
551 |
pierre@0
|
552 /** |
pierre@0
|
553 * Implementation of hook_access(). |
pierre@0
|
554 */ |
pierre@0
|
555 function ad_access($op, $node, $account) { |
pierre@1
|
556 switch ($op) { |
pierre@1
|
557 case 'create': |
pierre@1
|
558 return (user_access('create advertisements', $account) || user_access('administer advertisements')); |
pierre@1
|
559 case 'update': |
pierre@1
|
560 return (user_access('edit any advertisement', $account) || (user_access('edit own advertisements', $account) && is_ad_owner($node->nid)) || user_access('administer advertisements', $account)); |
pierre@1
|
561 case 'delete': |
pierre@1
|
562 return (user_access('delete any advertisement', $account) || (user_access('delete own advertisements', $account) && is_ad_owner($node->nid)) || user_access('administer advertisements', $account)); |
pierre@1
|
563 case 'view': |
pierre@1
|
564 return (user_access('show advertisements', $account) || user_access('administer advertisements', $account)); |
pierre@0
|
565 } |
pierre@0
|
566 } |
pierre@0
|
567 |
pierre@0
|
568 /** |
pierre@0
|
569 * Implementation of hook_form(). |
pierre@0
|
570 */ |
pierre@1
|
571 function ad_form(&$node, &$form_state) { |
pierre@0
|
572 $form = array(); |
pierre@0
|
573 |
pierre@1
|
574 // When form_state is not empty, we should rather use it's values |
pierre@1
|
575 // to not loose data if validation fails. |
pierre@1
|
576 if (!empty($form_state['values'])) { |
pierre@1
|
577 $node = (object)$form_state['values']; |
pierre@0
|
578 } |
pierre@0
|
579 |
pierre@0
|
580 $form['aid'] = array( |
pierre@0
|
581 '#type' => 'value', |
pierre@0
|
582 '#value' => isset($node->nid) ? $node->nid : 0, |
pierre@0
|
583 ); |
pierre@0
|
584 |
pierre@0
|
585 $form['title'] = array( |
pierre@0
|
586 '#type' => 'textfield', |
pierre@0
|
587 '#title' => t('Title'), |
pierre@0
|
588 '#required' => TRUE, |
pierre@0
|
589 '#default_value' => isset($node->title) ? $node->title : '', |
pierre@0
|
590 ); |
pierre@0
|
591 $form['body_filter']['body'] = array( |
pierre@0
|
592 '#type' => 'textarea', |
pierre@0
|
593 '#title' => t('Description'), |
pierre@0
|
594 '#default_value' => isset($node->body) ? $node->body : '', |
pierre@0
|
595 '#rows' => 3 |
pierre@0
|
596 ); |
pierre@0
|
597 $form['body_filter']['format'] = filter_form($node->format); |
pierre@0
|
598 |
pierre@0
|
599 // determine the current ad type |
pierre@0
|
600 if (!isset($adtype)) { |
pierre@0
|
601 $adtypes = ad_get_types(); |
pierre@0
|
602 if (sizeof($adtypes) == 1) { |
pierre@0
|
603 $adtype = key($adtypes); |
pierre@0
|
604 } |
pierre@0
|
605 else if (!sizeof($adtypes)) { |
pierre@0
|
606 drupal_set_message(t('At least one ad type module must be enabled before you can create advertisements. For example, try <a href="!url">enabling</a> the ad_text or ad_image module.', array('!url' => url('admin/build/modules'))), 'error'); |
pierre@0
|
607 } |
pierre@0
|
608 } |
pierre@0
|
609 |
pierre@1
|
610 // display ad type switch |
pierre@1
|
611 if (!isset($node->adtype) || isset($node->adtype_select)) { |
pierre@1
|
612 $adtypes = array(0 => '---'); |
pierre@1
|
613 $adtypes += ad_get_types('name'); |
pierre@1
|
614 $form['select'] = array( |
pierre@1
|
615 '#type' => 'fieldset', |
pierre@1
|
616 '#title' => t('Select Ad type'), |
pierre@1
|
617 '#prefix' => '<div class="container-inline">', |
pierre@1
|
618 '#suffix' => '</div>', |
pierre@1
|
619 '#weight' => 3, |
pierre@1
|
620 ); |
pierre@1
|
621 $form['select']['adtype_select'] = array( |
pierre@1
|
622 '#type' => 'select', |
pierre@1
|
623 '#required' => TRUE, |
pierre@1
|
624 '#options' => $adtypes, |
pierre@1
|
625 '#default_value' => isset($node->adtype_select) ? $node->adtype_select : '', |
pierre@1
|
626 ); |
pierre@1
|
627 $form['select']['adtype_submit'] = array( |
pierre@1
|
628 '#type' => 'submit', |
pierre@1
|
629 '#value' => t('Select'), |
pierre@1
|
630 '#validate' => array('ad_select_adtype'), |
pierre@1
|
631 '#ahah' => array( |
pierre@1
|
632 'path' => 'node/add/ad/ahah', |
pierre@1
|
633 'wrapper' => 'adtype-ahah-wrapper', |
pierre@1
|
634 ), |
pierre@1
|
635 ); |
pierre@1
|
636 } |
pierre@0
|
637 // display type-specific options |
pierre@1
|
638 if (isset($node->adtype) && $node->adtype) { |
pierre@1
|
639 if (isset($node->adtype_select) && $node->adtype_select && ($node->adtype_select != $node->adtype)) { |
pierre@1
|
640 $node->adtype = $node->adtype_select; |
pierre@0
|
641 } |
pierre@1
|
642 ad_form_add_adtype_elements($form, $node->adtype, $node); |
pierre@1
|
643 // add ahah wrapper |
pierre@1
|
644 $form['adtype_elements']['#prefix'] = '<div id="adtype-ahah-wrapper">'; |
pierre@1
|
645 $form['adtype_elements']['#suffix'] = '</div>'; |
pierre@1
|
646 } |
pierre@1
|
647 if (!isset($form['adtype_elements'])) { |
pierre@1
|
648 $form['adtype_elements'] = array( |
pierre@1
|
649 '#value' => '<div id="adtype-ahah-wrapper"></div>', |
pierre@1
|
650 '#weight' => 3.1, |
pierre@0
|
651 ); |
pierre@0
|
652 } |
pierre@0
|
653 |
pierre@1
|
654 // fieldset for updating ad status |
pierre@1
|
655 $form['adstatus'] = array( |
pierre@1
|
656 '#type' => 'fieldset', |
pierre@1
|
657 '#title' => t('Status'), |
pierre@1
|
658 '#collapsible' => TRUE, |
pierre@1
|
659 '#weight' => 4, |
pierre@1
|
660 ); |
pierre@1
|
661 $nid = isset($node->nid) ? $node->nid : 0; |
pierre@1
|
662 $adstatus = isset($node->adstatus) ? $node->adstatus : ''; |
pierre@1
|
663 // display all available status options |
pierre@1
|
664 foreach (ad_status_array($nid, $adstatus) as $status => $description) { |
pierre@1
|
665 $form['adstatus']["ad$status"] = array( |
pierre@1
|
666 '#type' => 'radio', |
pierre@1
|
667 '#title' => t("$status"), |
pierre@1
|
668 '#return_value' => $status, |
pierre@1
|
669 '#default_value' => isset($node->adstatus) ? $node->adstatus : 'pending', |
pierre@1
|
670 '#description' => "$description", |
pierre@1
|
671 '#parents' => array("adstatus") |
pierre@0
|
672 ); |
pierre@0
|
673 } |
pierre@0
|
674 |
pierre@0
|
675 // display scheduling options |
pierre@0
|
676 $form['schedule'] = array( |
pierre@0
|
677 '#type' => 'fieldset', |
pierre@0
|
678 '#title' => t('Scheduling'), |
pierre@0
|
679 '#collapsible' => TRUE, |
pierre@0
|
680 // Collapse if there isn't any scheduling data set. |
pierre@0
|
681 '#collapsed' => ( |
pierre@0
|
682 isset($node->autoactivate) || |
pierre@0
|
683 isset($form_state['values']['autoactivate']) || |
pierre@0
|
684 isset($node->autoexpire) || |
pierre@0
|
685 isset($form_state['values']['autoexpire']) || |
pierre@0
|
686 isset($node->maxviews) || |
pierre@0
|
687 isset($form_state['values']['maxviews']) || |
pierre@0
|
688 isset($node->maxclicks) || |
pierre@0
|
689 isset($form_state['values']['maxclicks'])) |
pierre@0
|
690 ? FALSE : TRUE, |
pierre@0
|
691 ); |
pierre@0
|
692 |
pierre@1
|
693 if ((isset($node->nid) && ad_permission($node->nid, 'manage status')) || |
pierre@1
|
694 user_access('administer advertisements')) { |
pierre@0
|
695 $form['schedule']['current'] = array( |
pierre@0
|
696 '#type' => 'markup', |
pierre@0
|
697 '#prefix' => '<div>', |
pierre@0
|
698 '#suffix' => '</div>', |
pierre@0
|
699 '#value' => t('The current date and time is "%date".', array('%date' => format_date(time(), 'custom', 'F j, Y H:i'))) |
pierre@0
|
700 ); |
pierre@0
|
701 $form['schedule']['autoactivate'] = array( |
pierre@0
|
702 '#type' => 'textfield', |
pierre@0
|
703 '#title' => t('Automatically activate ad'), |
pierre@0
|
704 '#required' => FALSE, |
pierre@0
|
705 '#default_value' => isset($node->autoactivate) && $node->autoactivate > 0 ? format_date((int)$node->autoactivate, 'custom', 'F j, Y H:i') : 0, |
pierre@0
|
706 '#description' => t('You can specify a date and time for this advertisement to be automatically activated. The advertisement needs to be in an <em>approved</em> state before it can be automatically activated. If you prefer to activate the advertisement immediately, leave this field empty.') |
pierre@0
|
707 ); |
pierre@0
|
708 } |
pierre@0
|
709 |
pierre@0
|
710 if (user_access('administer advertisements')) { |
pierre@0
|
711 // admins can expire advertisements |
pierre@0
|
712 $form['schedule']['autoexpire'] = array( |
pierre@0
|
713 '#type' => 'textfield', |
pierre@0
|
714 '#title' => t('Automatically expire ad'), |
pierre@0
|
715 '#required' => FALSE, |
pierre@0
|
716 '#default_value' => isset($node->autoexpire) && $node->autoexpire > 0 ? format_date((int)$node->autoexpire, 'custom', 'F j, Y H:i') : 0, |
pierre@0
|
717 '#description' => t('You can specify a date and time for this advertisement to be automatically expired. If you don\'t want the advertisement to expire, leave this field empty.') |
pierre@0
|
718 ); |
pierre@0
|
719 $form['schedule']['maxviews'] = array( |
pierre@0
|
720 '#type' => 'textfield', |
pierre@0
|
721 '#title' => t('Maximum impressions'), |
pierre@0
|
722 '#required' => FALSE, |
pierre@0
|
723 '#size' => 10, |
pierre@0
|
724 '#maxlength' => 11, |
pierre@0
|
725 '#default_value' => isset($node->maxviews) ? $node->maxviews : 0, |
pierre@0
|
726 '#description' => t('You can specify the maximum number of times this advertisement should be displayed, after which it will be automatically expired. If you don\'t want this advertisement to expire after a certain number of impressions, leave this field set to %zero.', array('%zero' => '0')), |
pierre@0
|
727 ); |
pierre@0
|
728 $form['schedule']['maxclicks'] = array( |
pierre@0
|
729 '#type' => 'textfield', |
pierre@0
|
730 '#title' => t('Maximum clicks'), |
pierre@0
|
731 '#required' => FALSE, |
pierre@0
|
732 '#size' => 10, |
pierre@0
|
733 '#maxlength' => 11, |
pierre@0
|
734 '#default_value' => isset($node->maxclicks) ? $node->maxclicks : 0, |
pierre@0
|
735 '#description' => t('You can specify the maximum number of times this advertisement should be clicked, after which it will be automatically expired. If you don\'t want this advertisement to expire after a certain number of clicks leave this field set to %zero.', array('%zero' => '0')), |
pierre@0
|
736 ); |
pierre@0
|
737 } |
pierre@0
|
738 else { |
pierre@0
|
739 // display expiration time |
pierre@0
|
740 $form['schedule']['autoexpire_display'] = array( |
pierre@0
|
741 '#type' => 'markup', |
pierre@0
|
742 '#prefix' => '<div>', |
pierre@0
|
743 '#suffix' => '</div>', |
pierre@0
|
744 '#value' => theme('ad_status_display', $node), |
pierre@0
|
745 ); |
pierre@0
|
746 $form['schedule']['autoexpire'] = array( |
pierre@0
|
747 '#type' => 'hidden', |
pierre@0
|
748 '#value' => isset($node->autoexpire) ? $node->autoexpire : 0, |
pierre@0
|
749 ); |
pierre@0
|
750 } |
pierre@0
|
751 |
pierre@1
|
752 $form['#validate'][] = 'ad_select_adtype'; |
pierre@0
|
753 return $form; |
pierre@0
|
754 } |
pierre@0
|
755 |
pierre@0
|
756 /** |
pierre@1
|
757 * Ad type switch submit handler. |
pierre@1
|
758 */ |
pierre@1
|
759 function ad_select_adtype(&$form, &$form_state) { |
pierre@1
|
760 if (!$form_state['values']['adtype'] && !$form_state['values']['adtype_select']) { |
pierre@1
|
761 form_set_error('adtype_select', t('Please, select an Ad type.')); |
pierre@1
|
762 } |
pierre@1
|
763 if (!isset($form_state['values']['adtype']) || isset($form_state['values']['adtype_select']) && $form_state['values']['adtype'] != $form_state['values']['adtype_select']) { |
pierre@1
|
764 $form_state['values']['adtype'] = $form_state['values']['adtype_select']; |
pierre@1
|
765 $form_state['rebuild'] = TRUE; |
pierre@1
|
766 } |
pierre@1
|
767 } |
pierre@1
|
768 |
pierre@1
|
769 /** |
pierre@1
|
770 * Ad type switch AHAH menu handler. |
pierre@1
|
771 */ |
pierre@1
|
772 function ad_form_ahah() { |
pierre@1
|
773 $form_state = array('storage' => NULL, 'submitted' => FALSE); |
pierre@1
|
774 $form_build_id = $_POST['form_build_id']; |
pierre@1
|
775 $form = form_get_cache($form_build_id, $form_state); |
pierre@1
|
776 ad_form_add_adtype_elements($form, $_POST['adtype_select']); |
pierre@1
|
777 form_set_cache($form_build_id, $form, $form_state); |
pierre@1
|
778 $form += array( |
pierre@1
|
779 '#post' => $_POST, |
pierre@1
|
780 '#programmed' => FALSE, |
pierre@1
|
781 ); |
pierre@1
|
782 // Rebuild the form. |
pierre@1
|
783 $form = form_builder($_POST['form_id'], $form, $form_state); |
pierre@1
|
784 $output = drupal_render($form['adtype_elements']); |
pierre@1
|
785 drupal_json(array( |
pierre@1
|
786 'status' => TRUE, |
pierre@1
|
787 'data' => $output, |
pierre@1
|
788 )); |
pierre@1
|
789 } |
pierre@1
|
790 |
pierre@1
|
791 /** |
pierre@1
|
792 * Loads Ad type elements into form. |
pierre@1
|
793 */ |
pierre@1
|
794 function ad_form_add_adtype_elements(&$form, $adtype, $node = NULL) { |
pierre@1
|
795 unset($form['adtype_elements']); |
pierre@1
|
796 $form['adtype_elements'] = module_invoke('ad_'. $adtype, 'adapi', 'form', $node); |
pierre@1
|
797 $form['adtype'] = array( |
pierre@1
|
798 '#type' => 'hidden', |
pierre@1
|
799 '#value' => $adtype, |
pierre@1
|
800 ); |
pierre@1
|
801 $form['adtype_elements']['#weight'] = 3.1; |
pierre@1
|
802 } |
pierre@1
|
803 |
pierre@1
|
804 /** |
pierre@0
|
805 * Implementation of hook_form_alter(). |
pierre@0
|
806 */ |
pierre@0
|
807 function ad_form_alter(&$form, &$form_state, $form_id) { |
pierre@0
|
808 if ($form_id == 'taxonomy_form_vocabulary') { |
pierre@0
|
809 // Remove taxonomy form options not applicable for ad groups. |
pierre@0
|
810 if ($form['vid']['#value'] == _ad_get_vid()) { |
pierre@0
|
811 $form['help_ad_vocab'] = array( |
pierre@0
|
812 '#value' => t('This vocabulary was automatically created for use by the ad module. Only applicable options are available.'), |
pierre@0
|
813 '#weight' => -1 |
pierre@0
|
814 ); |
pierre@0
|
815 $form['nodes']['ad'] = array( |
pierre@0
|
816 '#type' => 'checkbox', |
pierre@0
|
817 '#title' => t('ad group'), |
pierre@0
|
818 '#value' => 1, |
pierre@0
|
819 '#attributes' => array('disabled' => ''), |
pierre@0
|
820 '#description' => t('Type %type is required to use this vocabulary.', array('%type' => t('ad group'))) |
pierre@0
|
821 ); |
pierre@0
|
822 $form['tags']['#description'] = t('If enabled, ads are categorized by typing ad group names instead of choosing them from a list.'); |
pierre@0
|
823 $form['multiple']['#description'] = t('If enabled, allows ads to have more than one ad group (always true for free tagging).'); |
pierre@0
|
824 $form['required']['#description'] = t('If enabled, every ad <strong>must</strong> be assigned to at least one ad group.'); |
pierre@0
|
825 $form['hierarchy'] = array( |
pierre@0
|
826 '#type' => 'value', |
pierre@0
|
827 '#value' => 0 |
pierre@0
|
828 ); |
pierre@0
|
829 unset($form['relations']); |
pierre@0
|
830 } |
pierre@0
|
831 else { |
pierre@0
|
832 unset($form['nodes']['ad']); |
pierre@0
|
833 } |
pierre@0
|
834 } |
pierre@0
|
835 else if ($form_id == 'taxonomy_form_term') { |
pierre@0
|
836 if ($form['vid']['#value'] == _ad_get_vid()) { |
pierre@0
|
837 $form['name']['#title'] = t('Ad group name'); |
pierre@0
|
838 $form['name']['#description'] = t('The name for this ad group. Example: "Linux".'); |
pierre@0
|
839 $form['description']['#description'] = t('A description of the ad group.'); |
pierre@0
|
840 $form['description']['#required'] = TRUE; |
pierre@0
|
841 $form['weight']['#description'] = t('In listings, the heavier ad groups will sink and the lighter ad groups will be positioned nearer the top.'); |
pierre@0
|
842 unset($form['synonyms']); |
pierre@0
|
843 } |
pierre@0
|
844 } |
pierre@0
|
845 } |
pierre@0
|
846 |
pierre@0
|
847 /** |
pierre@0
|
848 * Implementation of hook_nodeapi(). |
pierre@0
|
849 */ |
pierre@0
|
850 function ad_nodeapi(&$node, $op, $teaser, $page) { |
pierre@0
|
851 global $user; |
pierre@0
|
852 |
pierre@0
|
853 switch ($op) { |
pierre@0
|
854 |
pierre@0
|
855 case 'load': |
pierre@0
|
856 $ad = db_fetch_array(db_query('SELECT * FROM {ads} WHERE aid = %d', $node->nid)); |
pierre@0
|
857 $merge = array_merge((array)$node, (array)$ad); |
pierre@0
|
858 $adtype = module_invoke('ad_'. $ad['adtype'], 'adapi', 'load', $merge); |
pierre@0
|
859 if (is_array($adtype)) { |
pierre@0
|
860 return array_merge($ad, $adtype); |
pierre@0
|
861 } |
pierre@0
|
862 else { |
pierre@0
|
863 return $ad; |
pierre@0
|
864 } |
pierre@0
|
865 break; |
pierre@0
|
866 |
pierre@0
|
867 case 'insert': |
pierre@0
|
868 if (isset($node->adtype)) { |
pierre@0
|
869 if ($node->status != 1 && $node->adstatus == 'active') { |
pierre@1
|
870 $node->adstatus = 'expired'; |
pierre@0
|
871 } |
pierre@0
|
872 $activated = $node->adstatus == 'active' ? time() : 0; |
pierre@1
|
873 if (!isset($node->autoactivate)) { |
pierre@0
|
874 $node->autoactivate = 0; |
pierre@0
|
875 } |
pierre@0
|
876 if (!isset($node->maxviews)) { |
pierre@0
|
877 $node->maxviews = 0; |
pierre@0
|
878 } |
pierre@0
|
879 if (!isset($node->maxclicks)) { |
pierre@0
|
880 $node->maxclicks = 0; |
pierre@0
|
881 } |
pierre@0
|
882 db_query("INSERT INTO {ads} (aid, uid, adstatus, adtype, redirect, autoactivate, autoexpire, activated, maxviews, maxclicks) VALUES(%d, %d, '%s', '%s', '%s', %d, %d, %d, %d, %d)", $node->nid, $node->uid, $node->adstatus, $node->adtype, url('ad/redirect/'. $node->nid, array('absolute' => TRUE)), $node->autoactivate ? strtotime($node->autoactivate) : '', $node->autoexpire ? strtotime($node->autoexpire) : '', $activated, $node->maxviews, $node->maxclicks); |
pierre@0
|
883 ad_statistics_increment($node->nid, 'create'); |
pierre@0
|
884 } |
pierre@0
|
885 break; |
pierre@0
|
886 |
pierre@0
|
887 case 'update': |
pierre@0
|
888 if (isset($node->adtype)) { |
pierre@0
|
889 $ad = db_fetch_object(db_query('SELECT * FROM {ads} WHERE aid = %d', $node->nid)); |
pierre@0
|
890 // Ad must be in approved state to be able to autoactivate it. |
pierre@1
|
891 if ($node->adstatus != 'approved' && isset($node->autoactive) && $node->autoactivate) { |
pierre@0
|
892 if ($node->adstatus == 'active') { |
pierre@0
|
893 // This ad is already active, no need to autoactivate it. |
pierre@0
|
894 $node->autoactivate = 0; |
pierre@0
|
895 } |
pierre@0
|
896 else { |
pierre@0
|
897 drupal_set_message(t('This ad will not be automatically activated at the scheduled time because it is not in the <em>approved</em> state.'), 'error'); |
pierre@0
|
898 } |
pierre@0
|
899 } |
pierre@0
|
900 // If this node has been upublished, the ad should no longer be active. |
pierre@0
|
901 if ($node->status != 1 && $node->adstatus == 'active') { |
pierre@1
|
902 $node->adstatus = 'expired'; |
pierre@0
|
903 } |
pierre@0
|
904 // Check if ad is being manually activated. |
pierre@0
|
905 if ($ad->adstatus != 'active' && $node->adstatus == 'active') { |
pierre@0
|
906 $activated = time(); |
pierre@0
|
907 } |
pierre@0
|
908 // Check if ad is being manually expired. |
pierre@0
|
909 else if ($ad->adstatus != 'expired' && $node->adstatus == 'expired') { |
pierre@0
|
910 // Ad has been manually expired. |
pierre@1
|
911 $activated = $ad->activated; |
pierre@0
|
912 $expired = time(); |
pierre@0
|
913 } |
pierre@0
|
914 // Ad has not been manually activated or expired, preserve timestamps. |
pierre@0
|
915 else { |
pierre@0
|
916 $activated = $ad->activated; |
pierre@0
|
917 $expired = $ad->expired; |
pierre@0
|
918 } |
pierre@0
|
919 // Ad status has changed, record the event. |
pierre@0
|
920 if ($ad->adstatus != $node->adstatus) { |
pierre@0
|
921 ad_statistics_increment($node->nid, $node->adstatus); |
pierre@0
|
922 } |
pierre@0
|
923 // Update ads table with new information. |
pierre@1
|
924 db_query("UPDATE {ads} SET uid = %d, adstatus = '%s', adtype = '%s', redirect = '%s', autoactivate = %d, autoexpire = %d, activated = %d, maxviews = %d, maxclicks = %d, expired = %d WHERE aid = %d", $node->uid, $node->adstatus, $node->adtype, url('ad/redirect/'. $node->nid, array('absolute' => TRUE)), isset($node->autoactivate) && strlen($node->autoactivate) > 1 ? strtotime($node->autoactivate) : '', isset($node->autoexpire) && strlen($node->autoexpire) > 1 ? strtotime($node->autoexpire) : '', isset($activated) ? $activated : 0, isset($node->maxviews) ? (int)$node->maxviews : 0, isset($node->maxclicks) ? (int)$node->maxclicks : 0, isset($expired) ? $expired : 0, $node->nid); |
pierre@0
|
925 ad_statistics_increment($node->nid, 'update'); |
pierre@0
|
926 } |
pierre@0
|
927 break; |
pierre@0
|
928 |
pierre@0
|
929 case 'delete': |
pierre@0
|
930 db_query("DELETE FROM {ads} WHERE aid = %d", $node->nid); |
pierre@0
|
931 db_query("DELETE FROM {ad_statistics} WHERE aid = %d", $node->nid); |
pierre@0
|
932 // All that's left of the ad is a single timestamp as to when it was |
pierre@0
|
933 // deleted. |
pierre@0
|
934 ad_statistics_increment($node->nid, 'delete'); |
pierre@0
|
935 break; |
pierre@0
|
936 |
pierre@0
|
937 case 'view': |
pierre@0
|
938 if (isset($node->adtype)) { |
pierre@0
|
939 $node = node_prepare($node, $teaser); |
pierre@0
|
940 $node->content['body'] = array( |
pierre@0
|
941 '#value' => $teaser ? $node->teaser : theme('node_ad', $node, $page), |
pierre@0
|
942 '#weight' => 1, |
pierre@0
|
943 ); |
pierre@0
|
944 } |
pierre@0
|
945 break; |
pierre@0
|
946 } |
pierre@0
|
947 // Allow ad type module to act on nodeapi events. The adapi hook provides |
pierre@0
|
948 // access to additional variables not available in the nodeapi hook. |
pierre@0
|
949 if (isset($node->adtype)) { |
pierre@0
|
950 // Don't use module_invoke, as in pre-PHP5 the changes to $node won't be |
pierre@0
|
951 // passed back. |
pierre@0
|
952 $function = "ad_$node->adtype" .'_adapi'; |
pierre@0
|
953 if (function_exists($function)) { |
pierre@0
|
954 $function($op, $node); |
pierre@0
|
955 } |
pierre@0
|
956 } |
pierre@0
|
957 // Allow ad cache module to act on nodeapi events. |
pierre@0
|
958 $cache = variable_get('ad_cache', 'none'); |
pierre@0
|
959 if ($cache != 'none') { |
pierre@0
|
960 $function = "ad_cache_$cache" .'_adcacheapi'; |
pierre@0
|
961 if (function_exists($function)) { |
pierre@0
|
962 $function($op, $node); |
pierre@0
|
963 } |
pierre@0
|
964 } |
pierre@1
|
965 |
pierre@1
|
966 // Rebuild the cache after all hooks are invoked. |
pierre@1
|
967 switch ($op) { |
pierre@1
|
968 case 'insert': |
pierre@1
|
969 case 'update': |
pierre@1
|
970 case 'delete': |
pierre@1
|
971 if (variable_get('ad_cache_file_rebuild_realtime', 0) && |
pierre@1
|
972 isset($node->adtype)) { |
pierre@1
|
973 ad_rebuild_cache(); |
pierre@1
|
974 } |
pierre@1
|
975 } |
pierre@0
|
976 } |
pierre@0
|
977 |
pierre@0
|
978 function ad_adapi($op, $node = NULL) { |
pierre@0
|
979 switch ($op) { |
pierre@0
|
980 case 'permissions': |
pierre@1
|
981 return array( |
pierre@1
|
982 'access statistics' => TRUE, |
pierre@1
|
983 'access click history' => TRUE, |
pierre@1
|
984 'set status as pending' => FALSE, |
pierre@1
|
985 'set status as denied' => FALSE, |
pierre@1
|
986 'set status from pending to approved' => FALSE, |
pierre@1
|
987 'set status from pending to denied' => FALSE, |
pierre@1
|
988 'set status from approved to active' => TRUE, |
pierre@1
|
989 'set status from approved to offline' => TRUE, |
pierre@1
|
990 'set status from active to offline' => TRUE, |
pierre@1
|
991 'set status from active to expired' => FALSE, |
pierre@1
|
992 'set status from offline to active' => TRUE, |
pierre@1
|
993 'set status from offline to expired' => FALSE, |
pierre@1
|
994 ); |
pierre@0
|
995 break; |
pierre@0
|
996 } |
pierre@0
|
997 } |
pierre@0
|
998 |
pierre@0
|
999 /** |
pierre@0
|
1000 * Implementation of hook_menu(). |
pierre@0
|
1001 */ |
pierre@0
|
1002 function ad_menu() { |
pierre@0
|
1003 $items = array(); |
pierre@0
|
1004 |
pierre@0
|
1005 $items['admin/content/ad'] = array( |
pierre@0
|
1006 'title' => 'Ads', |
pierre@0
|
1007 'page callback' => 'ad_admin_list', |
pierre@0
|
1008 'access arguments' => array('administer advertisements'), |
pierre@0
|
1009 'description' => 'Configure and manage your advertising system.', |
pierre@0
|
1010 'file' => 'ad.admin.inc', |
pierre@0
|
1011 ); |
pierre@0
|
1012 $items['admin/content/ad/list'] = array( |
pierre@0
|
1013 'title' => 'List', |
pierre@0
|
1014 'page callback' => 'ad_admin_list', |
pierre@0
|
1015 'access arguments' => array('administer advertisements'), |
pierre@0
|
1016 'type' => MENU_DEFAULT_LOCAL_TASK, |
pierre@0
|
1017 'file' => 'ad.admin.inc', |
pierre@0
|
1018 ); |
pierre@0
|
1019 $items['admin/content/ad/configure'] = array( |
pierre@0
|
1020 'title' => 'Settings', |
pierre@0
|
1021 'page callback' => 'drupal_get_form', |
pierre@0
|
1022 'page arguments' => array('ad_admin_configure_settings'), |
pierre@0
|
1023 'access arguments' => array('administer advertisements'), |
pierre@0
|
1024 'type' => MENU_LOCAL_TASK, |
pierre@0
|
1025 'weight' => 3, |
pierre@0
|
1026 'file' => 'ad.admin.inc', |
pierre@0
|
1027 ); |
pierre@1
|
1028 $items['node/add/ad/ahah'] = array( |
pierre@1
|
1029 'access arguments' => array('create advertisements'), |
pierre@1
|
1030 'page callback' => 'ad_form_ahah', |
pierre@1
|
1031 'type' => MENU_CALLBACK, |
pierre@1
|
1032 ); |
pierre@0
|
1033 |
pierre@0
|
1034 ad_menu_add_global_settings($items); |
pierre@0
|
1035 |
pierre@0
|
1036 $items['admin/content/ad/groups'] = array( |
pierre@0
|
1037 'title' => 'Ad groups', |
pierre@0
|
1038 'page callback' => 'ad_admin_groups_list', |
pierre@0
|
1039 'access arguments' => array('administer advertisements'), |
pierre@0
|
1040 'type' => MENU_LOCAL_TASK, |
pierre@0
|
1041 'weight' => 5, |
pierre@0
|
1042 'file' => 'ad.admin.inc', |
pierre@0
|
1043 ); |
pierre@0
|
1044 $items['admin/content/ad/groups/list'] = array( |
pierre@0
|
1045 'title' => 'List', |
pierre@0
|
1046 'page callback' => 'ad_admin_groups_list', |
pierre@0
|
1047 'access arguments' => array('administer advertisements'), |
pierre@0
|
1048 'type' => MENU_DEFAULT_LOCAL_TASK, |
pierre@0
|
1049 'weight' => 0, |
pierre@0
|
1050 'file' => 'ad.admin.inc', |
pierre@0
|
1051 ); |
pierre@0
|
1052 $items['admin/content/ad/groups/add'] = array( |
pierre@0
|
1053 'title' => 'Create group', |
pierre@0
|
1054 'page callback' => 'drupal_get_form', |
pierre@0
|
1055 'page arguments' => array('ad_admin_group_form'), |
pierre@0
|
1056 'access arguments' => array('administer advertisements'), |
pierre@0
|
1057 'type' => MENU_LOCAL_TASK, |
pierre@0
|
1058 'weight' => 3, |
pierre@0
|
1059 'file' => 'ad.admin.inc', |
pierre@0
|
1060 ); |
pierre@0
|
1061 $items["admin/content/ad/groups/%ad_group/edit"] = array( |
pierre@0
|
1062 'title' => 'Edit group', |
pierre@0
|
1063 'page callback' => 'drupal_get_form', |
pierre@0
|
1064 'page arguments' => array('ad_admin_group_form', 4), |
pierre@0
|
1065 'access arguments' => array('administer advertisements'), |
pierre@0
|
1066 'weight' => 1, |
pierre@0
|
1067 'file' => 'ad.admin.inc', |
pierre@0
|
1068 ); |
pierre@0
|
1069 $items["admin/content/ad/groups/%ad_group/delete"] = array( |
pierre@0
|
1070 'title' => 'Delete group', |
pierre@0
|
1071 'page callback' => 'drupal_get_form', |
pierre@0
|
1072 'page arguments' => array('ad_confirm_group_delete', 4), |
pierre@0
|
1073 'access arguments' => array('administer advertisements'), |
pierre@0
|
1074 'weight' => 2, |
pierre@0
|
1075 'file' => 'ad.admin.inc', |
pierre@0
|
1076 ); |
pierre@0
|
1077 $items['admin/content/ad/configure/global'] = array( |
pierre@0
|
1078 'title' => 'Global settings', |
pierre@0
|
1079 'page callback' => 'drupal_get_form', |
pierre@0
|
1080 'page arguments' => array('ad_admin_configure_settings'), |
pierre@0
|
1081 'access arguments' => array('administer advertisements'), |
pierre@0
|
1082 'type' => MENU_DEFAULT_LOCAL_TASK, |
pierre@0
|
1083 'weight' => 0, |
pierre@0
|
1084 'file' => 'ad.admin.inc', |
pierre@0
|
1085 ); |
pierre@0
|
1086 $items["node/%node/details/%"] = array( |
pierre@0
|
1087 'title' => 'Click details', |
pierre@0
|
1088 'page callback' => 'ad_click_details', |
pierre@0
|
1089 'page arguments' => array(1, 3), |
pierre@0
|
1090 'access arguments' => array(1, 'access click history'), |
pierre@1
|
1091 'access callback' => 'ad_permission', |
pierre@0
|
1092 'type' => MENU_CALLBACK, |
pierre@0
|
1093 'file' => 'ad.pages.inc', |
pierre@0
|
1094 ); |
pierre@1
|
1095 $items["ad/redirect/%"] = array( |
pierre@0
|
1096 'access arguments' => array('show advertisements'), |
pierre@0
|
1097 'type' => MENU_CALLBACK, |
pierre@0
|
1098 'page callback' => 'ad_redirect', |
pierre@1
|
1099 'page arguments' => (array(2)), |
pierre@0
|
1100 ); |
pierre@0
|
1101 |
pierre@0
|
1102 return $items; |
pierre@0
|
1103 } |
pierre@0
|
1104 |
pierre@0
|
1105 /** |
pierre@0
|
1106 * Load settings for all ad modules. Those modules, who don't |
pierre@0
|
1107 * have their settings form, will get a standard one. |
pierre@0
|
1108 */ |
pierre@0
|
1109 function ad_menu_add_global_settings(&$menu_items) { |
pierre@0
|
1110 $adtypes = ad_get_types(); |
pierre@0
|
1111 foreach ($adtypes as $type => $name) { |
pierre@0
|
1112 // Ad type global settings. |
pierre@0
|
1113 $settings = 'ad_'. $type .'_global_settings'; |
pierre@1
|
1114 $file = 'ad_image.module'; |
pierre@0
|
1115 if (!function_exists($settings)) { |
pierre@0
|
1116 $settings = 'ad_no_global_settings'; |
pierre@1
|
1117 $file = 'ad.admin.inc'; |
pierre@0
|
1118 } |
pierre@0
|
1119 $menu_items['admin/content/ad/configure/'. $type] = array( |
pierre@0
|
1120 'title' => $name, |
pierre@0
|
1121 'page callback' => 'drupal_get_form', |
pierre@0
|
1122 'page arguments' => array($settings), |
pierre@0
|
1123 'access arguments' => array('administer advertisements'), |
pierre@0
|
1124 'type' => MENU_LOCAL_TASK, |
pierre@0
|
1125 'weight' => 2, |
pierre@0
|
1126 'file' => 'ad.admin.inc', |
pierre@0
|
1127 ); |
pierre@0
|
1128 } |
pierre@0
|
1129 } |
pierre@0
|
1130 |
pierre@0
|
1131 /** |
pierre@0
|
1132 * Drupal menu wildcard Ad group loader |
pierre@0
|
1133 */ |
pierre@0
|
1134 function ad_group_load($tid) { |
pierre@0
|
1135 if (!is_numeric($tid)) { |
pierre@0
|
1136 return FALSE; |
pierre@0
|
1137 } |
pierre@0
|
1138 $group = ad_groups_list(TRUE, $tid); |
pierre@0
|
1139 if (!isset($group)) { |
pierre@0
|
1140 return FALSE; |
pierre@0
|
1141 } |
pierre@0
|
1142 return $group; |
pierre@0
|
1143 } |
pierre@0
|
1144 |
pierre@0
|
1145 /** |
pierre@0
|
1146 * Implementation of hook_block(). |
pierre@0
|
1147 */ |
pierre@0
|
1148 function ad_block($op = 'list', $delta = 0, $edit = array()) { |
pierre@0
|
1149 switch ($op) { |
pierre@0
|
1150 case 'list': |
pierre@0
|
1151 $blocks = array(); |
pierre@0
|
1152 $groups = ad_groups_list(); |
pierre@0
|
1153 foreach ($groups as $tid => $name) { |
pierre@0
|
1154 $blocks[$tid]['info'] = t('ad group: @name', array('@name' => $name)); |
pierre@0
|
1155 } |
pierre@0
|
1156 return $blocks; |
pierre@0
|
1157 case 'configure': |
pierre@0
|
1158 $form['ad_block_quantity_'. $delta] = array( |
pierre@0
|
1159 '#type' => 'select', |
pierre@0
|
1160 '#title' => t('Number of ads'), |
pierre@0
|
1161 '#default_value' => variable_get('ad_block_quantity_'. $delta, 1), |
pierre@0
|
1162 '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)), |
pierre@0
|
1163 '#description' => t('Select the maximum number of unique ads that should be displayed together in this block. If you specify a number larger than the maximum number of ads in this ad group, all ads will be displayed once.'), |
pierre@0
|
1164 ); |
pierre@0
|
1165 return $form; |
pierre@0
|
1166 case 'save': |
pierre@0
|
1167 variable_set('ad_block_quantity_'. $delta, $edit['ad_block_quantity_'. $delta]); |
pierre@0
|
1168 break; |
pierre@0
|
1169 case 'view': |
pierre@0
|
1170 $groups = ad_groups_list(); |
pierre@0
|
1171 $block['content'] = ad($delta, variable_get('ad_block_quantity_'. $delta, 1)); |
pierre@0
|
1172 return $block; |
pierre@0
|
1173 } |
pierre@0
|
1174 } |
pierre@0
|
1175 |
pierre@0
|
1176 /** |
pierre@0
|
1177 * Determine whether the user has a given privilege. |
pierre@0
|
1178 * |
pierre@1
|
1179 * @param $aid |
pierre@1
|
1180 * ID of advertisement. |
pierre@0
|
1181 * @param $permission |
pierre@1
|
1182 * Permission string which should be checked (such as 'access click history') |
pierre@0
|
1183 * @param $account |
pierre@0
|
1184 * User object, which are accessing the ad or current user by default. |
pierre@0
|
1185 */ |
pierre@1
|
1186 function ad_permission($aid, $string, $account = NULL) { |
pierre@0
|
1187 global $user; |
pierre@1
|
1188 $access = FALSE; |
pierre@0
|
1189 |
pierre@1
|
1190 // by default, check permission for current user |
pierre@0
|
1191 if (!isset($account)) { |
pierre@0
|
1192 $account = $user; |
pierre@0
|
1193 } |
pierre@0
|
1194 |
pierre@1
|
1195 // user #1 has all privileges |
pierre@0
|
1196 if ($account->uid == 1) { |
pierre@0
|
1197 return TRUE; |
pierre@0
|
1198 } |
pierre@0
|
1199 |
pierre@1
|
1200 // if you have administer permissions, you have all permissions |
pierre@0
|
1201 if (user_access('administer advertisements', $account)) { |
pierre@0
|
1202 return TRUE; |
pierre@0
|
1203 } |
pierre@0
|
1204 |
pierre@1
|
1205 // when used in the Drupal menu, $aid may be the full ad object. |
pierre@1
|
1206 if (is_object($aid) && isset($aid->aid)) { |
pierre@1
|
1207 $aid = $aid->aid; |
pierre@1
|
1208 } |
pierre@1
|
1209 else if (is_object($aid)) { |
pierre@1
|
1210 watchdog('ad', 'Invalid aid object passed into ad_permission, no aid->aid set.'); |
pierre@1
|
1211 $aid = 0; |
pierre@0
|
1212 } |
pierre@0
|
1213 |
pierre@1
|
1214 // invoke ad_owners module to determine user's access |
pierre@1
|
1215 if (module_exists('ad_owners') && |
pierre@1
|
1216 function_exists('ad_owners_permission')) { |
pierre@1
|
1217 $access = ad_owners_permission($aid, $string, $account); |
pierre@1
|
1218 } |
pierre@1
|
1219 // no ad_owners module, allow acces to statistics and click history |
pierre@1
|
1220 else if (in_array($string, array('access statistics', 'access click history'))) { |
pierre@1
|
1221 $access = TRUE; |
pierre@1
|
1222 } |
pierre@1
|
1223 // with no ad_owners module, all other permissions are denied unless user |
pierre@1
|
1224 // has 'administer advertisements' permission |
pierre@1
|
1225 return $access; |
pierre@0
|
1226 } |
pierre@0
|
1227 |
pierre@0
|
1228 /** |
pierre@0
|
1229 * Returns ad types data. |
pierre@0
|
1230 * |
pierre@0
|
1231 * @param $op |
pierre@0
|
1232 * If set to 'name', will only return array of type names ($type => $name). |
pierre@0
|
1233 * If set to 'data', will return all of the type's data |
pierre@0
|
1234 * @param $type |
pierre@0
|
1235 * If not specified, will return array of all available types, else will |
pierre@0
|
1236 * return specific type's name or data. |
pierre@0
|
1237 */ |
pierre@0
|
1238 function ad_get_types($op = 'name', $type = NULL) { |
pierre@0
|
1239 $adtypes = module_invoke_all('adapi', 'type', array()); |
pierre@0
|
1240 switch ($op) { |
pierre@0
|
1241 case 'name': |
pierre@0
|
1242 if (isset($type)) { |
pierre@0
|
1243 return $adtypes[$type]['name']; |
pierre@0
|
1244 } |
pierre@0
|
1245 else { |
pierre@0
|
1246 foreach ($adtypes as $type => $data) { |
pierre@0
|
1247 $adtypes[$type] = $data['name']; |
pierre@0
|
1248 } |
pierre@0
|
1249 return $adtypes; |
pierre@0
|
1250 } |
pierre@0
|
1251 case 'data': |
pierre@0
|
1252 if (isset($type)) { |
pierre@0
|
1253 return $adtypes[$type]; |
pierre@0
|
1254 } |
pierre@0
|
1255 else { |
pierre@0
|
1256 return $adtypes; |
pierre@0
|
1257 } |
pierre@0
|
1258 } |
pierre@0
|
1259 } |
pierre@0
|
1260 |
pierre@0
|
1261 /** |
pierre@0
|
1262 * Return an array of all groups, or a specific group. |
pierre@0
|
1263 * |
pierre@0
|
1264 * @param $object |
pierre@0
|
1265 * If FALSE, will return only name of group(s). If TRUE, will return full |
pierre@0
|
1266 * group object including ->name, ->description, and ->tid. |
pierre@0
|
1267 * @param $tid |
pierre@0
|
1268 * If set to an integer >0, will only return group info about that specific |
pierre@0
|
1269 * group. |
pierre@0
|
1270 */ |
pierre@0
|
1271 function ad_groups_list($object = FALSE, $tid = NULL) { |
pierre@0
|
1272 static $groups = array(); |
pierre@0
|
1273 static $names = array(); |
pierre@0
|
1274 |
pierre@0
|
1275 // Return the full group object(s). |
pierre@0
|
1276 if ($object) { |
pierre@0
|
1277 if (empty($groups)) { |
pierre@0
|
1278 $tids = taxonomy_get_tree(_ad_get_vid()); |
pierre@0
|
1279 if (is_array($tids)) { |
pierre@0
|
1280 foreach ($tids as $group) { |
pierre@0
|
1281 $groups[$group->tid]->name = $group->name; |
pierre@0
|
1282 $groups[$group->tid]->description = $group->description; |
pierre@0
|
1283 $groups[$group->tid]->tid = $group->tid; |
pierre@0
|
1284 $groups[$group->tid]->weight = $group->weight; |
pierre@0
|
1285 } |
pierre@0
|
1286 } |
pierre@0
|
1287 // Hard coded "default" group with tid of 0. |
pierre@0
|
1288 $groups[0]->name = t('default'); |
pierre@0
|
1289 $groups[0]->description = t('The default ad group is comprised of all ads not assigned to any other ad group.'); |
pierre@0
|
1290 $groups[0]->tid = 0; |
pierre@0
|
1291 $groups[0]->weight = 0; |
pierre@0
|
1292 } |
pierre@0
|
1293 // Return a specific group object. |
pierre@0
|
1294 if ((int)$tid) { |
pierre@0
|
1295 return $groups[$tid]; |
pierre@0
|
1296 } |
pierre@0
|
1297 // Return an array of all group objects. |
pierre@0
|
1298 else { |
pierre@0
|
1299 return $groups; |
pierre@0
|
1300 } |
pierre@0
|
1301 } |
pierre@0
|
1302 // Return only the group name(s). |
pierre@0
|
1303 else { |
pierre@0
|
1304 if (empty($names)) { |
pierre@0
|
1305 $tids = taxonomy_get_tree(_ad_get_vid()); |
pierre@0
|
1306 if (is_array($tids)) { |
pierre@0
|
1307 foreach ($tids as $group) { |
pierre@0
|
1308 $names[$group->tid] = $group->name; |
pierre@0
|
1309 } |
pierre@0
|
1310 } |
pierre@0
|
1311 // Hard coded "default" group with tid of 0. |
pierre@0
|
1312 $names[0] = t('default'); |
pierre@0
|
1313 } |
pierre@0
|
1314 // Return a specific group name. |
pierre@0
|
1315 if ((int)$tid) { |
pierre@0
|
1316 return $names[$tid]; |
pierre@0
|
1317 } |
pierre@0
|
1318 // Return an array of all group names. |
pierre@0
|
1319 else { |
pierre@0
|
1320 return $names; |
pierre@0
|
1321 } |
pierre@0
|
1322 } |
pierre@0
|
1323 } |
pierre@0
|
1324 |
pierre@0
|
1325 /** |
pierre@0
|
1326 * Implement ad notify api _hook. |
pierre@0
|
1327 */ |
pierre@0
|
1328 function ad_adnotifyapi($op, $arg1 = NULL, $arg2 = NULL) { |
pierre@0
|
1329 switch ($op) { |
pierre@0
|
1330 // Make the following events available for notification. |
pierre@0
|
1331 case 'register': |
pierre@0
|
1332 return array( |
pierre@0
|
1333 '-expired' => t('Email @when before the advertisement will expire.'), |
pierre@0
|
1334 'expired' => t('Email @when after the advertisement is expired.'), |
pierre@0
|
1335 '-active' => t('Email @when before the advertisement will be activated (if scheduled).'), |
pierre@0
|
1336 'active' => t('Email @when after the advertisement is activated.'), |
pierre@0
|
1337 'click' => t('Email @when after the advertisement is clicked.'), |
pierre@0
|
1338 'approved' => t('Email @when after the advertisement is approved.'), |
pierre@0
|
1339 'denied' => t('Email @when after the advertisement is denied.'), |
pierre@0
|
1340 ); |
pierre@0
|
1341 break; |
pierre@0
|
1342 case '-expired': |
pierre@0
|
1343 $node = node_load($arg1->aid); |
pierre@0
|
1344 if (isset($node->autoexpire) && $node->autoexpire) { |
pierre@0
|
1345 if ((time() + $arg1->delay >= $node->autoexpire) && |
pierre@0
|
1346 ($arg1->sent + $arg1->delay < $node->autoexpire)) { |
pierre@0
|
1347 return array('-expired' => 1); |
pierre@0
|
1348 } |
pierre@0
|
1349 } |
pierre@0
|
1350 break; |
pierre@0
|
1351 case '-active': |
pierre@0
|
1352 $node = node_load($arg1->aid); |
pierre@0
|
1353 if (isset($node->autoactivate) && $node->autoactivate) { |
pierre@0
|
1354 if ((time() + $arg1->delay >= $node->autoactivate) && |
pierre@0
|
1355 ($arg1->sent + $arg1->delay < $node->autoactivate)) { |
pierre@0
|
1356 return array('-active' => 1); |
pierre@0
|
1357 } |
pierre@0
|
1358 } |
pierre@0
|
1359 break; |
pierre@0
|
1360 case 'mail_text': |
pierre@0
|
1361 switch ($arg1) { |
pierre@0
|
1362 case 'expired': |
pierre@0
|
1363 return array( |
pierre@1
|
1364 'subject' => t('[%site-name ad] %event notification'), |
pierre@1
|
1365 'body' => t("Hello %owner_name,\n\n This is an automatically generated notification to inform you that your advertisement \"%title\" that was being displayed on the %site-name website has expired.\n\n Your advertisement was viewed %global_impressions times and clicked %global_clicks times since it was activated on %activated_large.\n\n You can view additional statistics about this advertisement or update this notification at the following url:\n %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"), |
pierre@0
|
1366 ); |
pierre@0
|
1367 case '-expired': |
pierre@0
|
1368 return array( |
pierre@1
|
1369 'subject' => t('[%site-name ad] expiration notification'), |
pierre@1
|
1370 'body' => t("Hello %owner_name,\n\n This is an automatically generated notification to inform you that your advertisement \"%title\" that is being displayed on the %site-name website will expire on %autoexpire_large.\n\n Your advertisement has been viewed %today_impressions times and clicked %today_clicks times today. It was viewed %yesterday_impressions times and clicked %yesterday_clicks times yesterday. It has been viewed %global_impressions times and clicked %global_clicks times since it was activated on %activated_large.\n\n You can view additional statistics about this advertisement or update this notification at the following url:\n %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"), |
pierre@0
|
1371 ); |
pierre@0
|
1372 case 'active': |
pierre@0
|
1373 return array( |
pierre@1
|
1374 'subject' => t('[%site-name ad] %event notification'), |
pierre@1
|
1375 'body' => t("Hello %owner_name,\n\n This is an automatically generated notification to inform you that your advertisement \"%title\" is now actively being displayed on the %site-name website.\n\n Your advertisement has been viewed %global_impressions times and clicked %global_clicks times since it was activated on %activated_large.\n\n You can view additional statistics about this advertisement or update this notification at the following url:\n %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"), |
pierre@0
|
1376 ); |
pierre@0
|
1377 case '-active': |
pierre@0
|
1378 return array( |
pierre@1
|
1379 'subject' => t('[%site-name ad] activation notification'), |
pierre@1
|
1380 'body' => t("Hello %owner_name,\n\n This is an automatically generated notification to inform you that your advertisement \"%title\" will be actively displayed on the %site-name website on %autoactivate_large.\n\n You can view statistics about this advertisement or update this notification at the following url:\n %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"), |
pierre@0
|
1381 ); |
pierre@0
|
1382 case 'click': |
pierre@0
|
1383 return array( |
pierre@1
|
1384 'subject' => t('[%site-name ad] %event notification'), |
pierre@1
|
1385 'body' => t("Hello %owner_name,\n\n This is an automatically generated notification to inform you that your advertisement \"%title\" on the %site-name website has been clicked.\n\n Your advertisement has been viewed %today_impressions times and clicked %today_clicks times today. It was viewed %yesterday_impressions times and clicked %yesterday_clicks times yesterday. It has been viewed %global_impressions times and clicked %global_clicks times since it was activated on %activated_large.\n\n You will receive this %frequency You can view additional statistics about this advertisement or update this notification at the following url:\n %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"), |
pierre@0
|
1386 ); |
pierre@0
|
1387 case 'approved': |
pierre@0
|
1388 return array( |
pierre@1
|
1389 'subject' => t('[%site-name ad] %event notification'), |
pierre@1
|
1390 'body' => t("Hello %owner_name,\n\n This is an automatically generated notification to inform you that your advertisement \"%title\" on the %site-name website has been approved.\n\n You can view statistics about this advertisement at the following url:\n %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"), |
pierre@0
|
1391 ); |
pierre@0
|
1392 case 'denied': |
pierre@0
|
1393 return array( |
pierre@1
|
1394 'subject' => t('[%site-name ad] %event notification'), |
pierre@1
|
1395 'body' => t("Hello %owner_name,\n\n This is an automatically generated notification to inform you that your advertisement \"%title\" on the %site-name website has been denied and will not be displayed.\n\n You can view statistics about this advertisement at the following url:\n %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"), |
pierre@0
|
1396 ); |
pierre@0
|
1397 } |
pierre@0
|
1398 break; |
pierre@0
|
1399 } |
pierre@0
|
1400 } |
pierre@0
|
1401 |
pierre@0
|
1402 function _ad_check_installation() { |
pierre@0
|
1403 // Verify serve.php exists and is readable. |
pierre@0
|
1404 $adserve = variable_get('adserve', ''); |
pierre@0
|
1405 $adserveinc = variable_get('adserveinc', ''); |
pierre@0
|
1406 if (!file_exists($adserve)) { |
pierre@0
|
1407 // The serve.php file should be in the same directory as the ad.module. |
pierre@0
|
1408 $adserve = drupal_get_path('module', 'ad') .'/serve.php'; |
pierre@0
|
1409 variable_set('adserve', $adserve); |
pierre@0
|
1410 } |
pierre@0
|
1411 if (!is_readable($adserve)) { |
pierre@0
|
1412 variable_set('adserve', ''); |
pierre@0
|
1413 drupal_set_message(t('Failed to read the required file %filename. Please make the file readable by the webserver process. No ads can be displayed until this problem is resolved.', array('%filename' => $adserve)), 'error'); |
pierre@0
|
1414 } |
pierre@0
|
1415 if (!file_exists($adserveinc)) { |
pierre@0
|
1416 // The adserve.inc file should be in the same directory as the ad.module. |
pierre@0
|
1417 $adserveinc = drupal_get_path('module', 'ad') .'/adserve.inc'; |
pierre@0
|
1418 variable_set('adserveinc', $adserveinc); |
pierre@0
|
1419 } |
pierre@0
|
1420 if (!is_readable($adserveinc)) { |
pierre@0
|
1421 variable_set('adserveinc', ''); |
pierre@0
|
1422 drupal_set_message(t('Failed to read the required file %filename. Please make the file readable by the webserver process. No ads can be displayed until this problem is resolved.', array('%filename' => $adserveinc)), 'error'); |
pierre@0
|
1423 } |
pierre@0
|
1424 |
pierre@0
|
1425 // Validate vid in vocabulary table. |
pierre@0
|
1426 $vid = db_result(db_query("SELECT vid FROM {vocabulary} WHERE module = 'ad'")); |
pierre@0
|
1427 if ($vid != variable_get('ad_group_vid', '')) { |
pierre@0
|
1428 drupal_set_message(t('Invalid vocabulary defined for advertisements, attempting to auto-fix.'), 'error'); |
pierre@0
|
1429 if ($vid) { |
pierre@0
|
1430 db_query("DELETE FROM {vocabulary_node_types} WHERE vid = %d OR type = 'ad'", variable_get('ad_group_vid', '')); |
pierre@0
|
1431 variable_set('ad_group_vid_restore', variable_get('ad_group_vid', '')); |
pierre@0
|
1432 } |
pierre@0
|
1433 variable_del('ad_group_vid'); |
pierre@0
|
1434 } |
pierre@0
|
1435 else { |
pierre@0
|
1436 // Validate vid in vocabulary_node_types table. |
pierre@0
|
1437 $result = db_query("SELECT vid FROM {vocabulary_node_types} WHERE type = 'ad'"); |
pierre@0
|
1438 $found = FALSE; |
pierre@0
|
1439 while ($vocab = db_fetch_object($result)) { |
pierre@0
|
1440 if ($vocab->vid == variable_get('ad_group_vid', '')) { |
pierre@0
|
1441 $found = TRUE; |
pierre@0
|
1442 } |
pierre@0
|
1443 } |
pierre@0
|
1444 if (!$found) { |
pierre@0
|
1445 drupal_set_message(t('Missing vocabulary node type for advertisements, attempting to auto-fix.'), 'error'); |
pierre@0
|
1446 db_query("DELETE FROM {vocabulary_node_types} WHERE vid = %d OR type = 'ad'", variable_get('ad_group_vid', '')); |
pierre@0
|
1447 db_query("DELETE FROM {vocabulary} WHERE vid = %d", variable_get('ad_group_vid', '')); |
pierre@0
|
1448 variable_set('ad_group_vid_restore', variable_get('ad_group_vid', '')); |
pierre@0
|
1449 variable_del('ad_group_vid'); |
pierre@0
|
1450 } |
pierre@0
|
1451 } |
pierre@0
|
1452 |
pierre@0
|
1453 _ad_get_vid(); |
pierre@0
|
1454 // Preserve old ad groups, if any. |
pierre@0
|
1455 if (($old = variable_get('ad_group_vid_restore', '')) && |
pierre@0
|
1456 $vid = variable_get('ad_group_vid', '')) { |
pierre@0
|
1457 drupal_set_message(t('Restoring orphaned ad group configuration.')); |
pierre@0
|
1458 db_query('UPDATE {term_data} SET vid = %d WHERE vid = %d', $vid, $old); |
pierre@0
|
1459 variable_set('ad_group_vid_restore', ''); |
pierre@0
|
1460 } |
pierre@0
|
1461 |
pierre@0
|
1462 $rid = db_result(db_query_range("SELECT rid FROM {permission} WHERE perm LIKE '%%show advertisements%%'", 1)); |
pierre@0
|
1463 if (!$rid) { |
pierre@0
|
1464 drupal_set_message(t('Be sure to enable "!show" permissions for all roles that you wish to see advertisements.', array('!show' => l(t('show advertisements'), 'admin/user/permissions')))); |
pierre@0
|
1465 } |
pierre@0
|
1466 |
pierre@0
|
1467 // Allow modules to define an action to take each time an ad is served. |
pierre@0
|
1468 // When modules define 'adserve_select' or 'adserve_filter', they must set |
pierre@0
|
1469 // the 'function' and 'path' parameters. The 'weight' parameter can |
pierre@0
|
1470 // optionally be set. |
pierre@0
|
1471 // function: the function to call when serving an add |
pierre@0
|
1472 // path: the path to the include file where $function is defined |
pierre@0
|
1473 // Modules can define actions that happen when advertisements are served. |
pierre@0
|
1474 // Currently support actions are: |
pierre@0
|
1475 // - init_text (display content before displaying ads) // TODO |
pierre@0
|
1476 // - select (alter which ads are selected to be displayed) // TODO |
pierre@0
|
1477 // - filter (filter selected ads before they are displayed) // TODO |
pierre@0
|
1478 // - exit_text (display content after displaying ads) // TODO |
pierre@0
|
1479 $hooks = array('init_text', 'select', 'filter', 'exit_text'); |
pierre@0
|
1480 foreach ($hooks as $hook) { |
pierre@0
|
1481 $adserve_actions = module_invoke_all('adapi', "adserve_$hook", array()); |
pierre@0
|
1482 $actions = array(); |
pierre@0
|
1483 foreach ($adserve_actions as $name => $action) { |
pierre@0
|
1484 if (is_numeric($action['weight'])) { |
pierre@0
|
1485 $weight = $action['weight']; |
pierre@0
|
1486 } |
pierre@0
|
1487 else { |
pierre@0
|
1488 // weight is an optional, defaults to 0 |
pierre@0
|
1489 $weight = $action['weight'] = 0; |
pierre@0
|
1490 } |
pierre@0
|
1491 $actions[$weight .'.'. $name] = $action; |
pierre@0
|
1492 $actions[$weight .'.'. $name]['name'] = $name; |
pierre@0
|
1493 } |
pierre@0
|
1494 // order actions by weight (multiple same-weight actions sorted by alpha) |
pierre@0
|
1495 ksort($actions); |
pierre@0
|
1496 variable_set("adserve_$hook", serialize($actions)); |
pierre@0
|
1497 } |
pierre@0
|
1498 |
pierre@0
|
1499 module_invoke_all('adapi', 'check_install', array()); |
pierre@0
|
1500 } |
pierre@0
|
1501 |
pierre@0
|
1502 /** |
pierre@0
|
1503 * Creates a vocabulary for use by ad groups if not already created. |
pierre@0
|
1504 */ |
pierre@0
|
1505 function _ad_get_vid() { |
pierre@0
|
1506 $vid = variable_get('ad_group_vid', ''); |
pierre@0
|
1507 if (empty($vid)) { |
pierre@0
|
1508 // No vid stored in the variables table, check if one even exists. |
pierre@0
|
1509 $vid = db_result(db_query("SELECT vid FROM {vocabulary} WHERE module = '%s'", 'ad')); |
pierre@0
|
1510 if (!$vid) { |
pierre@0
|
1511 // No vid, so we create one. |
pierre@0
|
1512 $edit = array( |
pierre@0
|
1513 'name' => t('Ad groups'), |
pierre@0
|
1514 'multiple' => 1, |
pierre@0
|
1515 'required' => 0, |
pierre@0
|
1516 'hierarchy' => 0, |
pierre@0
|
1517 'relations' => 0, |
pierre@0
|
1518 'module' => 'ad', |
pierre@0
|
1519 'nodes' => array('ad' => 1) |
pierre@0
|
1520 ); |
pierre@0
|
1521 |
pierre@0
|
1522 taxonomy_save_vocabulary($edit); |
pierre@0
|
1523 $vid = $edit['vid']; |
pierre@0
|
1524 } |
pierre@0
|
1525 // Save the vid for next time. |
pierre@0
|
1526 variable_set('ad_group_vid', $vid); |
pierre@0
|
1527 } |
pierre@0
|
1528 return $vid; |
pierre@0
|
1529 } |
pierre@0
|
1530 |
pierre@0
|
1531 /** |
pierre@0
|
1532 * Builds the necessary HTML to display an image-based impressions counter. |
pierre@0
|
1533 */ |
pierre@0
|
1534 function ad_display_image($ad, $css = TRUE) { |
pierre@0
|
1535 global $base_url; |
pierre@0
|
1536 $adserve = variable_get('adserve', ''); |
pierre@0
|
1537 $cache = variable_get('ad_cache', 'none'); |
pierre@0
|
1538 $variables = "?o=image"; |
pierre@0
|
1539 if (is_object($ad)) { |
pierre@0
|
1540 $aid = $ad->aid; |
pierre@0
|
1541 } |
pierre@0
|
1542 else { |
pierre@0
|
1543 /** |
pierre@0
|
1544 * No ad is specified, so we're just tracking traffic. |
pierre@0
|
1545 */ |
pierre@0
|
1546 $aid = 0; |
pierre@0
|
1547 } |
pierre@0
|
1548 $variables .= "&a=$aid"; |
pierre@0
|
1549 if ($cache != 'none') { |
pierre@0
|
1550 $variables .= '&c='. $cache . module_invoke('ad_cache_'. $cache, 'adcacheapi', 'display_variables', array()); |
pierre@0
|
1551 } |
pierre@0
|
1552 $output = '<img src="'. url($base_url .'/'. $adserve . $variables) .'" height="0" width="0" alt="view counter" />'; |
pierre@0
|
1553 if ($css) { |
pierre@0
|
1554 return '<div class="ad-image-counter">'. $output .'</div>'; |
pierre@0
|
1555 } |
pierre@0
|
1556 else { |
pierre@0
|
1557 return $output; |
pierre@0
|
1558 } |
pierre@0
|
1559 } |
pierre@0
|
1560 |
pierre@0
|
1561 /** |
pierre@0
|
1562 * Retrieve the group name from the nid. |
pierre@0
|
1563 */ |
pierre@0
|
1564 function _ad_get_group($nid) { |
pierre@0
|
1565 static $groups = array(); |
pierre@0
|
1566 |
pierre@0
|
1567 if (!isset($groups[$nid])) { |
pierre@0
|
1568 $result = db_query('SELECT d.name FROM {term_data} d LEFT JOIN {term_node} n ON d.tid = n.tid WHERE n.nid = %d AND d.vid = %d', $nid, _ad_get_vid()); |
pierre@0
|
1569 while ($term = db_fetch_object($result)) { |
pierre@0
|
1570 $terms[] = $term->name; |
pierre@0
|
1571 } |
pierre@0
|
1572 if (!empty($terms)) { |
pierre@0
|
1573 $groups[$nid] = implode(', ', $terms); |
pierre@0
|
1574 } |
pierre@0
|
1575 else { |
pierre@0
|
1576 $groups[$nid] = t('default'); |
pierre@0
|
1577 } |
pierre@0
|
1578 } |
pierre@0
|
1579 |
pierre@0
|
1580 return $groups[$nid]; |
pierre@0
|
1581 } |
pierre@0
|
1582 |