pierre@0
|
1 <?php |
sly@3
|
2 // $Id: ad.module,v 1.2.2.29.2.83.2.16.2.21 2009/04/16 14:24:53 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 } |
sly@2
|
160 $src = htmlentities(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 } |
sly@3
|
845 else if ($form_id == 'search_form' && variable_get('ad_no_search', 1) && !user_access('administer advertisements') && !user_access('administer any advertisement')) { |
sly@3
|
846 $vid = _ad_get_vid(); |
sly@3
|
847 $vocabulary = db_result(db_query('SELECT name FROM {vocabulary} WHERE vid = %d', $vid)); |
sly@3
|
848 unset($form['advanced']['category']['#options'][$vocabulary]); |
sly@3
|
849 if (empty($form['advanced']['category']['#options'])) { |
sly@3
|
850 unset($form['advanced']['category']); |
sly@3
|
851 } |
sly@3
|
852 unset($form['advanced']['type']['#options']['ad']); |
sly@3
|
853 } |
sly@3
|
854 } |
sly@3
|
855 |
sly@3
|
856 /** |
sly@3
|
857 * Implementation of hook_db_rewrite_sql(). |
sly@3
|
858 */ |
sly@3
|
859 function ad_db_rewrite_sql($query, $primary_table, $primary_field, $args) { |
sly@3
|
860 if (variable_get('ad_no_search', 1) && !user_access('administer advertisements') && !user_access('edit any advertisement') && $query == '' && $primary_table == 'n' && $primary_field = 'nid' && empty($args)) { |
sly@3
|
861 return array('where' => " n.type != 'ad'"); |
sly@3
|
862 } |
pierre@0
|
863 } |
pierre@0
|
864 |
pierre@0
|
865 /** |
pierre@0
|
866 * Implementation of hook_nodeapi(). |
pierre@0
|
867 */ |
pierre@0
|
868 function ad_nodeapi(&$node, $op, $teaser, $page) { |
pierre@0
|
869 global $user; |
pierre@0
|
870 |
pierre@0
|
871 switch ($op) { |
pierre@0
|
872 |
pierre@0
|
873 case 'load': |
pierre@0
|
874 $ad = db_fetch_array(db_query('SELECT * FROM {ads} WHERE aid = %d', $node->nid)); |
pierre@0
|
875 $merge = array_merge((array)$node, (array)$ad); |
pierre@0
|
876 $adtype = module_invoke('ad_'. $ad['adtype'], 'adapi', 'load', $merge); |
pierre@0
|
877 if (is_array($adtype)) { |
pierre@0
|
878 return array_merge($ad, $adtype); |
pierre@0
|
879 } |
pierre@0
|
880 else { |
pierre@0
|
881 return $ad; |
pierre@0
|
882 } |
pierre@0
|
883 break; |
pierre@0
|
884 |
pierre@0
|
885 case 'insert': |
pierre@0
|
886 if (isset($node->adtype)) { |
pierre@0
|
887 if ($node->status != 1 && $node->adstatus == 'active') { |
pierre@1
|
888 $node->adstatus = 'expired'; |
pierre@0
|
889 } |
pierre@0
|
890 $activated = $node->adstatus == 'active' ? time() : 0; |
pierre@1
|
891 if (!isset($node->autoactivate)) { |
pierre@0
|
892 $node->autoactivate = 0; |
pierre@0
|
893 } |
pierre@0
|
894 if (!isset($node->maxviews)) { |
pierre@0
|
895 $node->maxviews = 0; |
pierre@0
|
896 } |
pierre@0
|
897 if (!isset($node->maxclicks)) { |
pierre@0
|
898 $node->maxclicks = 0; |
pierre@0
|
899 } |
pierre@0
|
900 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
|
901 ad_statistics_increment($node->nid, 'create'); |
pierre@0
|
902 } |
pierre@0
|
903 break; |
pierre@0
|
904 |
pierre@0
|
905 case 'update': |
pierre@0
|
906 if (isset($node->adtype)) { |
pierre@0
|
907 $ad = db_fetch_object(db_query('SELECT * FROM {ads} WHERE aid = %d', $node->nid)); |
pierre@0
|
908 // Ad must be in approved state to be able to autoactivate it. |
pierre@1
|
909 if ($node->adstatus != 'approved' && isset($node->autoactive) && $node->autoactivate) { |
pierre@0
|
910 if ($node->adstatus == 'active') { |
pierre@0
|
911 // This ad is already active, no need to autoactivate it. |
pierre@0
|
912 $node->autoactivate = 0; |
pierre@0
|
913 } |
pierre@0
|
914 else { |
pierre@0
|
915 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
|
916 } |
pierre@0
|
917 } |
pierre@0
|
918 // If this node has been upublished, the ad should no longer be active. |
pierre@0
|
919 if ($node->status != 1 && $node->adstatus == 'active') { |
pierre@1
|
920 $node->adstatus = 'expired'; |
pierre@0
|
921 } |
pierre@0
|
922 // Check if ad is being manually activated. |
pierre@0
|
923 if ($ad->adstatus != 'active' && $node->adstatus == 'active') { |
pierre@0
|
924 $activated = time(); |
pierre@0
|
925 } |
pierre@0
|
926 // Check if ad is being manually expired. |
pierre@0
|
927 else if ($ad->adstatus != 'expired' && $node->adstatus == 'expired') { |
pierre@0
|
928 // Ad has been manually expired. |
pierre@1
|
929 $activated = $ad->activated; |
pierre@0
|
930 $expired = time(); |
pierre@0
|
931 } |
pierre@0
|
932 // Ad has not been manually activated or expired, preserve timestamps. |
pierre@0
|
933 else { |
pierre@0
|
934 $activated = $ad->activated; |
pierre@0
|
935 $expired = $ad->expired; |
pierre@0
|
936 } |
pierre@0
|
937 // Ad status has changed, record the event. |
pierre@0
|
938 if ($ad->adstatus != $node->adstatus) { |
pierre@0
|
939 ad_statistics_increment($node->nid, $node->adstatus); |
pierre@0
|
940 } |
pierre@0
|
941 // Update ads table with new information. |
pierre@1
|
942 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
|
943 ad_statistics_increment($node->nid, 'update'); |
pierre@0
|
944 } |
pierre@0
|
945 break; |
pierre@0
|
946 |
pierre@0
|
947 case 'delete': |
pierre@0
|
948 db_query("DELETE FROM {ads} WHERE aid = %d", $node->nid); |
pierre@0
|
949 db_query("DELETE FROM {ad_statistics} WHERE aid = %d", $node->nid); |
pierre@0
|
950 // All that's left of the ad is a single timestamp as to when it was |
pierre@0
|
951 // deleted. |
pierre@0
|
952 ad_statistics_increment($node->nid, 'delete'); |
pierre@0
|
953 break; |
pierre@0
|
954 |
pierre@0
|
955 case 'view': |
pierre@0
|
956 if (isset($node->adtype)) { |
sly@3
|
957 if (variable_get('ad_meta_noindex', 1)) { |
sly@3
|
958 ad_noindex_meta(); |
sly@3
|
959 } |
pierre@0
|
960 $node = node_prepare($node, $teaser); |
pierre@0
|
961 $node->content['body'] = array( |
pierre@0
|
962 '#value' => $teaser ? $node->teaser : theme('node_ad', $node, $page), |
pierre@0
|
963 '#weight' => 1, |
pierre@0
|
964 ); |
pierre@0
|
965 } |
pierre@0
|
966 break; |
pierre@0
|
967 } |
pierre@0
|
968 // Allow ad type module to act on nodeapi events. The adapi hook provides |
pierre@0
|
969 // access to additional variables not available in the nodeapi hook. |
pierre@0
|
970 if (isset($node->adtype)) { |
pierre@0
|
971 // Don't use module_invoke, as in pre-PHP5 the changes to $node won't be |
pierre@0
|
972 // passed back. |
pierre@0
|
973 $function = "ad_$node->adtype" .'_adapi'; |
pierre@0
|
974 if (function_exists($function)) { |
pierre@0
|
975 $function($op, $node); |
pierre@0
|
976 } |
pierre@0
|
977 } |
pierre@0
|
978 // Allow ad cache module to act on nodeapi events. |
pierre@0
|
979 $cache = variable_get('ad_cache', 'none'); |
pierre@0
|
980 if ($cache != 'none') { |
pierre@0
|
981 $function = "ad_cache_$cache" .'_adcacheapi'; |
pierre@0
|
982 if (function_exists($function)) { |
pierre@0
|
983 $function($op, $node); |
pierre@0
|
984 } |
pierre@0
|
985 } |
pierre@1
|
986 |
pierre@1
|
987 // Rebuild the cache after all hooks are invoked. |
pierre@1
|
988 switch ($op) { |
pierre@1
|
989 case 'insert': |
pierre@1
|
990 case 'update': |
pierre@1
|
991 case 'delete': |
pierre@1
|
992 if (variable_get('ad_cache_file_rebuild_realtime', 0) && |
pierre@1
|
993 isset($node->adtype)) { |
pierre@1
|
994 ad_rebuild_cache(); |
pierre@1
|
995 } |
pierre@1
|
996 } |
pierre@0
|
997 } |
pierre@0
|
998 |
sly@3
|
999 /** |
sly@3
|
1000 * Add the noindex meta tag. |
sly@3
|
1001 */ |
sly@3
|
1002 function ad_noindex_meta() { |
sly@3
|
1003 static $added = FALSE; |
sly@3
|
1004 if (!$added) { |
sly@3
|
1005 drupal_set_html_head('<meta name="robots" content="noindex" />'); |
sly@3
|
1006 $added = TRUE; |
sly@3
|
1007 } |
sly@3
|
1008 } |
sly@3
|
1009 |
pierre@0
|
1010 function ad_adapi($op, $node = NULL) { |
pierre@0
|
1011 switch ($op) { |
pierre@0
|
1012 case 'permissions': |
pierre@1
|
1013 return array( |
pierre@1
|
1014 'access statistics' => TRUE, |
pierre@1
|
1015 'access click history' => TRUE, |
pierre@1
|
1016 'set status as pending' => FALSE, |
pierre@1
|
1017 'set status as denied' => FALSE, |
pierre@1
|
1018 'set status from pending to approved' => FALSE, |
pierre@1
|
1019 'set status from pending to denied' => FALSE, |
pierre@1
|
1020 'set status from approved to active' => TRUE, |
pierre@1
|
1021 'set status from approved to offline' => TRUE, |
pierre@1
|
1022 'set status from active to offline' => TRUE, |
pierre@1
|
1023 'set status from active to expired' => FALSE, |
pierre@1
|
1024 'set status from offline to active' => TRUE, |
pierre@1
|
1025 'set status from offline to expired' => FALSE, |
pierre@1
|
1026 ); |
pierre@0
|
1027 break; |
pierre@0
|
1028 } |
pierre@0
|
1029 } |
pierre@0
|
1030 |
pierre@0
|
1031 /** |
pierre@0
|
1032 * Implementation of hook_menu(). |
pierre@0
|
1033 */ |
pierre@0
|
1034 function ad_menu() { |
pierre@0
|
1035 $items = array(); |
pierre@0
|
1036 |
pierre@0
|
1037 $items['admin/content/ad'] = array( |
pierre@0
|
1038 'title' => 'Ads', |
pierre@0
|
1039 'page callback' => 'ad_admin_list', |
pierre@0
|
1040 'access arguments' => array('administer advertisements'), |
pierre@0
|
1041 'description' => 'Configure and manage your advertising system.', |
pierre@0
|
1042 'file' => 'ad.admin.inc', |
pierre@0
|
1043 ); |
pierre@0
|
1044 $items['admin/content/ad/list'] = array( |
pierre@0
|
1045 'title' => 'List', |
pierre@0
|
1046 'page callback' => 'ad_admin_list', |
pierre@0
|
1047 'access arguments' => array('administer advertisements'), |
pierre@0
|
1048 'type' => MENU_DEFAULT_LOCAL_TASK, |
pierre@0
|
1049 'file' => 'ad.admin.inc', |
pierre@0
|
1050 ); |
pierre@0
|
1051 $items['admin/content/ad/configure'] = array( |
pierre@0
|
1052 'title' => 'Settings', |
pierre@0
|
1053 'page callback' => 'drupal_get_form', |
pierre@0
|
1054 'page arguments' => array('ad_admin_configure_settings'), |
pierre@0
|
1055 'access arguments' => array('administer advertisements'), |
pierre@0
|
1056 'type' => MENU_LOCAL_TASK, |
pierre@0
|
1057 'weight' => 3, |
pierre@0
|
1058 'file' => 'ad.admin.inc', |
pierre@0
|
1059 ); |
pierre@1
|
1060 $items['node/add/ad/ahah'] = array( |
pierre@1
|
1061 'access arguments' => array('create advertisements'), |
pierre@1
|
1062 'page callback' => 'ad_form_ahah', |
pierre@1
|
1063 'type' => MENU_CALLBACK, |
pierre@1
|
1064 ); |
pierre@0
|
1065 |
pierre@0
|
1066 ad_menu_add_global_settings($items); |
pierre@0
|
1067 |
pierre@0
|
1068 $items['admin/content/ad/groups'] = array( |
pierre@0
|
1069 'title' => 'Ad groups', |
pierre@0
|
1070 'page callback' => 'ad_admin_groups_list', |
pierre@0
|
1071 'access arguments' => array('administer advertisements'), |
pierre@0
|
1072 'type' => MENU_LOCAL_TASK, |
pierre@0
|
1073 'weight' => 5, |
pierre@0
|
1074 'file' => 'ad.admin.inc', |
pierre@0
|
1075 ); |
pierre@0
|
1076 $items['admin/content/ad/groups/list'] = array( |
pierre@0
|
1077 'title' => 'List', |
pierre@0
|
1078 'page callback' => 'ad_admin_groups_list', |
pierre@0
|
1079 'access arguments' => array('administer advertisements'), |
pierre@0
|
1080 'type' => MENU_DEFAULT_LOCAL_TASK, |
pierre@0
|
1081 'weight' => 0, |
pierre@0
|
1082 'file' => 'ad.admin.inc', |
pierre@0
|
1083 ); |
pierre@0
|
1084 $items['admin/content/ad/groups/add'] = array( |
pierre@0
|
1085 'title' => 'Create group', |
pierre@0
|
1086 'page callback' => 'drupal_get_form', |
pierre@0
|
1087 'page arguments' => array('ad_admin_group_form'), |
pierre@0
|
1088 'access arguments' => array('administer advertisements'), |
pierre@0
|
1089 'type' => MENU_LOCAL_TASK, |
pierre@0
|
1090 'weight' => 3, |
pierre@0
|
1091 'file' => 'ad.admin.inc', |
pierre@0
|
1092 ); |
pierre@0
|
1093 $items["admin/content/ad/groups/%ad_group/edit"] = array( |
pierre@0
|
1094 'title' => 'Edit group', |
pierre@0
|
1095 'page callback' => 'drupal_get_form', |
pierre@0
|
1096 'page arguments' => array('ad_admin_group_form', 4), |
pierre@0
|
1097 'access arguments' => array('administer advertisements'), |
pierre@0
|
1098 'weight' => 1, |
pierre@0
|
1099 'file' => 'ad.admin.inc', |
pierre@0
|
1100 ); |
pierre@0
|
1101 $items["admin/content/ad/groups/%ad_group/delete"] = array( |
pierre@0
|
1102 'title' => 'Delete group', |
pierre@0
|
1103 'page callback' => 'drupal_get_form', |
pierre@0
|
1104 'page arguments' => array('ad_confirm_group_delete', 4), |
pierre@0
|
1105 'access arguments' => array('administer advertisements'), |
pierre@0
|
1106 'weight' => 2, |
pierre@0
|
1107 'file' => 'ad.admin.inc', |
pierre@0
|
1108 ); |
pierre@0
|
1109 $items['admin/content/ad/configure/global'] = array( |
pierre@0
|
1110 'title' => 'Global settings', |
pierre@0
|
1111 'page callback' => 'drupal_get_form', |
pierre@0
|
1112 'page arguments' => array('ad_admin_configure_settings'), |
pierre@0
|
1113 'access arguments' => array('administer advertisements'), |
pierre@0
|
1114 'type' => MENU_DEFAULT_LOCAL_TASK, |
pierre@0
|
1115 'weight' => 0, |
pierre@0
|
1116 'file' => 'ad.admin.inc', |
pierre@0
|
1117 ); |
pierre@0
|
1118 $items["node/%node/details/%"] = array( |
pierre@0
|
1119 'title' => 'Click details', |
pierre@0
|
1120 'page callback' => 'ad_click_details', |
pierre@0
|
1121 'page arguments' => array(1, 3), |
pierre@0
|
1122 'access arguments' => array(1, 'access click history'), |
pierre@1
|
1123 'access callback' => 'ad_permission', |
pierre@0
|
1124 'type' => MENU_CALLBACK, |
pierre@0
|
1125 'file' => 'ad.pages.inc', |
pierre@0
|
1126 ); |
pierre@1
|
1127 $items["ad/redirect/%"] = array( |
pierre@0
|
1128 'access arguments' => array('show advertisements'), |
pierre@0
|
1129 'type' => MENU_CALLBACK, |
pierre@0
|
1130 'page callback' => 'ad_redirect', |
pierre@1
|
1131 'page arguments' => (array(2)), |
pierre@0
|
1132 ); |
pierre@0
|
1133 |
pierre@0
|
1134 return $items; |
pierre@0
|
1135 } |
pierre@0
|
1136 |
pierre@0
|
1137 /** |
pierre@0
|
1138 * Load settings for all ad modules. Those modules, who don't |
pierre@0
|
1139 * have their settings form, will get a standard one. |
pierre@0
|
1140 */ |
pierre@0
|
1141 function ad_menu_add_global_settings(&$menu_items) { |
pierre@0
|
1142 $adtypes = ad_get_types(); |
pierre@0
|
1143 foreach ($adtypes as $type => $name) { |
pierre@0
|
1144 // Ad type global settings. |
pierre@0
|
1145 $settings = 'ad_'. $type .'_global_settings'; |
pierre@1
|
1146 $file = 'ad_image.module'; |
pierre@0
|
1147 if (!function_exists($settings)) { |
pierre@0
|
1148 $settings = 'ad_no_global_settings'; |
pierre@1
|
1149 $file = 'ad.admin.inc'; |
pierre@0
|
1150 } |
pierre@0
|
1151 $menu_items['admin/content/ad/configure/'. $type] = array( |
pierre@0
|
1152 'title' => $name, |
pierre@0
|
1153 'page callback' => 'drupal_get_form', |
pierre@0
|
1154 'page arguments' => array($settings), |
pierre@0
|
1155 'access arguments' => array('administer advertisements'), |
pierre@0
|
1156 'type' => MENU_LOCAL_TASK, |
pierre@0
|
1157 'weight' => 2, |
pierre@0
|
1158 'file' => 'ad.admin.inc', |
pierre@0
|
1159 ); |
pierre@0
|
1160 } |
pierre@0
|
1161 } |
pierre@0
|
1162 |
pierre@0
|
1163 /** |
pierre@0
|
1164 * Drupal menu wildcard Ad group loader |
pierre@0
|
1165 */ |
pierre@0
|
1166 function ad_group_load($tid) { |
pierre@0
|
1167 if (!is_numeric($tid)) { |
pierre@0
|
1168 return FALSE; |
pierre@0
|
1169 } |
pierre@0
|
1170 $group = ad_groups_list(TRUE, $tid); |
pierre@0
|
1171 if (!isset($group)) { |
pierre@0
|
1172 return FALSE; |
pierre@0
|
1173 } |
pierre@0
|
1174 return $group; |
pierre@0
|
1175 } |
pierre@0
|
1176 |
pierre@0
|
1177 /** |
pierre@0
|
1178 * Implementation of hook_block(). |
pierre@0
|
1179 */ |
pierre@0
|
1180 function ad_block($op = 'list', $delta = 0, $edit = array()) { |
pierre@0
|
1181 switch ($op) { |
pierre@0
|
1182 case 'list': |
pierre@0
|
1183 $blocks = array(); |
pierre@0
|
1184 $groups = ad_groups_list(); |
pierre@0
|
1185 foreach ($groups as $tid => $name) { |
pierre@0
|
1186 $blocks[$tid]['info'] = t('ad group: @name', array('@name' => $name)); |
pierre@0
|
1187 } |
pierre@0
|
1188 return $blocks; |
pierre@0
|
1189 case 'configure': |
pierre@0
|
1190 $form['ad_block_quantity_'. $delta] = array( |
pierre@0
|
1191 '#type' => 'select', |
pierre@0
|
1192 '#title' => t('Number of ads'), |
pierre@0
|
1193 '#default_value' => variable_get('ad_block_quantity_'. $delta, 1), |
pierre@0
|
1194 '#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
|
1195 '#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
|
1196 ); |
pierre@0
|
1197 return $form; |
pierre@0
|
1198 case 'save': |
pierre@0
|
1199 variable_set('ad_block_quantity_'. $delta, $edit['ad_block_quantity_'. $delta]); |
pierre@0
|
1200 break; |
pierre@0
|
1201 case 'view': |
pierre@0
|
1202 $groups = ad_groups_list(); |
pierre@0
|
1203 $block['content'] = ad($delta, variable_get('ad_block_quantity_'. $delta, 1)); |
pierre@0
|
1204 return $block; |
pierre@0
|
1205 } |
pierre@0
|
1206 } |
pierre@0
|
1207 |
pierre@0
|
1208 /** |
pierre@0
|
1209 * Determine whether the user has a given privilege. |
pierre@0
|
1210 * |
pierre@1
|
1211 * @param $aid |
pierre@1
|
1212 * ID of advertisement. |
pierre@0
|
1213 * @param $permission |
pierre@1
|
1214 * Permission string which should be checked (such as 'access click history') |
pierre@0
|
1215 * @param $account |
pierre@0
|
1216 * User object, which are accessing the ad or current user by default. |
pierre@0
|
1217 */ |
pierre@1
|
1218 function ad_permission($aid, $string, $account = NULL) { |
pierre@0
|
1219 global $user; |
pierre@1
|
1220 $access = FALSE; |
pierre@0
|
1221 |
pierre@1
|
1222 // by default, check permission for current user |
pierre@0
|
1223 if (!isset($account)) { |
pierre@0
|
1224 $account = $user; |
pierre@0
|
1225 } |
pierre@0
|
1226 |
pierre@1
|
1227 // user #1 has all privileges |
pierre@0
|
1228 if ($account->uid == 1) { |
pierre@0
|
1229 return TRUE; |
pierre@0
|
1230 } |
pierre@0
|
1231 |
pierre@1
|
1232 // if you have administer permissions, you have all permissions |
pierre@0
|
1233 if (user_access('administer advertisements', $account)) { |
pierre@0
|
1234 return TRUE; |
pierre@0
|
1235 } |
pierre@0
|
1236 |
pierre@1
|
1237 // when used in the Drupal menu, $aid may be the full ad object. |
pierre@1
|
1238 if (is_object($aid) && isset($aid->aid)) { |
pierre@1
|
1239 $aid = $aid->aid; |
pierre@1
|
1240 } |
sly@3
|
1241 else if (is_object($aid) && isset($aid->nid)) { |
sly@3
|
1242 $aid = $aid->nid; |
sly@3
|
1243 } |
pierre@1
|
1244 else if (is_object($aid)) { |
pierre@1
|
1245 watchdog('ad', 'Invalid aid object passed into ad_permission, no aid->aid set.'); |
pierre@1
|
1246 $aid = 0; |
pierre@0
|
1247 } |
pierre@0
|
1248 |
pierre@1
|
1249 // invoke ad_owners module to determine user's access |
pierre@1
|
1250 if (module_exists('ad_owners') && |
pierre@1
|
1251 function_exists('ad_owners_permission')) { |
pierre@1
|
1252 $access = ad_owners_permission($aid, $string, $account); |
pierre@1
|
1253 } |
pierre@1
|
1254 // no ad_owners module, allow acces to statistics and click history |
pierre@1
|
1255 else if (in_array($string, array('access statistics', 'access click history'))) { |
pierre@1
|
1256 $access = TRUE; |
pierre@1
|
1257 } |
pierre@1
|
1258 // with no ad_owners module, all other permissions are denied unless user |
pierre@1
|
1259 // has 'administer advertisements' permission |
pierre@1
|
1260 return $access; |
pierre@0
|
1261 } |
pierre@0
|
1262 |
pierre@0
|
1263 /** |
pierre@0
|
1264 * Returns ad types data. |
pierre@0
|
1265 * |
pierre@0
|
1266 * @param $op |
pierre@0
|
1267 * If set to 'name', will only return array of type names ($type => $name). |
pierre@0
|
1268 * If set to 'data', will return all of the type's data |
pierre@0
|
1269 * @param $type |
pierre@0
|
1270 * If not specified, will return array of all available types, else will |
pierre@0
|
1271 * return specific type's name or data. |
pierre@0
|
1272 */ |
pierre@0
|
1273 function ad_get_types($op = 'name', $type = NULL) { |
pierre@0
|
1274 $adtypes = module_invoke_all('adapi', 'type', array()); |
pierre@0
|
1275 switch ($op) { |
pierre@0
|
1276 case 'name': |
pierre@0
|
1277 if (isset($type)) { |
pierre@0
|
1278 return $adtypes[$type]['name']; |
pierre@0
|
1279 } |
pierre@0
|
1280 else { |
pierre@0
|
1281 foreach ($adtypes as $type => $data) { |
pierre@0
|
1282 $adtypes[$type] = $data['name']; |
pierre@0
|
1283 } |
pierre@0
|
1284 return $adtypes; |
pierre@0
|
1285 } |
pierre@0
|
1286 case 'data': |
pierre@0
|
1287 if (isset($type)) { |
pierre@0
|
1288 return $adtypes[$type]; |
pierre@0
|
1289 } |
pierre@0
|
1290 else { |
pierre@0
|
1291 return $adtypes; |
pierre@0
|
1292 } |
pierre@0
|
1293 } |
pierre@0
|
1294 } |
pierre@0
|
1295 |
pierre@0
|
1296 /** |
pierre@0
|
1297 * Return an array of all groups, or a specific group. |
pierre@0
|
1298 * |
pierre@0
|
1299 * @param $object |
pierre@0
|
1300 * If FALSE, will return only name of group(s). If TRUE, will return full |
pierre@0
|
1301 * group object including ->name, ->description, and ->tid. |
pierre@0
|
1302 * @param $tid |
pierre@0
|
1303 * If set to an integer >0, will only return group info about that specific |
pierre@0
|
1304 * group. |
pierre@0
|
1305 */ |
pierre@0
|
1306 function ad_groups_list($object = FALSE, $tid = NULL) { |
pierre@0
|
1307 static $groups = array(); |
pierre@0
|
1308 static $names = array(); |
pierre@0
|
1309 |
pierre@0
|
1310 // Return the full group object(s). |
pierre@0
|
1311 if ($object) { |
pierre@0
|
1312 if (empty($groups)) { |
pierre@0
|
1313 $tids = taxonomy_get_tree(_ad_get_vid()); |
pierre@0
|
1314 if (is_array($tids)) { |
pierre@0
|
1315 foreach ($tids as $group) { |
pierre@0
|
1316 $groups[$group->tid]->name = $group->name; |
pierre@0
|
1317 $groups[$group->tid]->description = $group->description; |
pierre@0
|
1318 $groups[$group->tid]->tid = $group->tid; |
pierre@0
|
1319 $groups[$group->tid]->weight = $group->weight; |
pierre@0
|
1320 } |
pierre@0
|
1321 } |
pierre@0
|
1322 // Hard coded "default" group with tid of 0. |
pierre@0
|
1323 $groups[0]->name = t('default'); |
pierre@0
|
1324 $groups[0]->description = t('The default ad group is comprised of all ads not assigned to any other ad group.'); |
pierre@0
|
1325 $groups[0]->tid = 0; |
pierre@0
|
1326 $groups[0]->weight = 0; |
pierre@0
|
1327 } |
pierre@0
|
1328 // Return a specific group object. |
pierre@0
|
1329 if ((int)$tid) { |
pierre@0
|
1330 return $groups[$tid]; |
pierre@0
|
1331 } |
pierre@0
|
1332 // Return an array of all group objects. |
pierre@0
|
1333 else { |
pierre@0
|
1334 return $groups; |
pierre@0
|
1335 } |
pierre@0
|
1336 } |
pierre@0
|
1337 // Return only the group name(s). |
pierre@0
|
1338 else { |
pierre@0
|
1339 if (empty($names)) { |
pierre@0
|
1340 $tids = taxonomy_get_tree(_ad_get_vid()); |
pierre@0
|
1341 if (is_array($tids)) { |
pierre@0
|
1342 foreach ($tids as $group) { |
pierre@0
|
1343 $names[$group->tid] = $group->name; |
pierre@0
|
1344 } |
pierre@0
|
1345 } |
pierre@0
|
1346 // Hard coded "default" group with tid of 0. |
pierre@0
|
1347 $names[0] = t('default'); |
pierre@0
|
1348 } |
pierre@0
|
1349 // Return a specific group name. |
pierre@0
|
1350 if ((int)$tid) { |
pierre@0
|
1351 return $names[$tid]; |
pierre@0
|
1352 } |
pierre@0
|
1353 // Return an array of all group names. |
pierre@0
|
1354 else { |
pierre@0
|
1355 return $names; |
pierre@0
|
1356 } |
pierre@0
|
1357 } |
pierre@0
|
1358 } |
pierre@0
|
1359 |
pierre@0
|
1360 /** |
pierre@0
|
1361 * Implement ad notify api _hook. |
pierre@0
|
1362 */ |
pierre@0
|
1363 function ad_adnotifyapi($op, $arg1 = NULL, $arg2 = NULL) { |
pierre@0
|
1364 switch ($op) { |
pierre@0
|
1365 // Make the following events available for notification. |
pierre@0
|
1366 case 'register': |
pierre@0
|
1367 return array( |
pierre@0
|
1368 '-expired' => t('Email @when before the advertisement will expire.'), |
pierre@0
|
1369 'expired' => t('Email @when after the advertisement is expired.'), |
pierre@0
|
1370 '-active' => t('Email @when before the advertisement will be activated (if scheduled).'), |
pierre@0
|
1371 'active' => t('Email @when after the advertisement is activated.'), |
sly@2
|
1372 'offline' => t('Email @when after the advertisement is taken offline.'), |
pierre@0
|
1373 'click' => t('Email @when after the advertisement is clicked.'), |
pierre@0
|
1374 'approved' => t('Email @when after the advertisement is approved.'), |
pierre@0
|
1375 'denied' => t('Email @when after the advertisement is denied.'), |
sly@2
|
1376 'update' => t('Email @when after the advertisement is updated.'), |
pierre@0
|
1377 ); |
pierre@0
|
1378 break; |
pierre@0
|
1379 case '-expired': |
pierre@0
|
1380 $node = node_load($arg1->aid); |
pierre@0
|
1381 if (isset($node->autoexpire) && $node->autoexpire) { |
pierre@0
|
1382 if ((time() + $arg1->delay >= $node->autoexpire) && |
pierre@0
|
1383 ($arg1->sent + $arg1->delay < $node->autoexpire)) { |
pierre@0
|
1384 return array('-expired' => 1); |
pierre@0
|
1385 } |
pierre@0
|
1386 } |
pierre@0
|
1387 break; |
pierre@0
|
1388 case '-active': |
pierre@0
|
1389 $node = node_load($arg1->aid); |
pierre@0
|
1390 if (isset($node->autoactivate) && $node->autoactivate) { |
pierre@0
|
1391 if ((time() + $arg1->delay >= $node->autoactivate) && |
pierre@0
|
1392 ($arg1->sent + $arg1->delay < $node->autoactivate)) { |
pierre@0
|
1393 return array('-active' => 1); |
pierre@0
|
1394 } |
pierre@0
|
1395 } |
pierre@0
|
1396 break; |
pierre@0
|
1397 case 'mail_text': |
pierre@0
|
1398 switch ($arg1) { |
pierre@0
|
1399 case 'expired': |
pierre@0
|
1400 return array( |
pierre@1
|
1401 'subject' => t('[%site-name ad] %event notification'), |
pierre@1
|
1402 '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
|
1403 ); |
pierre@0
|
1404 case '-expired': |
pierre@0
|
1405 return array( |
pierre@1
|
1406 'subject' => t('[%site-name ad] expiration notification'), |
pierre@1
|
1407 '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
|
1408 ); |
pierre@0
|
1409 case 'active': |
pierre@0
|
1410 return array( |
pierre@1
|
1411 'subject' => t('[%site-name ad] %event notification'), |
pierre@1
|
1412 '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
|
1413 ); |
pierre@0
|
1414 case '-active': |
pierre@0
|
1415 return array( |
pierre@1
|
1416 'subject' => t('[%site-name ad] activation notification'), |
pierre@1
|
1417 '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
|
1418 ); |
pierre@0
|
1419 case 'click': |
pierre@0
|
1420 return array( |
pierre@1
|
1421 'subject' => t('[%site-name ad] %event notification'), |
pierre@1
|
1422 '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
|
1423 ); |
pierre@0
|
1424 case 'approved': |
pierre@0
|
1425 return array( |
pierre@1
|
1426 'subject' => t('[%site-name ad] %event notification'), |
pierre@1
|
1427 '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
|
1428 ); |
pierre@0
|
1429 case 'denied': |
pierre@0
|
1430 return array( |
pierre@1
|
1431 'subject' => t('[%site-name ad] %event notification'), |
pierre@1
|
1432 '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
|
1433 ); |
pierre@0
|
1434 } |
pierre@0
|
1435 break; |
pierre@0
|
1436 } |
pierre@0
|
1437 } |
pierre@0
|
1438 |
pierre@0
|
1439 function _ad_check_installation() { |
pierre@0
|
1440 // Verify serve.php exists and is readable. |
pierre@0
|
1441 $adserve = variable_get('adserve', ''); |
pierre@0
|
1442 $adserveinc = variable_get('adserveinc', ''); |
pierre@0
|
1443 if (!file_exists($adserve)) { |
pierre@0
|
1444 // The serve.php file should be in the same directory as the ad.module. |
pierre@0
|
1445 $adserve = drupal_get_path('module', 'ad') .'/serve.php'; |
pierre@0
|
1446 variable_set('adserve', $adserve); |
pierre@0
|
1447 } |
pierre@0
|
1448 if (!is_readable($adserve)) { |
pierre@0
|
1449 variable_set('adserve', ''); |
pierre@0
|
1450 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
|
1451 } |
pierre@0
|
1452 if (!file_exists($adserveinc)) { |
pierre@0
|
1453 // The adserve.inc file should be in the same directory as the ad.module. |
pierre@0
|
1454 $adserveinc = drupal_get_path('module', 'ad') .'/adserve.inc'; |
pierre@0
|
1455 variable_set('adserveinc', $adserveinc); |
pierre@0
|
1456 } |
pierre@0
|
1457 if (!is_readable($adserveinc)) { |
pierre@0
|
1458 variable_set('adserveinc', ''); |
pierre@0
|
1459 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
|
1460 } |
pierre@0
|
1461 |
pierre@0
|
1462 // Validate vid in vocabulary table. |
pierre@0
|
1463 $vid = db_result(db_query("SELECT vid FROM {vocabulary} WHERE module = 'ad'")); |
pierre@0
|
1464 if ($vid != variable_get('ad_group_vid', '')) { |
pierre@0
|
1465 drupal_set_message(t('Invalid vocabulary defined for advertisements, attempting to auto-fix.'), 'error'); |
pierre@0
|
1466 if ($vid) { |
pierre@0
|
1467 db_query("DELETE FROM {vocabulary_node_types} WHERE vid = %d OR type = 'ad'", variable_get('ad_group_vid', '')); |
pierre@0
|
1468 variable_set('ad_group_vid_restore', variable_get('ad_group_vid', '')); |
pierre@0
|
1469 } |
pierre@0
|
1470 variable_del('ad_group_vid'); |
pierre@0
|
1471 } |
pierre@0
|
1472 else { |
pierre@0
|
1473 // Validate vid in vocabulary_node_types table. |
pierre@0
|
1474 $result = db_query("SELECT vid FROM {vocabulary_node_types} WHERE type = 'ad'"); |
pierre@0
|
1475 $found = FALSE; |
pierre@0
|
1476 while ($vocab = db_fetch_object($result)) { |
pierre@0
|
1477 if ($vocab->vid == variable_get('ad_group_vid', '')) { |
pierre@0
|
1478 $found = TRUE; |
pierre@0
|
1479 } |
pierre@0
|
1480 } |
pierre@0
|
1481 if (!$found) { |
pierre@0
|
1482 drupal_set_message(t('Missing vocabulary node type for advertisements, attempting to auto-fix.'), 'error'); |
pierre@0
|
1483 db_query("DELETE FROM {vocabulary_node_types} WHERE vid = %d OR type = 'ad'", variable_get('ad_group_vid', '')); |
pierre@0
|
1484 db_query("DELETE FROM {vocabulary} WHERE vid = %d", variable_get('ad_group_vid', '')); |
pierre@0
|
1485 variable_set('ad_group_vid_restore', variable_get('ad_group_vid', '')); |
pierre@0
|
1486 variable_del('ad_group_vid'); |
pierre@0
|
1487 } |
pierre@0
|
1488 } |
pierre@0
|
1489 |
pierre@0
|
1490 _ad_get_vid(); |
pierre@0
|
1491 // Preserve old ad groups, if any. |
pierre@0
|
1492 if (($old = variable_get('ad_group_vid_restore', '')) && |
pierre@0
|
1493 $vid = variable_get('ad_group_vid', '')) { |
pierre@0
|
1494 drupal_set_message(t('Restoring orphaned ad group configuration.')); |
pierre@0
|
1495 db_query('UPDATE {term_data} SET vid = %d WHERE vid = %d', $vid, $old); |
pierre@0
|
1496 variable_set('ad_group_vid_restore', ''); |
pierre@0
|
1497 } |
pierre@0
|
1498 |
pierre@0
|
1499 $rid = db_result(db_query_range("SELECT rid FROM {permission} WHERE perm LIKE '%%show advertisements%%'", 1)); |
pierre@0
|
1500 if (!$rid) { |
pierre@0
|
1501 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
|
1502 } |
pierre@0
|
1503 |
pierre@0
|
1504 // Allow modules to define an action to take each time an ad is served. |
pierre@0
|
1505 // When modules define 'adserve_select' or 'adserve_filter', they must set |
pierre@0
|
1506 // the 'function' and 'path' parameters. The 'weight' parameter can |
pierre@0
|
1507 // optionally be set. |
pierre@0
|
1508 // function: the function to call when serving an add |
pierre@0
|
1509 // path: the path to the include file where $function is defined |
pierre@0
|
1510 // Modules can define actions that happen when advertisements are served. |
pierre@0
|
1511 // Currently support actions are: |
pierre@0
|
1512 // - init_text (display content before displaying ads) // TODO |
pierre@0
|
1513 // - select (alter which ads are selected to be displayed) // TODO |
pierre@0
|
1514 // - filter (filter selected ads before they are displayed) // TODO |
pierre@0
|
1515 // - exit_text (display content after displaying ads) // TODO |
pierre@0
|
1516 $hooks = array('init_text', 'select', 'filter', 'exit_text'); |
pierre@0
|
1517 foreach ($hooks as $hook) { |
pierre@0
|
1518 $adserve_actions = module_invoke_all('adapi', "adserve_$hook", array()); |
pierre@0
|
1519 $actions = array(); |
pierre@0
|
1520 foreach ($adserve_actions as $name => $action) { |
pierre@0
|
1521 if (is_numeric($action['weight'])) { |
pierre@0
|
1522 $weight = $action['weight']; |
pierre@0
|
1523 } |
pierre@0
|
1524 else { |
pierre@0
|
1525 // weight is an optional, defaults to 0 |
pierre@0
|
1526 $weight = $action['weight'] = 0; |
pierre@0
|
1527 } |
pierre@0
|
1528 $actions[$weight .'.'. $name] = $action; |
pierre@0
|
1529 $actions[$weight .'.'. $name]['name'] = $name; |
pierre@0
|
1530 } |
pierre@0
|
1531 // order actions by weight (multiple same-weight actions sorted by alpha) |
pierre@0
|
1532 ksort($actions); |
pierre@0
|
1533 variable_set("adserve_$hook", serialize($actions)); |
pierre@0
|
1534 } |
pierre@0
|
1535 |
pierre@0
|
1536 module_invoke_all('adapi', 'check_install', array()); |
pierre@0
|
1537 } |
pierre@0
|
1538 |
pierre@0
|
1539 /** |
pierre@0
|
1540 * Creates a vocabulary for use by ad groups if not already created. |
pierre@0
|
1541 */ |
pierre@0
|
1542 function _ad_get_vid() { |
pierre@0
|
1543 $vid = variable_get('ad_group_vid', ''); |
pierre@0
|
1544 if (empty($vid)) { |
pierre@0
|
1545 // No vid stored in the variables table, check if one even exists. |
pierre@0
|
1546 $vid = db_result(db_query("SELECT vid FROM {vocabulary} WHERE module = '%s'", 'ad')); |
pierre@0
|
1547 if (!$vid) { |
pierre@0
|
1548 // No vid, so we create one. |
pierre@0
|
1549 $edit = array( |
pierre@0
|
1550 'name' => t('Ad groups'), |
pierre@0
|
1551 'multiple' => 1, |
pierre@0
|
1552 'required' => 0, |
pierre@0
|
1553 'hierarchy' => 0, |
pierre@0
|
1554 'relations' => 0, |
pierre@0
|
1555 'module' => 'ad', |
pierre@0
|
1556 'nodes' => array('ad' => 1) |
pierre@0
|
1557 ); |
pierre@0
|
1558 |
pierre@0
|
1559 taxonomy_save_vocabulary($edit); |
pierre@0
|
1560 $vid = $edit['vid']; |
pierre@0
|
1561 } |
pierre@0
|
1562 // Save the vid for next time. |
pierre@0
|
1563 variable_set('ad_group_vid', $vid); |
pierre@0
|
1564 } |
pierre@0
|
1565 return $vid; |
pierre@0
|
1566 } |
pierre@0
|
1567 |
pierre@0
|
1568 /** |
pierre@0
|
1569 * Builds the necessary HTML to display an image-based impressions counter. |
pierre@0
|
1570 */ |
sly@2
|
1571 function ad_display_image($aid, $css = TRUE) { |
pierre@0
|
1572 global $base_url; |
pierre@0
|
1573 $adserve = variable_get('adserve', ''); |
pierre@0
|
1574 $cache = variable_get('ad_cache', 'none'); |
pierre@0
|
1575 $variables = "?o=image"; |
sly@2
|
1576 $variables .= "&a=$aid"; |
sly@2
|
1577 if ($cache != 'none') { |
sly@2
|
1578 $variables .= '&c='. $cache . module_invoke('ad_cache_'. $cache, 'adcacheapi', 'display_variables', array()); |
pierre@0
|
1579 } |
sly@2
|
1580 $output = '<img src="'. htmlentities(url($base_url .'/'. $adserve . $variables)) .'" height="0" width="0" alt="view counter" />'; |
pierre@0
|
1581 if ($css) { |
pierre@0
|
1582 return '<div class="ad-image-counter">'. $output .'</div>'; |
pierre@0
|
1583 } |
pierre@0
|
1584 else { |
pierre@0
|
1585 return $output; |
pierre@0
|
1586 } |
pierre@0
|
1587 } |
pierre@0
|
1588 |
pierre@0
|
1589 /** |
pierre@0
|
1590 * Retrieve the group name from the nid. |
pierre@0
|
1591 */ |
pierre@0
|
1592 function _ad_get_group($nid) { |
pierre@0
|
1593 static $groups = array(); |
pierre@0
|
1594 |
pierre@0
|
1595 if (!isset($groups[$nid])) { |
pierre@0
|
1596 $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
|
1597 while ($term = db_fetch_object($result)) { |
pierre@0
|
1598 $terms[] = $term->name; |
pierre@0
|
1599 } |
pierre@0
|
1600 if (!empty($terms)) { |
pierre@0
|
1601 $groups[$nid] = implode(', ', $terms); |
pierre@0
|
1602 } |
pierre@0
|
1603 else { |
pierre@0
|
1604 $groups[$nid] = t('default'); |
pierre@0
|
1605 } |
pierre@0
|
1606 } |
pierre@0
|
1607 |
pierre@0
|
1608 return $groups[$nid]; |
pierre@0
|
1609 } |
pierre@0
|
1610 |