/[drupal]/contributions/modules/ad_geoip/ad_geoip.module
ViewVC logotype

Contents of /contributions/modules/ad_geoip/ad_geoip.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.3 - (show annotations) (download) (as text)
Sat Jun 28 00:24:04 2008 UTC (16 months, 4 weeks ago) by jeremy
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +23 -7 lines
File MIME type: text/x-php
 - ad_geoip.module
    o initial test definition of adapi() 'adserve_select' hook
    o code cleanup, make current ad_geoip_update_iso3166() usage default
1 <?php
2 // $Id: ad_geoip.module,v 1.2 2008/06/12 00:34:30 jeremy Exp $
3
4 /**
5 * @file
6 * Integrates Drupal's ad module with the MaxMind GeoIP database, providing
7 * GeoTargeting of advertisements.
8 *
9 * Sponsored by Pricescope.com.
10 *
11 * Copyright (c) 2008.
12 * Jeremy Andrews <jeremy@kerneltrap.org>. All rights reserved.
13 */
14
15 /**
16 * Implementation of hook_requirements. Be sure that the geoip package is
17 * properly installed.
18 */
19 function ad_geoip_requirements($phase) {
20 if (function_exists('geoip_db_get_all_info')) {
21 $versions = array();
22 // We currently support the following MaxMind databases:
23 foreach (array(
24 GEOIP_COUNTRY_EDITION => ' GeoIP Country Edition',
25 GEOIP_CITY_EDITION_REV0 => ' GeoIP City Edition, Rev 0',
26 GEOIP_CITY_EDITION_REV1 => ' GeoIP City Edition, Rev 1',
27 GEOIP_REGION_EDITION_REV0 => ' GeoIP Region Edition, Rev 0',
28 GEOIP_REGION_EDITION_REV1 => ' GeoIP Region Edition, Rev 1'
29 ) as $edition => $name) {
30 if (geoip_db_avail($edition)) {
31 $version = geoip_database_info($edition);
32 if ($version) {
33 $version = split(' ', $version);
34 $versions[] = $version[0] .' '. $version[1] . $name;
35 }
36 }
37 }
38 if (!empty($versions)) {
39 $severity = REQUIREMENT_OK;
40 $message = implode('; ', $versions);
41 }
42 else {
43 $severity = REQUIREMENT_ERROR;
44 $message = t('No valid GeoIP database installed.');
45 }
46 }
47 else {
48 $severity = REQUIREMENT_ERROR;
49 $message = t('Required !extension version 1.0.1 or greater not installed.', array('!extension' => l(t('GeoIP extension'), 'http://pecl.php.net/package/geoip')));
50 }
51
52 return array(
53 'geoip' => array(
54 'title' => t('GeoIP'),
55 'value' => $message,
56 'severity' => $severity,
57 ),
58 );
59 }
60
61 /**
62 * Drupal hook_form_alter() implementation.
63 */
64 function ad_geoip_form_alter($form_id, &$form) {
65 if ($form_id == 'ad_node_form') {
66 $form['geoip'] = array(
67 '#type' => 'fieldset',
68 '#title' => t('GeoTargeting'),
69 '#collapsible' => TRUE,
70 );
71
72 if (is_object($form['#node'])) {
73 $node = $form['#node'];
74 }
75 $geoip_format = isset($node->geoip_format) ? $node->geoip_format : 0;
76 $geoip_codes = isset($node->geoip_codes) ? $node->geoip_codes : array();
77
78 $formats = array(
79 0 => t('all visitors'),
80 1 => t('visitors from the countries selected below'),
81 2 => t('visitors not from the countries selected below'),
82 );
83 $form['geoip']['geoip_format'] = array(
84 '#type' => 'radios',
85 '#title' => t('Display advertisements to'),
86 '#options' => $formats,
87 '#default_value' => $geoip_format,
88 );
89
90 $form['geoip']['geoip_codes'] = array(
91 '#type' => 'select',
92 '#options' => ad_geoip_countries(),
93 '#multiple' => TRUE,
94 '#default_value' => $geoip_codes,
95 '#description' => t('If you select <em>all visitors</em> above, or you do not select any countries from this list, your advertisement will be displayed to all visitors.'),
96 '#prefix' => '<div>',
97 '#suffix' => '</div>',
98 );
99 }
100 }
101
102 /**
103 * Drupal hook_nodeapi implementation. Save advertisement geotargeting
104 * configuration.
105 */
106 function ad_geoip_nodeapi(&$node, $op, $teaser, $page) {
107 // TODO: Node versioning support.
108 switch ($op) {
109 case 'load':
110 $result = db_query('SELECT code, format FROM {ad_geoip_ads} WHERE aid = %d', $node->nid);
111 while ($code = db_fetch_object($result)) {
112 $geoip_codes[] = $code->code;
113 $format = $code->format;
114 }
115 if (isset($format)) {
116 $ad['geoip_codes'] = $geoip_codes;
117 $ad['geoip_format'] = $format;
118 return $ad;
119 }
120 break;
121
122 case 'update':
123 db_query('DELETE FROM {ad_geoip_ads} WHERE aid = %d', $node->nid);
124 // fall through and insert updated geoip information...
125 case 'insert':
126 if (is_array($node->geoip_codes)) {
127 foreach($node->geoip_codes as $code) {
128 db_query("INSERT INTO {ad_geoip_ads} (aid, code, format) VALUES(%d, '%s', %d)", $node->nid, $code, $node->geoip_format);
129 }
130 }
131 break;
132
133 case 'delete':
134 db_query('DELETE FROM {ad_geoip_ads} WHERE aid = %d', $node->nid);
135 break;
136 }
137 }
138
139 /**
140 * Define ad mdule hook_adapi().
141 */
142 function ad_geoip_adapi($op, &$node) {
143 switch ($op) {
144 case 'adserve_select':
145 return array(
146 'geoip' => array(
147 'function' => 'ad_geoip_adserve',
148 'path' => drupal_get_path('module', 'ad_geoip') .'/ad_geoip.inc',
149 'weight' => -10,
150 ),
151 );
152 }
153 }
154
155 /**
156 * Return an array of countries indexed on their country code.
157 */
158 function ad_geoip_countries() {
159 static $codes = array();
160
161 if (empty($codes)) {
162 // Automatically update our ISO country codes every 30 days.
163 if ((int)variable_get('ad_geoip_iso3166', '') <= (86400 * 30)) {
164 ad_geoip_update_iso3166();
165 }
166
167 $result = db_query('SELECT code, country FROM {ad_geoip_codes}');
168 while ($code = db_fetch_object($result)) {
169 $codes[$code->code] = decode_entities($code->country);
170 }
171 }
172
173 return $codes;
174 }
175
176 /**
177 * Download the latest ISO3166 list of country codes.
178 */
179 function ad_geoip_update_iso3166($verbose = FALSE) {
180 // url for latest iso3166 list of two-character country codes.
181 $url = 'http://www.iso.org/iso/iso3166_en_code_lists.txt';
182 // load list into an array.
183 $codes = file($url);
184
185 if (is_array($codes) && !empty($codes)) {
186 $checksum = md5(implode(' ', $codes));
187 if ($checksum != variable_get('ad_geoip_iso3166_checksum', '')) {
188 // We expect the second line of the file to be essentially empty. If not,
189 // the format has changed.
190 if (strlen($codes[1] < 5)) {
191 db_query('TRUNCATE {ad_geoip_codes}');
192 $line = 2;
193 while (!empty($codes[$line])) {
194 list($country, $code) = split(';', $codes[$line++]);
195 $country = check_plain(utf8_encode(ucwords(strtolower($country))));
196 // Manual capitalization cleanup.
197 $country = strtr($country, array(' And ' => ' and ', ' Of' => ' of', '(keeling)' => '(Keeling)', '(malvinas)' => '(Malvinas)', '(vatican' => '(Vatican', 'U.s.' => 'U.S.'));
198 $code = trim($code);
199 if (strlen($code) != 2) {
200 if ($verbose) drupal_set_message(t('ISO3166 import error: invalid country code %code for country %country.', array('%code' => $code, '%country' => $country)), 'error');
201 }
202 else {
203 db_query("INSERT INTO {ad_geoip_codes} (code, country) VALUES('%s', '%s')", $code, $country);
204 }
205 }
206 if ($verbose) drupal_set_message('Your ISO3166 country codes have been updated.');
207 // Store checksum to prevent reloading data if unchanged.
208 variable_set('ad_geoip_iso3166_updated', time());
209 variable_set('ad_geoip_iso3166_checksum', $checksum);
210 }
211 else {
212 if ($verbose) drupal_set_message(t('The format of the file at !url has changed. Check to see if there has been a !release of the Ad GeoIP module.', array('!url' => l($url, $url), '!release' => l(t('new release'), 'http://drupal.org/project/ad_geoip'))));
213 }
214 }
215 }
216 else {
217 if ($verbose) drupal_set_message(t('Failed to retrieve country codes from !url.', array('!url' => l($url, $url))), 'error');
218 }
219 }

  ViewVC Help
Powered by ViewVC 1.1.2