annotate ad.admin.inc @ 1:948362c2a207 ad

update advertisement
author pierre
date Thu, 02 Apr 2009 15:28:21 +0000
parents d8a3998dac8e
children 416ea999ed76
rev   line source
pierre@0 1 <?php
pierre@1 2 // $Id: ad.admin.inc,v 1.1.2.9.2.2 2009/03/02 07:31:23 jeremy Exp $
pierre@0 3
pierre@0 4 /**
pierre@0 5 * @file
pierre@0 6 * Advertisement admin pages and functions.
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@0 12 /**
pierre@0 13 * Build default ad administration page.
pierre@0 14 */
pierre@0 15 function ad_admin_list() {
pierre@0 16 _ad_check_installation();
pierre@0 17
pierre@0 18 $output = drupal_get_form('ad_filter_form');
pierre@0 19
pierre@0 20 if (isset($_POST['operation']) && ($_POST['operation'] == 'delete') && isset($_POST['ads'])) {
pierre@0 21 return drupal_get_form('ad_multiple_delete_confirm');
pierre@0 22 }
pierre@0 23 $output .= drupal_get_form('ad_admin_ads');
pierre@0 24
pierre@0 25 return $output;
pierre@0 26 }
pierre@0 27
pierre@0 28 /**
pierre@0 29 * Provide a filterable list of advertisements.
pierre@0 30 */
pierre@0 31 function ad_admin_ads() {
pierre@0 32 $filter = ad_build_filter_query();
pierre@0 33 $result = pager_query('SELECT a.*, n.* FROM {ads} a INNER JOIN {node} n ON a.aid = n.nid '. $filter['join'] .' '. $filter['where'] .' ORDER BY n.changed DESC', 50, 0, NULL, $filter['args']);
pierre@0 34
pierre@0 35 $form['options'] = array('#type' => 'fieldset',
pierre@0 36 '#title' => t('Update options'),
pierre@0 37 '#prefix' => '<div class="container-inline">',
pierre@0 38 '#suffix' => '</div>',
pierre@0 39 );
pierre@0 40 $options = array();
pierre@0 41 foreach (module_invoke_all('ad_operations') as $operation => $array) {
pierre@0 42 $options[$operation] = $array['label'];
pierre@0 43 }
pierre@0 44 $form['options']['operation'] = array('#type' => 'select', '#options' => $options, '#default_value' => 'approve');
pierre@0 45 $form['options']['submit'] = array('#type' => 'submit', '#value' => t('Update'));
pierre@0 46
pierre@0 47 $destination = drupal_get_destination();
pierre@0 48 $ads = array();
pierre@0 49 while ($ad = db_fetch_object($result)) {
pierre@0 50 $ads[$ad->aid] = '';
pierre@0 51 $form['title'][$ad->aid] = array('#value' => l($ad->title, 'node/'. $ad->aid));
pierre@0 52 $form['group'][$ad->aid] = array('#value' => _ad_get_group($ad->aid));
pierre@0 53 $form['adtype'][$ad->aid] = array('#value' => t(check_plain($ad->adtype)));
pierre@0 54 $form['adstatus'][$ad->aid] = array('#value' => t(check_plain($ad->adstatus)));
pierre@0 55 $form['operations'][$ad->aid] = array('#value' => l(t('edit'), 'node/'. $ad->aid .'/edit', array('query' => $destination)));
pierre@0 56 }
pierre@0 57 $form['ads'] = array('#type' => 'checkboxes', '#options' => $ads);
pierre@0 58 $form['pager'] = array('#value' => theme('pager', NULL, 50, 0));
pierre@0 59 return $form;
pierre@0 60 }
pierre@0 61
pierre@0 62 /**
pierre@0 63 * Implementation of hook_ad_operations().
pierre@0 64 */
pierre@0 65 function ad_ad_operations() {
pierre@0 66 $operations = array(
pierre@0 67 'approved' => array(
pierre@0 68 'label' => t('Mark as approved'),
pierre@0 69 'callback' => 'ad_operations_callback',
pierre@0 70 'callback arguments' => array('approved'),
pierre@0 71 ),
pierre@0 72 'active' => array(
pierre@0 73 'label' => t('Mark as active'),
pierre@0 74 'callback' => 'ad_operations_callback',
pierre@0 75 'callback arguments' => array('active'),
pierre@0 76 ),
pierre@0 77 'expired' => array(
pierre@0 78 'label' => t('Mark as expired'),
pierre@0 79 'callback' => 'ad_operations_callback',
pierre@0 80 'callback arguments' => array('expired'),
pierre@0 81 ),
pierre@0 82 'pending' => array(
pierre@0 83 'label' => t('Mark as pending'),
pierre@0 84 'callback' => 'ad_operations_callback',
pierre@0 85 'callback arguments' => array('pending'),
pierre@0 86 ),
pierre@0 87 'offline' => array(
pierre@0 88 'label' => t('Mark as offline'),
pierre@0 89 'callback' => 'ad_operations_callback',
pierre@0 90 'callback arguments' => array('offline'),
pierre@0 91 ),
pierre@0 92 'denied' => array(
pierre@0 93 'label' => t('Mark as denied'),
pierre@0 94 'callback' => 'ad_operations_callback',
pierre@0 95 'callback arguments' => array('denied'),
pierre@0 96 ),
pierre@0 97 'delete' => array(
pierre@0 98 'label' => t('Delete'),
pierre@0 99 ),
pierre@0 100 );
pierre@0 101 return $operations;
pierre@0 102 }
pierre@0 103
pierre@0 104 /**
pierre@0 105 * Callback function for admin mass approving ads.
pierre@0 106 * TODO: Update activated and expired when appropriate.
pierre@0 107 * TODO: Publish/unpublish nodes when appropriate.
pierre@0 108 */
pierre@0 109 function ad_operations_callback($ads, $action) {
pierre@0 110 $placeholders = implode(',', array_fill(0, count($ads), '%d'));
pierre@0 111 db_query("UPDATE {ads} SET adstatus = '". $action ."' WHERE aid IN(". $placeholders .')', $ads);
pierre@0 112 foreach ($ads as $aid) {
pierre@0 113 $node = node_load($aid);
pierre@0 114 ad_statistics_increment($aid, 'update');
pierre@0 115 ad_statistics_increment($aid, $action);
pierre@0 116 // Allow ad type module to act on nodeapi events. The adapi hook provides
pierre@0 117 // access to additional variables not available in the nodeapi hook.
pierre@0 118 if (isset($node->adtype)) {
pierre@0 119 // Don't use module_invoke, as in pre-PHP5 the changes to $node won't be
pierre@0 120 // passed back.
pierre@0 121 $function = "ad_$node->adtype" .'_adapi';
pierre@0 122 if (function_exists($function)) {
pierre@0 123 $function('update', $node);
pierre@0 124 }
pierre@0 125 }
pierre@0 126 // Allow ad cache module to act on nodeapi events.
pierre@0 127 $cache = variable_get('ad_cache', 'none');
pierre@0 128 if ($cache != 'none') {
pierre@0 129 $function = "ad_cache_$cache" .'_adcacheapi';
pierre@0 130 if (function_exists($function)) {
pierre@0 131 $function($action, $node);
pierre@0 132 }
pierre@0 133 }
pierre@0 134 }
pierre@0 135 }
pierre@0 136
pierre@0 137 /**
pierre@0 138 * Display a form to confirm whether to really delete the selected ads.
pierre@0 139 */
pierre@0 140 function ad_multiple_delete_confirm($form_state) {
pierre@0 141 $form['ads'] = array('#prefix' => '<ul>', '#suffix' => '</ul>', '#tree' => TRUE);
pierre@0 142 // array_filter returns only elements with TRUE values
pierre@0 143 foreach (array_filter($form_state['post']['ads']) as $aid => $value) {
pierre@0 144 $title = db_result(db_query('SELECT title FROM {node} WHERE nid = %d', $aid));
pierre@0 145 $form['ads'][$aid] = array('#type' => 'hidden', '#value' => $aid, '#prefix' => '<li>', '#suffix' => check_plain($title) ."</li>\n");
pierre@0 146 }
pierre@0 147 $form['operation'] = array('#type' => 'hidden', '#value' => 'delete');
pierre@0 148
pierre@0 149 return confirm_form($form,
pierre@0 150 t('Are you sure you want to delete these ads?'),
pierre@0 151 'admin/content/ad', t('This action cannot be undone.'),
pierre@0 152 t('Delete all'), t('Cancel'));
pierre@0 153 }
pierre@0 154
pierre@0 155 /**
pierre@0 156 * Perform the actual ad deletions.
pierre@0 157 */
pierre@0 158 function ad_multiple_delete_confirm_submit($form, &$form_state) {
pierre@0 159 if ($form_state['values']['confirm']) {
pierre@0 160 foreach ($form_state['values']['ads'] as $aid => $value) {
pierre@0 161 node_delete($aid);
pierre@0 162 }
pierre@0 163 drupal_set_message(t('The ads have been deleted.'));
pierre@0 164 }
pierre@0 165 $form_state['redirect'] = 'admin/content/ad';
pierre@0 166 }
pierre@0 167
pierre@0 168 /**
pierre@0 169 * Theme ad administration overview.
pierre@0 170 */
pierre@0 171 function theme_ad_admin_ads($form) {
pierre@0 172 // Overview table:
pierre@0 173 $header = array(theme('table_select_header_cell'), t('Title'), t('Group'), t('Type'), t('Status'), t('Operations'));
pierre@0 174
pierre@0 175 $output = drupal_render($form['options']);
pierre@0 176 if (isset($form['title']) && is_array($form['title'])) {
pierre@0 177 foreach (element_children($form['title']) as $key) {
pierre@0 178 $row = array();
pierre@0 179 $row[] = drupal_render($form['ads'][$key]);
pierre@0 180 $row[] = drupal_render($form['title'][$key]);
pierre@0 181 $row[] = drupal_render($form['group'][$key]);
pierre@0 182 $row[] = drupal_render($form['adtype'][$key]);
pierre@0 183 $row[] = drupal_render($form['adstatus'][$key]);
pierre@0 184 $row[] = drupal_render($form['operations'][$key]);
pierre@0 185 $rows[] = $row;
pierre@0 186 }
pierre@0 187
pierre@0 188 }
pierre@0 189 else {
pierre@0 190 $rows[] = array(array('data' => t('No ads available.'), 'colspan' => '6'));
pierre@0 191 }
pierre@0 192
pierre@0 193 $output .= theme('table', $header, $rows);
pierre@0 194 if ($form['pager']['#value']) {
pierre@0 195 $output .= drupal_render($form['pager']);
pierre@0 196 }
pierre@0 197
pierre@0 198 $output .= drupal_render($form);
pierre@0 199
pierre@0 200 return $output;
pierre@0 201 }
pierre@0 202
pierre@0 203 /**
pierre@0 204 * Must select an ad if performing an operation.
pierre@0 205 */
pierre@0 206 function ad_admin_ads_validate($form, &$form_state) {
pierre@0 207 $ads = array_filter($form_state['values']['ads']);
pierre@0 208 if (count($ads) == 0) {
pierre@0 209 form_set_error('', t('No ads selected.'));
pierre@0 210 }
pierre@0 211 }
pierre@0 212
pierre@0 213 /**
pierre@0 214 * Submit the ad administration update form.
pierre@0 215 */
pierre@0 216 function ad_admin_ads_submit($form, &$form_state) {
pierre@0 217 $operations = module_invoke_all('ad_operations');
pierre@0 218 $operation = $operations[$form_state['values']['operation']];
pierre@0 219 // Filter out unchecked nodes
pierre@0 220 $ads = array_filter($form_state['values']['ads']);
pierre@0 221 if ($function = $operation['callback']) {
pierre@0 222 // Add in callback arguments if present.
pierre@0 223 if (isset($operation['callback arguments'])) {
pierre@0 224 $args = array_merge(array($ads), $operation['callback arguments']);
pierre@0 225 }
pierre@0 226 else {
pierre@0 227 $args = array($ads);
pierre@0 228 }
pierre@0 229 call_user_func_array($function, $args);
pierre@0 230
pierre@0 231 cache_clear_all();
pierre@1 232 ad_rebuild_cache(TRUE);
pierre@0 233 drupal_set_message(t('The update has been performed.'));
pierre@0 234 }
pierre@0 235 }
pierre@0 236
pierre@0 237 /**
pierre@0 238 * Build query for ad administration filters based on session.
pierre@0 239 */
pierre@0 240 function ad_build_filter_query() {
pierre@0 241 $filters = ad_filters();
pierre@0 242
pierre@0 243 // Build query
pierre@0 244 $where = $args = array();
pierre@0 245 $join = '';
pierre@0 246 foreach ($_SESSION['ad_overview_filter'] as $index => $filter) {
pierre@0 247 list($key, $value) = $filter;
pierre@0 248 switch ($key) {
pierre@0 249 case 'status':
pierre@0 250 list($value, $key) = explode('-', $value, 2);
pierre@0 251 $op = $key == 1 ? '=' : '!=';
pierre@0 252 $where[] = "a.adstatus $op '%s'";
pierre@0 253 break;
pierre@0 254 case 'group':
pierre@0 255 $table = "tn$index";
pierre@0 256 $where[] = "$table.tid = %d";
pierre@0 257 $join .= "INNER JOIN {term_node} $table ON n.nid = $table.nid ";
pierre@0 258 break;
pierre@0 259 case 'type':
pierre@0 260 $where[] = "a.adtype = '%s'";
pierre@1 261 default:
pierre@1 262 $return = module_invoke_all('adapi', 'admin_filter_query', $filter);
pierre@1 263 foreach ($return as $module => $funcs) {
pierre@1 264 if (isset($funcs['where'])) {
pierre@1 265 $where[] = $funcs['where'];
pierre@1 266 }
pierre@1 267 if (isset($funcs['join'])) {
pierre@1 268 $join .= $funcs['join'];
pierre@1 269 }
pierre@1 270 if (isset($funcs['value'])) {
pierre@1 271 $value = $funcs['value'];
pierre@1 272 }
pierre@1 273 }
pierre@1 274 break;
pierre@0 275 }
pierre@0 276 $args[] = $value;
pierre@0 277 }
pierre@0 278 $where = count($where) ? 'WHERE '. implode(' AND ', $where) : '';
pierre@0 279
pierre@0 280 return array('where' => $where, 'join' => $join, 'args' => $args);
pierre@0 281 }
pierre@0 282
pierre@0 283 /**
pierre@0 284 * List ad administration filters that can be applied.
pierre@0 285 */
pierre@0 286 function ad_filters() {
pierre@0 287 $session = &$_SESSION['ad_overview_filter'];
pierre@0 288 $session = is_array($session) ? $session : array();
pierre@0 289 // Regular filters
pierre@0 290 $options = array();
pierre@0 291 $options = array(
pierre@0 292 'pending-1' => t('pending'),
pierre@0 293 'approved-1' => t('approved'),
pierre@0 294 'active-1' => t('active'),
pierre@0 295 'offline-1' => t('offline'),
pierre@0 296 'expired-1' => t('expired'),
pierre@0 297 'denied-1' => t('denied'),
pierre@0 298 'pending-0' => t('not pending'),
pierre@0 299 'approved-0' => t('not approved'),
pierre@0 300 'active-0' => t('not active'),
pierre@0 301 'offline-0' => t('not offline'),
pierre@0 302 'expired-0' => t('not expired'),
pierre@0 303 'denied-0' => t('not denied')
pierre@0 304 );
pierre@0 305
pierre@0 306 $filters['status'] = array(
pierre@0 307 'title' => t('status'),
pierre@0 308 'options' => $options
pierre@0 309 );
pierre@0 310 $adtypes = ad_get_types();
pierre@0 311 $filters['type'] = array(
pierre@0 312 'title' => t('type'),
pierre@0 313 'options' => $adtypes,
pierre@0 314 );
pierre@0 315 // The taxonomy filter
pierre@0 316 if ($taxonomy = module_invoke('taxonomy', 'get_tree', _ad_get_vid())) {
pierre@0 317 $options = array();
pierre@0 318 // TODO: Add support for the default group.
pierre@0 319 //$options[0] = t('default');
pierre@0 320 foreach ($taxonomy as $term) {
pierre@0 321 $options[$term->tid] = check_plain($term->name);
pierre@0 322 }
pierre@0 323 $filters['group'] = array('title' => t('group'), 'options' => $options);
pierre@0 324 }
pierre@0 325
pierre@1 326 $filters = array_merge($filters, module_invoke_all('adapi', 'admin_filters', array()));
pierre@0 327 return $filters;
pierre@0 328 }
pierre@0 329
pierre@0 330 /**
pierre@0 331 * Theme ad administration filter selector.
pierre@0 332 */
pierre@0 333 function theme_ad_filters($form) {
pierre@0 334 $output = '<ul class="clear-block">';
pierre@0 335 if (isset($form['current']) && sizeof($form['current'])) {
pierre@0 336 foreach (element_children($form['current']) as $key) {
pierre@0 337 $output .= '<li>'. drupal_render($form['current'][$key]) .'</li>';
pierre@0 338 }
pierre@0 339 }
pierre@0 340
pierre@0 341 $output .= '<li><dl class="multiselect">'. (isset($form['current']) && sizeof($form['current']) ? '<dt><em>'. t('and') .'</em> '. t('where') .'</dt>' : '') .'<dd class="a">';
pierre@0 342 foreach (element_children($form['filter']) as $key) {
pierre@0 343 $output .= drupal_render($form['filter'][$key]);
pierre@0 344 }
pierre@0 345 $output .= '</dd>';
pierre@0 346
pierre@0 347 $output .= '<dt>'. t('is') .'</dt><dd class="b">';
pierre@0 348
pierre@0 349 if (isset($form['status'])) {
pierre@0 350 foreach (element_children($form['status']) as $key) {
pierre@0 351 $output .= drupal_render($form['status'][$key]);
pierre@0 352 }
pierre@0 353 }
pierre@0 354 $output .= '</dd>';
pierre@0 355
pierre@0 356 $output .= '</dl>';
pierre@0 357 $output .= '<div class="container-inline" id="ad-admin-buttons">'. drupal_render($form['buttons']) .'</div>';
pierre@0 358 $output .= '</li></ul>';
pierre@0 359
pierre@0 360 return $output;
pierre@0 361 }
pierre@0 362
pierre@0 363 /**
pierre@0 364 * Return form for advertisement administration filters.
pierre@0 365 */
pierre@0 366 function ad_filter_form($form_state) {
pierre@0 367 $session = &$_SESSION['ad_overview_filter'];
pierre@0 368 $session = is_array($session) ? $session : array();
pierre@0 369 $filters = ad_filters();
pierre@0 370
pierre@0 371 $i = 0;
pierre@0 372 $form['filters'] = array('#type' => 'fieldset',
pierre@0 373 '#title' => t('Show only ads where'),
pierre@0 374 '#theme' => 'ad_filters',
pierre@0 375 );
pierre@0 376 foreach ($session as $filter) {
pierre@0 377 list($type, $value) = $filter;
pierre@0 378 if ($type == 'category') {
pierre@0 379 // Load term name from DB rather than search and parse options array.
pierre@0 380 $value = module_invoke('taxonomy', 'get_term', $value);
pierre@0 381 $value = $value->name;
pierre@0 382 }
pierre@0 383 else if ($type == 'status') {
pierre@0 384 $value = $filters['status']['options'][$value];
pierre@0 385 }
pierre@0 386 else {
pierre@0 387 $value = $filters[$type]['options'][$value];
pierre@0 388 }
pierre@0 389 $string = ($i++ ? '<em>and</em> where <strong>%a</strong> is <strong>%b</strong>' : '<strong>%a</strong> is <strong>%b</strong>');
pierre@0 390 $form['filters']['current'][] = array('#value' => t($string, array('%a' => $filters[$type]['title'] , '%b' => $value)));
pierre@0 391 if ($type == 'type') {
pierre@0 392 // Remove the type option if it is already being filtered on.
pierre@0 393 unset($filters['type']);
pierre@0 394 }
pierre@0 395 else if ($type == 'group') {
pierre@0 396 unset($filters['group']);
pierre@0 397 }
pierre@0 398 if ($type == 'status') {
pierre@0 399 foreach ($session as $option) {
pierre@0 400 if ($option[0] == 'status') {
pierre@0 401 list($value, $key) = explode('-', $option[1], 2);
pierre@0 402 if ($key) {
pierre@0 403 // One postive key means we can't have any more.
pierre@0 404 // Remove the status option if we're already filtering on a positive
pierre@0 405 // key (ie, 'active', as an ad can't be 'active' and 'pending')
pierre@0 406 unset($filters['status']);
pierre@0 407 }
pierre@0 408 else {
pierre@0 409 // When a key is selected, remove it and its inverse as there's
pierre@0 410 // no logic in selecting the same key multiple times, and selecting
pierre@0 411 // two opposite keys will always return 0 results.
pierre@0 412 $inverse = $key == 1 ? 0 : 1;
pierre@0 413 unset($filters['status']['options'][$option[1]]);
pierre@0 414 unset($filters['status']['options'][$value .'-'. $inverse]);
pierre@0 415 }
pierre@0 416 }
pierre@0 417 }
pierre@0 418 }
pierre@0 419 }
pierre@0 420
pierre@0 421 $names = array();
pierre@0 422 foreach ($filters as $key => $filter) {
pierre@0 423 $names[$key] = $filter['title'];
pierre@0 424 $form['filters']['status'][$key] = array('#type' => 'select', '#options' => $filter['options']);
pierre@0 425 }
pierre@0 426
pierre@0 427 $form['filters']['filter'] = array('#type' => 'radios', '#options' => $names, '#default_value' => 'status');
pierre@0 428 $form['filters']['buttons']['submit'] = array('#type' => 'submit', '#value' => (count($session) ? t('Refine') : t('Filter')));
pierre@0 429 if (count($session)) {
pierre@0 430 $form['filters']['buttons']['undo'] = array('#type' => 'submit', '#value' => t('Undo'));
pierre@0 431 $form['filters']['buttons']['reset'] = array('#type' => 'submit', '#value' => t('Reset'));
pierre@0 432 }
pierre@0 433
pierre@0 434 return $form;
pierre@0 435 }
pierre@0 436
pierre@0 437 /**
pierre@0 438 * Theme ad administration filter form.
pierre@0 439 */
pierre@0 440 function theme_ad_filter_form($form) {
pierre@0 441 $output = '<div id="ad-admin-filter">';
pierre@0 442 $output .= drupal_render($form['filters']);
pierre@0 443 $output .= '</div>';
pierre@0 444 $output .= drupal_render($form);
pierre@0 445 return $output;
pierre@0 446 }
pierre@0 447
pierre@0 448 /**
pierre@0 449 * Process result from ad administration filter form.
pierre@0 450 */
pierre@0 451 function ad_filter_form_submit($form, &$form_state) {
pierre@0 452 $filters = ad_filters();
pierre@0 453 /* TODO The 'op' element in the form values is deprecated.
pierre@0 454 Each button can have #validate and #submit functions associated with it.
pierre@0 455 Thus, there should be one button that submits the form and which invokes
pierre@0 456 the normal form_id_validate and form_id_submit handlers. Any additional
pierre@0 457 buttons which need to invoke different validate or submit functionality
pierre@0 458 should have button-specific functions. */
pierre@0 459 switch ($form_state['values']['op']) {
pierre@0 460 case t('Filter'):
pierre@0 461 case t('Refine'):
pierre@0 462 if (isset($form_state['values']['filter'])) {
pierre@0 463 $filter = $form_state['values']['filter'];
pierre@0 464
pierre@0 465 // Flatten the options array to accommodate hierarchical/nested options.
pierre@0 466 $flat_options = form_options_flatten($filters[$filter]['options']);
pierre@0 467
pierre@0 468 if (isset($form_state['values'][$filter]) && isset($flat_options[$form_state['values'][$filter]])) {
pierre@0 469 $_SESSION['ad_overview_filter'][] = array($filter, $form_state['values'][$filter]);
pierre@0 470 }
pierre@0 471 }
pierre@0 472 break;
pierre@0 473 case t('Undo'):
pierre@0 474 array_pop($_SESSION['ad_overview_filter']);
pierre@0 475 break;
pierre@0 476 case t('Reset'):
pierre@0 477 $_SESSION['ad_overview_filter'] = array();
pierre@0 478 break;
pierre@0 479 }
pierre@0 480 }
pierre@0 481
pierre@0 482 /**
pierre@0 483 * Display a form for the ad module settings.
pierre@0 484 */
pierre@0 485 function ad_admin_configure_settings($form_state) {
pierre@0 486 _ad_check_installation();
pierre@0 487
pierre@0 488 $adserve = variable_get('adserve', '');
pierre@0 489 $adserveinc = variable_get('adserveinc', '');
pierre@0 490 $form['configuration'] = array(
pierre@0 491 '#type' => 'fieldset',
pierre@0 492 '#title' => t('Status'),
pierre@0 493 );
pierre@0 494 $form['configuration']['adserve'] = array(
pierre@0 495 '#type' => 'markup',
pierre@0 496 '#value' => t('Using detected adserve scripts: %adserve, %adserveinc', array('%adserve' => ($adserve ? $adserve : t('not found')), '%adserveinc' => ($adserveinc ? $adserveinc : t('not found')))),
pierre@0 497 );
pierre@0 498
pierre@0 499 $form['general'] = array(
pierre@0 500 '#type' => 'fieldset',
pierre@0 501 '#title' => t('General'),
pierre@0 502 '#collapsible' => TRUE,
pierre@0 503 '#collapsed' => FALSE,
pierre@0 504 );
pierre@0 505
pierre@0 506 // TODO: This needs a per-group over-ride, in case some groups are IFrames,
pierre@0 507 // while others are JavaScript, etc.
pierre@0 508 $form['general']['ad_link_target'] = array(
pierre@0 509 '#type' => 'radios',
pierre@0 510 '#title' => t('Click-through target'),
pierre@0 511 '#options' => array(
pierre@0 512 '_self' => t('same browser window and frame'),
pierre@0 513 '_blank' => t('new browser window'),
pierre@0 514 '_parent' => t('parent frame'),
pierre@0 515 '_top' => t('same browser window, removing all frames'),
pierre@0 516 ),
pierre@0 517 '#default_value' => variable_get('ad_link_target', '_self'),
pierre@0 518 '#description' => t('Select an option above to configure what happens when an ad is clicked. These options set the <em>a target</em>, and are <em>_self</em>, <em>_blank</em>, <em>_parent</em> and <em>_top</em> respectively.'),
pierre@0 519 );
pierre@0 520
pierre@0 521 $form['general']['ad_link_nofollow'] = array(
pierre@0 522 '#type' => 'checkbox',
pierre@0 523 '#title' => t('nofollow'),
pierre@0 524 '#default_value' => variable_get('ad_link_nofollow', 0),
pierre@0 525 '#description' => t('If enabled, %tag will be added to advertisement links generated by this module.', array('%tag' => t('rel="nofollow"'))),
pierre@0 526 );
pierre@0 527
pierre@0 528 // Provide hook for ad_display_TYPE modules to set display TYPE.
pierre@0 529 $display_options = array_merge(array('javascript' => t('JavaScript'), 'jquery' => t('jQuery'), 'iframe' => t('IFrame'), 'raw' => t('Raw')), module_invoke_all('displayapi', 'display_method'), array());
pierre@0 530
pierre@0 531 // Provide hook for ad_display_TYPE modules to define inline description.
pierre@0 532 $description = t('This setting configures the default method for displaying advertisements on your website. It is possible to override this setting when making direct calls to ad(), as described in the documentation. Using the JavaScript, jQuery, and IFrame display methods allows you to display random ads and track impressions even on cached pages. When using the Raw display method together with Drupal\'s page cache, impressions will be properly tracked but advertisements will only change when the page cache is updated.');
pierre@0 533 $return = module_invoke_all('displayapi', 'display_description', array());
pierre@0 534 foreach ($return as $describe) {
pierre@0 535 $description .= ' '. $describe;
pierre@0 536 }
pierre@0 537
pierre@0 538 $form['general']['ad_display'] = array(
pierre@0 539 '#type' => 'radios',
pierre@0 540 '#title' => t('Display type'),
pierre@0 541 '#default_value' => variable_get('ad_display', 'javascript'),
pierre@0 542 '#options' => $display_options,
pierre@0 543 '#description' => $description,
pierre@0 544 );
pierre@0 545
pierre@0 546 $form['general']['ad_validate_url'] = array(
pierre@0 547 '#type' => 'checkbox',
pierre@0 548 '#title' => t('Validate URLs'),
pierre@0 549 '#default_value' => variable_get('ad_validate_url', 1),
pierre@0 550 '#description' => t('If enabled, any destination URLs entered in ads will be required to be complete URLs (including http:// or https:// at the beginning). If you wish to include internal urls, you will need to disable this option.'),
pierre@0 551 );
pierre@0 552
pierre@0 553 $form['iframe'] = array(
pierre@0 554 '#type' => 'fieldset',
pierre@0 555 '#title' => t('IFrame'),
pierre@0 556 '#collapsible' => TRUE,
pierre@0 557 '#collapsed' => variable_get('ad_display', 'javascript') == 'iframe' ? FALSE : TRUE
pierre@0 558 );
pierre@0 559 $form['iframe']['ad_iframe_frameborder'] = array(
pierre@0 560 '#type' => 'checkbox',
pierre@0 561 '#title' => t('Frameborder'),
pierre@0 562 '#default_value' => variable_get('ad_iframe_frameborder', 0),
pierre@0 563 '#description' => t('If enabled, IFrames used for displaying ads will have a frameborder.'),
pierre@0 564 );
pierre@0 565 $form['iframe']['ad_iframe_scroll'] = array(
pierre@0 566 '#type' => 'radios',
pierre@0 567 '#title' => t('Scrolling'),
pierre@0 568 '#default_value' => variable_get('ad_iframe_scroll', 'auto'),
pierre@0 569 '#options' => array('auto' => 'auto', 'on' => 'on', 'off' => 'off'),
pierre@0 570 '#description' => t('Define whether or not scroll bars should be enabled for the ad IFrame.'),
pierre@0 571 );
pierre@0 572 $form['iframe']['ad_iframe_width'] = array(
pierre@0 573 '#type' => 'textfield',
pierre@0 574 '#title' => t('Width'),
pierre@0 575 '#default_value' => variable_get('ad_iframe_width', ''),
pierre@0 576 '#maxlength' => 8,
pierre@0 577 '#size' => 5,
pierre@0 578 '#required' => FALSE,
pierre@0 579 '#description' => t('The default width for advertisement IFrames'),
pierre@0 580 );
pierre@0 581 $form['iframe']['ad_iframe_height'] = array(
pierre@0 582 '#type' => 'textfield',
pierre@0 583 '#title' => t('Height'),
pierre@0 584 '#default_value' => variable_get('ad_iframe_height', ''),
pierre@0 585 '#maxlength' => 8,
pierre@0 586 '#size' => 5,
pierre@0 587 '#required' => FALSE,
pierre@0 588 '#description' => t('The default height for advertisement IFrames'),
pierre@0 589 );
pierre@0 590
pierre@0 591 $form['cache'] = array(
pierre@0 592 '#type' => 'fieldset',
pierre@0 593 '#title' => t('Cache'),
pierre@0 594 '#collapsible' => TRUE,
pierre@0 595 '#collapsed' => variable_get('ad_cache', 'none') == 'none' ? TRUE : FALSE,
pierre@0 596 );
pierre@0 597
pierre@0 598 // Provide hook for ad_cache_TYPE modules to set cache TYPE.
pierre@0 599 $cache_options = array_merge(array('none' => t('None')), module_invoke_all('adcacheapi', 'method', array()));
pierre@0 600
pierre@0 601 // Provide hook for ad_cache_TYPE modules to define inline description.
pierre@0 602 $description = t('A cache can be used to efficiently track how many times advertisements are displayed and clicked.');
pierre@0 603 $return = module_invoke_all('adcacheapi', 'description', array());
pierre@0 604 foreach ($return as $describe) {
pierre@0 605 $description .= ' '. $describe;
pierre@0 606 }
pierre@0 607
pierre@0 608 $form['cache']['ad_cache'] = array(
pierre@0 609 '#type' => 'radios',
pierre@0 610 '#title' => t('Type'),
pierre@0 611 '#default_value' => variable_get('ad_cache', 'none'),
pierre@0 612 '#options' => $cache_options,
pierre@0 613 '#description' => $description,
pierre@0 614 );
pierre@0 615
pierre@0 616 // Provide hook for ad_cache_TYPE modules to add inline settings.
pierre@0 617 $form['cache'] = array_merge($form['cache'], module_invoke_all('adcacheapi', 'settings'));
pierre@0 618
pierre@0 619 $form['save'] = array(
pierre@0 620 '#type' => 'submit',
pierre@0 621 '#value' => t('Save'),
pierre@0 622 );
pierre@0 623
pierre@0 624 return $form;
pierre@0 625 }
pierre@0 626
pierre@0 627 /**
pierre@0 628 * Validate form settings, calling attention to any illogical configurations.
pierre@0 629 */
pierre@0 630 function ad_admin_configure_settings_validate($form, &$form_state) {
pierre@0 631 if ($form_state['values']['ad_link_target'] == '_self' &&
pierre@0 632 $form_state['values']['ad_display'] == 'iframe') {
pierre@0 633 // We don't consider this an error, as this could be exactly what the
pierre@0 634 // administrator is trying to do. But as for most people it is likely
pierre@0 635 // to be a misconfiguration, display a helpful warning...
pierre@0 636 drupal_set_message(t('You have configured your advertisements to be displayed in iframes, and you have configured your click-through target as "same browser window and frame". This is an unusual configuration, as when you click your advertisements only the IFrame will be redirected. Be sure that this is actually what you are trying to do.'));
pierre@0 637 }
pierre@0 638 }
pierre@0 639
pierre@0 640 /**
pierre@0 641 * Save updated values from settings form.
pierre@0 642 */
pierre@0 643 function ad_admin_configure_settings_submit($form, &$form_state) {
pierre@0 644 variable_set('ad_link_target', $form_state['values']['ad_link_target']);
pierre@0 645 variable_set('ad_link_nofollow', $form_state['values']['ad_link_nofollow']);
pierre@0 646 variable_set('ad_cache', $form_state['values']['ad_cache']);
pierre@0 647 variable_set('ad_display', $form_state['values']['ad_display']);
pierre@0 648 variable_set('ad_validate_url', $form_state['values']['ad_validate_url']);
pierre@0 649 variable_set('ad_iframe_frameborder', $form_state['values']['ad_iframe_frameborder']);
pierre@0 650 variable_set('ad_iframe_scroll', $form_state['values']['ad_iframe_scroll']);
pierre@0 651 variable_set('ad_iframe_width', $form_state['values']['ad_iframe_width']);
pierre@0 652 variable_set('ad_iframe_height', $form_state['values']['ad_iframe_height']);
pierre@0 653 if (($cache = variable_get('ad_cache', 'none')) != 'none') {
pierre@0 654 // Allow external cache types to store their settings
pierre@0 655 module_invoke('ad_cache_'. $cache, 'adcacheapi', 'settings_submit', $form_state['values']);
pierre@0 656 }
pierre@0 657 /*
pierre@0 658 // TODO: Write an external display module and implement this.
pierre@0 659 $display = variable_get('ad_display', 'javascript');
pierre@0 660 if ($display != 'javascript' && $display != 'raw') {
pierre@0 661 // Allow external display types to store their settings
pierre@0 662 module_invoke('ad_cache_'. $cache, 'adcacheapi', 'settings_submit', $form_state['values']);
pierre@0 663 }*/
pierre@0 664 }
pierre@0 665
pierre@0 666 /**
pierre@0 667 * Empty page for ad_type modules that don't define a global settings page.
pierre@0 668 * This way admins can still set default permissions for this ad type.
pierre@0 669 */
pierre@0 670 function ad_no_global_settings($form_state) {
pierre@0 671 $form = array();
pierre@0 672
pierre@0 673 $form['save'] = array(
pierre@0 674 '#type' => 'submit',
pierre@0 675 '#value' => t('Save'),
pierre@0 676 );
pierre@0 677
pierre@0 678 return $form;
pierre@0 679 }
pierre@0 680
pierre@0 681 function ad_admin_groups_list() {
pierre@0 682 _ad_check_installation();
pierre@0 683
pierre@0 684 $header = array(
pierre@0 685 array('data' => t('Name'), 'field' => 'name'),
pierre@0 686 array('data' => t('Description'), 'field' => 'description'),
pierre@0 687 array('data' => t('Options')),
pierre@0 688 );
pierre@0 689
pierre@0 690 $groups = taxonomy_get_tree(_ad_get_vid());
pierre@0 691
pierre@0 692 if ($groups != array()) {
pierre@0 693 foreach ($groups as $group) {
pierre@0 694 $row = array();
pierre@0 695 $row[] = check_plain($group->name);
pierre@0 696 $row[] = check_plain($group->description);
pierre@0 697 $row[] = l(t('edit'), "admin/content/ad/groups/$group->tid/edit");
pierre@0 698 $rows[] = $row;
pierre@0 699 }
pierre@0 700 }
pierre@0 701 else {
pierre@0 702 $rows[] = array(array('data' => t('No groups have been created.'), 'colspan' => 3));
pierre@0 703 }
pierre@0 704
pierre@0 705 $output = theme('table', $header, $rows);
pierre@0 706 $output .= theme('pager', NULL, 15, 0);
pierre@0 707
pierre@0 708 return $output;
pierre@0 709 }
pierre@0 710
pierre@0 711 /**
pierre@0 712 * Returns a form for adding an ad group.
pierre@0 713 */
pierre@0 714 function ad_admin_group_form($form_state, $group = NULL) {
pierre@0 715 $form['name'] = array(
pierre@0 716 '#type' => 'textfield',
pierre@0 717 '#title' => t('Group name'),
pierre@0 718 '#default_value' => isset($group->name) ? check_plain($group->name) : '',
pierre@0 719 '#maxlength' => 64,
pierre@0 720 '#required' => TRUE,
pierre@0 721 '#description' => t('Specify a name for the ad group.')
pierre@0 722 );
pierre@0 723
pierre@0 724 $form['description'] = array(
pierre@0 725 '#type' => 'textarea',
pierre@0 726 '#title' => t('Description'),
pierre@0 727 '#default_value' => isset($group->description) ? check_plain($group->description) : '',
pierre@0 728 '#required' => TRUE,
pierre@0 729 '#description' => t('Describe this ad group.')
pierre@0 730 );
pierre@0 731
pierre@0 732 $form['weight'] = array(
pierre@0 733 '#type' => 'weight',
pierre@0 734 '#title' => t('Weight'),
pierre@0 735 '#default_value' => isset($group->weight) ? $group->weight : 0,
pierre@0 736 '#description' => t('When listing ad groups, those with lighter (smaller) weights get listed before ad groups with heavier (larger) weights. Ad groups with equal weights are sorted alphabetically.')
pierre@0 737 );
pierre@0 738
pierre@0 739 $form['vid'] = array(
pierre@0 740 '#type' => 'hidden',
pierre@0 741 '#value' => _ad_get_vid(),
pierre@0 742 );
pierre@0 743
pierre@0 744
pierre@0 745 if (isset($group->tid)) {
pierre@0 746 $form['submit'] = array(
pierre@0 747 '#type' => 'submit',
pierre@0 748 '#value' => t('Save'),
pierre@0 749 );
pierre@0 750 $form['delete'] = array(
pierre@0 751 '#type' => 'submit',
pierre@0 752 '#value' => t('Delete'),
pierre@0 753 );
pierre@0 754 $form['tid'] = array(
pierre@0 755 '#type' => 'value',
pierre@0 756 '#value' => $group->tid
pierre@0 757 );
pierre@0 758 }
pierre@0 759 else {
pierre@0 760 $form['submit'] = array(
pierre@0 761 '#type' => 'submit',
pierre@0 762 '#value' => t('Create group'),
pierre@0 763 );
pierre@0 764 }
pierre@0 765
pierre@0 766 return $form;
pierre@0 767 }
pierre@0 768
pierre@0 769 /**
pierre@0 770 * Save a newly created ad group.
pierre@0 771 */
pierre@0 772 function ad_admin_group_form_validate($form, &$form_state) {
pierre@0 773 if ($form_state['values']['op'] == t('Delete')) {
pierre@0 774 drupal_goto('admin/content/ad/groups/'. $form_state['values']['tid'] .'/delete');
pierre@0 775 }
pierre@0 776 }
pierre@0 777
pierre@0 778
pierre@0 779 /**
pierre@0 780 * Save a newly created ad group.
pierre@0 781 */
pierre@0 782 function ad_admin_group_form_submit($form, &$form_state) {
pierre@0 783 $status = taxonomy_save_term($form_state['values']);
pierre@0 784 switch ($status) {
pierre@0 785 case SAVED_NEW:
pierre@0 786 $groups = variable_get('ad_groups', array());
pierre@0 787 $groups[] = $form_state['values']['tid'];
pierre@0 788 variable_set('ad_groups', $groups);
pierre@0 789 drupal_set_message(t('Created new ad group %term.', array('%term' => $form_state['values']['name'])));
pierre@0 790 break;
pierre@0 791 case SAVED_UPDATED:
pierre@0 792 drupal_set_message(t('The ad group %term has been updated.', array('%term' => $form_state['values']['name'])));
pierre@0 793 }
pierre@0 794 $form_state['redirect'] = 'admin/content/ad/groups';
pierre@0 795 }
pierre@0 796
pierre@0 797 /**
pierre@0 798 * Returns a confirmation page when deleting an ad group and all of its ads.
pierre@0 799 */
pierre@0 800 function ad_confirm_group_delete($form_state, $group = NULL) {
pierre@0 801 $form['tid'] = array(
pierre@0 802 '#type' => 'value',
pierre@0 803 '#value' => $group->tid,
pierre@0 804 );
pierre@0 805 $form['name'] = array(
pierre@0 806 '#type' => 'value',
pierre@0 807 '#value' => check_plain($group->name),
pierre@0 808 );
pierre@0 809
pierre@0 810 return confirm_form(
pierre@0 811 $form,
pierre@0 812 t('Are you sure you want to delete the ad group %name?', array('%name' => $group->name)),
pierre@0 813 'admin/content/ad/groups',
pierre@0 814 t('Ads that were within this group will not be deleted. This action cannot be undone.'),
pierre@0 815 t('Delete'),
pierre@0 816 t('Cancel'));
pierre@0 817 }
pierre@0 818
pierre@0 819 /**
pierre@0 820 * Delete ad group.
pierre@0 821 */
pierre@0 822 function ad_confirm_group_delete_submit($form, &$form_state) {
pierre@0 823 taxonomy_del_term($form_state['values']['tid']);
pierre@0 824 drupal_set_message(t('The ad group %term has been deleted.', array('%term' => $form_state['values']['name'])));
pierre@0 825 watchdog('ad', 'mailarchive: deleted %term ad group.', array('%term' => $form_state['values']['name']));
pierre@0 826
pierre@0 827 $form_state['redirect'] = 'admin/content/ad/groups';
pierre@0 828 }
pierre@0 829