http://www.mediawiki.org/wiki/Special:Code/MediaWiki/99341
Revision: 99341 Author: kaldari Date: 2011-10-09 08:33:44 +0000 (Sun, 09 Oct 2011) Log Message: ----------- entirely new scheme to optimize banner loading - down from 1.1 seconds to 0.1 seconds - needs more testing Modified Paths: -------------- trunk/extensions/CentralNotice/CentralNotice.php trunk/extensions/CentralNotice/special/SpecialBannerController.php trunk/extensions/CentralNotice/special/SpecialBannerListLoader.php Modified: trunk/extensions/CentralNotice/CentralNotice.php =================================================================== --- trunk/extensions/CentralNotice/CentralNotice.php 2011-10-09 06:56:49 UTC (rev 99340) +++ trunk/extensions/CentralNotice/CentralNotice.php 2011-10-09 08:33:44 UTC (rev 99341) @@ -102,9 +102,8 @@ if ( $wgCentralNoticeLoader ) { $wgHooks['LoadExtensionSchemaUpdates'][] = 'efCentralNoticeSchema'; - $wgHooks['BeforePageDisplay'][] = 'efCentralNoticeLoader'; $wgHooks['MakeGlobalVariablesScript'][] = 'efCentralNoticeDefaults'; - $wgHooks['SiteNoticeAfter'][] = 'efCentralNoticeDisplay'; + $wgHooks['SiteNoticeAfter'][] = 'efCentralNoticeLoader'; $wgHooks['SkinAfterBottomScripts'][] = 'efCentralNoticeGeoLoader'; } @@ -200,40 +199,38 @@ return true; } -function efCentralNoticeLoader( $out, $skin ) { - global $wgOut; - - // Include '.js' to exempt script from squid cache expiration override - $centralLoader = SpecialPage::getTitleFor( 'BannerController' )->getLocalUrl( 'cache=/cn.js' ); - - // Insert the banner controller Javascript into the <head> - $wgOut->addScriptFile( $centralLoader ); - - return true; -} - function efCentralNoticeGeoLoader( $skin, &$text ) { - // Insert the geo IP lookup - $text .= '<script type="text/javascript" src="//geoiplookup.wikimedia.org/"></script>'; + // Insert the geo IP lookup and cookie setter + $text .= <<<HTML +<script type="text/javascript" src="//geoiplookup.wikimedia.org/"></script> +<script> +var e = new Date(); +e.setTime( e.getTime() + (30*24*60*60*1000) ); // 30 days +document.cookie = 'geo_country=' + Geo.country + '; expires=' + e.toGMTString() + '; path=/'; +</script> +HTML; return true; } function efCentralNoticeDefaults( &$vars ) { global $wgNoticeProject; - // Initialize global Javascript variables. We initialize Geo with empty values so if the geo - // IP lookup fails we don't have any surprises. + // Initialize global Javascript variables $geo = (object)array(); $geo->{'city'} = ''; - $geo->{'country'} = ''; - $vars['Geo'] = $geo; // change this to wgGeo as soon as Mark updates on his end + if ( array_key_exists( 'geo_country', $_COOKIE ) && $_COOKIE['geo_country'] != '' ) { + $geo->{'country'} = $_COOKIE['geo_country']; + } else { + $geo->{'country'} = ''; + } + $vars['Geo'] = $geo; $vars['wgNoticeProject'] = $wgNoticeProject; return true; } -function efCentralNoticeDisplay( &$notice ) { +function efCentralNoticeLoader( &$notice ) { // setup siteNotice div - $notice = - '<!-- centralNotice loads here -->'. // hack for IE8 to collapse empty div - $notice; + // Include '.js' to exempt script from squid cache expiration override + $centralLoader = SpecialPage::getTitleFor( 'BannerController' )->getLocalUrl( 'cache=/cn.js' ); + $notice .= '<!-- centralNotice loads here --><script type="text/javascript" src="'.$centralLoader.'"></script>'; return true; } Modified: trunk/extensions/CentralNotice/special/SpecialBannerController.php =================================================================== --- trunk/extensions/CentralNotice/special/SpecialBannerController.php 2011-10-09 06:56:49 UTC (rev 99340) +++ trunk/extensions/CentralNotice/special/SpecialBannerController.php 2011-10-09 08:33:44 UTC (rev 99341) @@ -4,8 +4,8 @@ * Generates Javascript file which controls banner selection on the client side */ class SpecialBannerController extends UnlistedSpecialPage { - protected $sharedMaxAge = 3600; // Cache for 1 hour on the server side - protected $maxAge = 3600; // Cache for 1 hour on the client side + protected $sharedMaxAge = 300; // Cache for 5 minutes on the server side + protected $maxAge = 300; // Cache for 5 minutes on the client side function __construct() { // Register special page @@ -19,16 +19,11 @@ $this->sendHeaders(); $content = $this->getOutput(); - if ( strlen( $content ) == 0 ) { - // Hack for IE/Mac 0-length keepalive problem, see RawPage.php - echo "/* Empty */"; - } else { - echo $content; - } + echo $content; } /** - * Generate the HTTP response headers for the banner controller + * Generate the HTTP response headers */ function sendHeaders() { global $wgJsMimeType; @@ -45,7 +40,7 @@ function getOutput() { global $wgCentralPagePath, $wgContLang; - $js = $this->getScriptFunctions() . $this->getToggleScripts(); + $js = $this->getAllBannerLists() . $this->getScriptFunctions() . $this->getToggleScripts(); $js .= <<<JAVASCRIPT ( function( $ ) { $.ajaxSetup({ cache: true }); @@ -81,22 +76,12 @@ } else { var geoLocation = Geo.country; // pull the geo info } - var bannerListQuery = $.param( { 'language': wgContentLanguage, 'project': wgNoticeProject, 'country': geoLocation } ); -JAVASCRIPT; - $js .= "\n\t\t\t\tvar bannerListURL = wgScript + '?title=' + encodeURIComponent('" . - $wgContLang->specialPage( 'BannerListLoader' ) . - "') + '&cache=/cn.js&' + bannerListQuery;\n"; - $js .= <<<JAVASCRIPT - var request = $.ajax( { - url: bannerListURL, - dataType: 'json', - success: $.centralNotice.fn.chooseBanner - } ); + var bannerList = $.parseJSON( wgBannerList[geoLocation] ); + $.centralNotice.fn.chooseBanner( bannerList ); }, 'chooseBanner': function( bannerList ) { // Convert the json object to a true array bannerList = Array.prototype.slice.call( bannerList ); - // Make sure there are some banners to choose from if ( bannerList.length == 0 ) return false; @@ -137,17 +122,29 @@ } } } - $( document ).ready( function () { - // Initialize the query string vars - $.centralNotice.fn.getQueryStringVariables(); + // Initialize the query string vars + $.centralNotice.fn.getQueryStringVariables(); + if ( Geo.country ) { + // We know the user's country so go ahead and load everything if( $.centralNotice.data.getVars['banner'] ) { - // if we're forcing one banner + // We're forcing one banner $.centralNotice.fn.loadBanner( $.centralNotice.data.getVars['banner'] ); } else { // Look for banners ready to go NOW $.centralNotice.fn.loadBannerList( $.centralNotice.data.getVars['country'] ); } - } ); //document ready + } else { + // We don't know the user's country yet, so we have to wait for the GeoIP lookup + $( document ).ready( function () { + if( $.centralNotice.data.getVars['banner'] ) { + // We're forcing one banner + $.centralNotice.fn.loadBanner( $.centralNotice.data.getVars['banner'] ); + } else { + // Look for banners ready to go NOW + $.centralNotice.fn.loadBannerList( $.centralNotice.data.getVars['country'] ); + } + } ); //document ready + } } )( jQuery ); JAVASCRIPT; return $js; @@ -218,5 +215,41 @@ JAVASCRIPT; return $script; } + + /** + * Generate all the banner lists for all the countries + */ + function getAllBannerLists() { + $script = "var wgBannerList = new Array();\r\n"; + $countriesList = CentralNoticeDB::getCountriesList(); + foreach ( $countriesList as $countryCode => $countryName ) { + $script .= "wgBannerList['$countryCode'] = '".$this->getBannerList( $countryCode )."';\r\n"; + } + return $script; + } + + /** + * Generate JSON banner list for a given country + */ + function getBannerList( $country ) { + global $wgNoticeProject, $wgNoticeLang; + $banners = array(); + + // See if we have any preferred campaigns for this language and project + $campaigns = CentralNoticeDB::getCampaigns( $wgNoticeProject, $wgNoticeLang, null, 1, 1, $country ); + + // Quick short circuit to show preferred campaigns + if ( $campaigns ) { + // Pull banners + $banners = CentralNoticeDB::getCampaignBanners( $campaigns ); + } + // Didn't find any preferred banners so do an old style lookup + if ( !$banners ) { + $banners = CentralNoticeDB::getBannersByTarget( $wgNoticeProject, $wgNoticeLang, $country ); + } + + return FormatJson::encode( $banners ); + } + } Modified: trunk/extensions/CentralNotice/special/SpecialBannerListLoader.php =================================================================== --- trunk/extensions/CentralNotice/special/SpecialBannerListLoader.php 2011-10-09 06:56:49 UTC (rev 99340) +++ trunk/extensions/CentralNotice/special/SpecialBannerListLoader.php 2011-10-09 08:33:44 UTC (rev 99341) @@ -1,6 +1,7 @@ <?php /** + * Note: This file is deprecated and should be deleted if the new banner loading system works better. * Generates JSON files listing all the banners for a particular site */ class SpecialBannerListLoader extends UnlistedSpecialPage { _______________________________________________ MediaWiki-CVS mailing list MediaWiki-CVS@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs