Index: trunk/extensions/CentralNotice/special/SpecialBannerListLoader.php |
— | — | @@ -1,6 +1,7 @@ |
2 | 2 | <?php |
3 | 3 | |
4 | 4 | /** |
| 5 | + * Note: This file is deprecated and should be deleted if the new banner loading system works better. |
5 | 6 | * Generates JSON files listing all the banners for a particular site |
6 | 7 | */ |
7 | 8 | class SpecialBannerListLoader extends UnlistedSpecialPage { |
Index: trunk/extensions/CentralNotice/special/SpecialBannerController.php |
— | — | @@ -4,8 +4,8 @@ |
5 | 5 | * Generates Javascript file which controls banner selection on the client side |
6 | 6 | */ |
7 | 7 | class SpecialBannerController extends UnlistedSpecialPage { |
8 | | - protected $sharedMaxAge = 3600; // Cache for 1 hour on the server side |
9 | | - protected $maxAge = 3600; // Cache for 1 hour on the client side |
| 8 | + protected $sharedMaxAge = 300; // Cache for 5 minutes on the server side |
| 9 | + protected $maxAge = 300; // Cache for 5 minutes on the client side |
10 | 10 | |
11 | 11 | function __construct() { |
12 | 12 | // Register special page |
— | — | @@ -19,16 +19,11 @@ |
20 | 20 | $this->sendHeaders(); |
21 | 21 | |
22 | 22 | $content = $this->getOutput(); |
23 | | - if ( strlen( $content ) == 0 ) { |
24 | | - // Hack for IE/Mac 0-length keepalive problem, see RawPage.php |
25 | | - echo "/* Empty */"; |
26 | | - } else { |
27 | | - echo $content; |
28 | | - } |
| 23 | + echo $content; |
29 | 24 | } |
30 | 25 | |
31 | 26 | /** |
32 | | - * Generate the HTTP response headers for the banner controller |
| 27 | + * Generate the HTTP response headers |
33 | 28 | */ |
34 | 29 | function sendHeaders() { |
35 | 30 | global $wgJsMimeType; |
— | — | @@ -45,7 +40,7 @@ |
46 | 41 | function getOutput() { |
47 | 42 | global $wgCentralPagePath, $wgContLang; |
48 | 43 | |
49 | | - $js = $this->getScriptFunctions() . $this->getToggleScripts(); |
| 44 | + $js = $this->getAllBannerLists() . $this->getScriptFunctions() . $this->getToggleScripts(); |
50 | 45 | $js .= <<<JAVASCRIPT |
51 | 46 | ( function( $ ) { |
52 | 47 | $.ajaxSetup({ cache: true }); |
— | — | @@ -81,22 +76,12 @@ |
82 | 77 | } else { |
83 | 78 | var geoLocation = Geo.country; // pull the geo info |
84 | 79 | } |
85 | | - var bannerListQuery = $.param( { 'language': wgContentLanguage, 'project': wgNoticeProject, 'country': geoLocation } ); |
86 | | -JAVASCRIPT; |
87 | | - $js .= "\n\t\t\t\tvar bannerListURL = wgScript + '?title=' + encodeURIComponent('" . |
88 | | - $wgContLang->specialPage( 'BannerListLoader' ) . |
89 | | - "') + '&cache=/cn.js&' + bannerListQuery;\n"; |
90 | | - $js .= <<<JAVASCRIPT |
91 | | - var request = $.ajax( { |
92 | | - url: bannerListURL, |
93 | | - dataType: 'json', |
94 | | - success: $.centralNotice.fn.chooseBanner |
95 | | - } ); |
| 80 | + var bannerList = $.parseJSON( wgBannerList[geoLocation] ); |
| 81 | + $.centralNotice.fn.chooseBanner( bannerList ); |
96 | 82 | }, |
97 | 83 | 'chooseBanner': function( bannerList ) { |
98 | 84 | // Convert the json object to a true array |
99 | 85 | bannerList = Array.prototype.slice.call( bannerList ); |
100 | | - |
101 | 86 | // Make sure there are some banners to choose from |
102 | 87 | if ( bannerList.length == 0 ) return false; |
103 | 88 | |
— | — | @@ -137,17 +122,29 @@ |
138 | 123 | } |
139 | 124 | } |
140 | 125 | } |
141 | | - $( document ).ready( function () { |
142 | | - // Initialize the query string vars |
143 | | - $.centralNotice.fn.getQueryStringVariables(); |
| 126 | + // Initialize the query string vars |
| 127 | + $.centralNotice.fn.getQueryStringVariables(); |
| 128 | + if ( Geo.country ) { |
| 129 | + // We know the user's country so go ahead and load everything |
144 | 130 | if( $.centralNotice.data.getVars['banner'] ) { |
145 | | - // if we're forcing one banner |
| 131 | + // We're forcing one banner |
146 | 132 | $.centralNotice.fn.loadBanner( $.centralNotice.data.getVars['banner'] ); |
147 | 133 | } else { |
148 | 134 | // Look for banners ready to go NOW |
149 | 135 | $.centralNotice.fn.loadBannerList( $.centralNotice.data.getVars['country'] ); |
150 | 136 | } |
151 | | - } ); //document ready |
| 137 | + } else { |
| 138 | + // We don't know the user's country yet, so we have to wait for the GeoIP lookup |
| 139 | + $( document ).ready( function () { |
| 140 | + if( $.centralNotice.data.getVars['banner'] ) { |
| 141 | + // We're forcing one banner |
| 142 | + $.centralNotice.fn.loadBanner( $.centralNotice.data.getVars['banner'] ); |
| 143 | + } else { |
| 144 | + // Look for banners ready to go NOW |
| 145 | + $.centralNotice.fn.loadBannerList( $.centralNotice.data.getVars['country'] ); |
| 146 | + } |
| 147 | + } ); //document ready |
| 148 | + } |
152 | 149 | } )( jQuery ); |
153 | 150 | JAVASCRIPT; |
154 | 151 | return $js; |
— | — | @@ -218,5 +215,41 @@ |
219 | 216 | JAVASCRIPT; |
220 | 217 | return $script; |
221 | 218 | } |
| 219 | + |
| 220 | + /** |
| 221 | + * Generate all the banner lists for all the countries |
| 222 | + */ |
| 223 | + function getAllBannerLists() { |
| 224 | + $script = "var wgBannerList = new Array();\r\n"; |
| 225 | + $countriesList = CentralNoticeDB::getCountriesList(); |
| 226 | + foreach ( $countriesList as $countryCode => $countryName ) { |
| 227 | + $script .= "wgBannerList['$countryCode'] = '".$this->getBannerList( $countryCode )."';\r\n"; |
| 228 | + } |
| 229 | + return $script; |
| 230 | + } |
| 231 | + |
| 232 | + /** |
| 233 | + * Generate JSON banner list for a given country |
| 234 | + */ |
| 235 | + function getBannerList( $country ) { |
| 236 | + global $wgNoticeProject, $wgNoticeLang; |
| 237 | + $banners = array(); |
| 238 | + |
| 239 | + // See if we have any preferred campaigns for this language and project |
| 240 | + $campaigns = CentralNoticeDB::getCampaigns( $wgNoticeProject, $wgNoticeLang, null, 1, 1, $country ); |
| 241 | + |
| 242 | + // Quick short circuit to show preferred campaigns |
| 243 | + if ( $campaigns ) { |
| 244 | + // Pull banners |
| 245 | + $banners = CentralNoticeDB::getCampaignBanners( $campaigns ); |
| 246 | + } |
222 | 247 | |
| 248 | + // Didn't find any preferred banners so do an old style lookup |
| 249 | + if ( !$banners ) { |
| 250 | + $banners = CentralNoticeDB::getBannersByTarget( $wgNoticeProject, $wgNoticeLang, $country ); |
| 251 | + } |
| 252 | + |
| 253 | + return FormatJson::encode( $banners ); |
| 254 | + } |
| 255 | + |
223 | 256 | } |
Index: trunk/extensions/CentralNotice/CentralNotice.php |
— | — | @@ -102,9 +102,8 @@ |
103 | 103 | |
104 | 104 | if ( $wgCentralNoticeLoader ) { |
105 | 105 | $wgHooks['LoadExtensionSchemaUpdates'][] = 'efCentralNoticeSchema'; |
106 | | - $wgHooks['BeforePageDisplay'][] = 'efCentralNoticeLoader'; |
107 | 106 | $wgHooks['MakeGlobalVariablesScript'][] = 'efCentralNoticeDefaults'; |
108 | | - $wgHooks['SiteNoticeAfter'][] = 'efCentralNoticeDisplay'; |
| 107 | + $wgHooks['SiteNoticeAfter'][] = 'efCentralNoticeLoader'; |
109 | 108 | $wgHooks['SkinAfterBottomScripts'][] = 'efCentralNoticeGeoLoader'; |
110 | 109 | } |
111 | 110 | |
— | — | @@ -200,40 +199,38 @@ |
201 | 200 | return true; |
202 | 201 | } |
203 | 202 | |
204 | | -function efCentralNoticeLoader( $out, $skin ) { |
205 | | - global $wgOut; |
206 | | - |
207 | | - // Include '.js' to exempt script from squid cache expiration override |
208 | | - $centralLoader = SpecialPage::getTitleFor( 'BannerController' )->getLocalUrl( 'cache=/cn.js' ); |
209 | | - |
210 | | - // Insert the banner controller Javascript into the <head> |
211 | | - $wgOut->addScriptFile( $centralLoader ); |
212 | | - |
213 | | - return true; |
214 | | -} |
215 | | - |
216 | 203 | function efCentralNoticeGeoLoader( $skin, &$text ) { |
217 | | - // Insert the geo IP lookup |
218 | | - $text .= '<script type="text/javascript" src="//geoiplookup.wikimedia.org/"></script>'; |
| 204 | + // Insert the geo IP lookup and cookie setter |
| 205 | + $text .= <<<HTML |
| 206 | +<script type="text/javascript" src="//geoiplookup.wikimedia.org/"></script> |
| 207 | +<script> |
| 208 | +var e = new Date(); |
| 209 | +e.setTime( e.getTime() + (30*24*60*60*1000) ); // 30 days |
| 210 | +document.cookie = 'geo_country=' + Geo.country + '; expires=' + e.toGMTString() + '; path=/'; |
| 211 | +</script> |
| 212 | +HTML; |
219 | 213 | return true; |
220 | 214 | } |
221 | 215 | |
222 | 216 | function efCentralNoticeDefaults( &$vars ) { |
223 | 217 | global $wgNoticeProject; |
224 | | - // Initialize global Javascript variables. We initialize Geo with empty values so if the geo |
225 | | - // IP lookup fails we don't have any surprises. |
| 218 | + // Initialize global Javascript variables |
226 | 219 | $geo = (object)array(); |
227 | 220 | $geo->{'city'} = ''; |
228 | | - $geo->{'country'} = ''; |
229 | | - $vars['Geo'] = $geo; // change this to wgGeo as soon as Mark updates on his end |
| 221 | + if ( array_key_exists( 'geo_country', $_COOKIE ) && $_COOKIE['geo_country'] != '' ) { |
| 222 | + $geo->{'country'} = $_COOKIE['geo_country']; |
| 223 | + } else { |
| 224 | + $geo->{'country'} = ''; |
| 225 | + } |
| 226 | + $vars['Geo'] = $geo; |
230 | 227 | $vars['wgNoticeProject'] = $wgNoticeProject; |
231 | 228 | return true; |
232 | 229 | } |
233 | 230 | |
234 | | -function efCentralNoticeDisplay( &$notice ) { |
| 231 | +function efCentralNoticeLoader( &$notice ) { |
235 | 232 | // setup siteNotice div |
236 | | - $notice = |
237 | | - '<!-- centralNotice loads here -->'. // hack for IE8 to collapse empty div |
238 | | - $notice; |
| 233 | + // Include '.js' to exempt script from squid cache expiration override |
| 234 | + $centralLoader = SpecialPage::getTitleFor( 'BannerController' )->getLocalUrl( 'cache=/cn.js' ); |
| 235 | + $notice .= '<!-- centralNotice loads here --><script type="text/javascript" src="'.$centralLoader.'"></script>'; |
239 | 236 | return true; |
240 | 237 | } |