Jack Phoenix has uploaded a new change for review. https://gerrit.wikimedia.org/r/272729
Change subject: Version 0.4.2 from ShoutWiki ...................................................................... Version 0.4.2 from ShoutWiki * Support for the following skins: ** Aurora ** Dusk ** Home ** Metrolook ** Quartz * CSS tweaks * HTML5 fixes * Made the leaderboard ad (which is rendered via the SiteNoticeAfter hook) * available for all skins except Dusk & DuskToDawn * Minor documentation fixes * Some E_NOTICE fixes * Some debug logging (enable with $wgDebugLogGroups['ShoutWikiAds'] = '/path/to/some/log.file'; in LocalSettings.php) * Support for responsive ads (set $wgAdConfig['mode'] = 'responsive'; in LocalSettings.php to enable) Change-Id: If0f8e72389ede63a98eb4d08b209633e314b839e --- M ShoutWikiAds.class.php M ShoutWikiAds.php A css/aurora-leaderboard-ad.css A css/aurora-skyscraper-ad.css A css/cologneblue-leaderboard-ad.css A css/home-leaderboard-bottom-ad.css A css/home-skyscraper-ad.css A css/metrolook-button-ad.css A css/metrolook-leaderboard-ad.css A css/metrolook-wide-skyscraper-ad.less A css/modern-button-ad.css A css/modern-leaderboard-ad.css M css/monobook-button-ad.css M css/monobook-skyscraper-ad.css A css/quartz-square-ad.css A css/truglass-leaderboard-ad.css A css/vector-button-ad.css A css/vector-skyscraper-ad.css 18 files changed, 1,010 insertions(+), 220 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/ShoutWikiAds refs/changes/29/272729/1 diff --git a/ShoutWikiAds.class.php b/ShoutWikiAds.class.php index aac4ae9..e2b3df8 100644 --- a/ShoutWikiAds.class.php +++ b/ShoutWikiAds.class.php @@ -2,20 +2,34 @@ /** * ShoutWikiAds class -- contains the hooked functions and some other crap for * displaying the advertisements. - * Route all requests through loadAd( $type ) to ensure correct processing. + * + * Route all requests through loadAd( $type ) to ensure correct processing, such + * as not showing ads on login pages etc. * * We allow wiki admins to configure some things because our "sane defaults" * may clash with certain CSS styles (dark wikis, for example). * The Message objects are called with ->inContentLanguage(), because CSS is * "global" (doesn't vary depending on the user's language). + * NOTE: the above applies only to static ads; responsive ads can be customized + * via CSS as usual. * * All class methods are public and static. * * @file * @ingroup Extensions + * @author Jack Phoenix <[email protected]> + * @license https://en.wikipedia.org/wiki/Public_domain Public domain + * @link https://www.mediawiki.org/wiki/Extension:ShoutWiki_Ads Documentation */ class ShoutWikiAds { + + /** + * Used to determine whether to load AdSense JS in the page footer or not + * when we're serving responsive ads; obviously it should only be loaded if + * the current page has at least one active ad slot + */ + public static $PAGE_HAS_ADS = false; /** * Can we show ads on the current page? @@ -27,13 +41,12 @@ public static function canShowAds() { global $wgAdConfig, $wgTitle, $wgUser, $wgRequest; - if( !$wgAdConfig['enabled'] ) { + if ( !$wgAdConfig['enabled'] ) { return false; } - list( $alias, /*..*/ ) = SpecialPageFactory::resolveAlias( $wgTitle->getDBkey() ); - if( $wgTitle instanceof Title && - $alias === 'Userlogin' || + if ( $wgTitle instanceof Title && + $wgTitle->isSpecial( 'Userlogin' ) || in_array( 'staff', $wgUser->getEffectiveGroups() ) && !$wgRequest->getVal( 'forceads' ) ) { @@ -41,7 +54,7 @@ } // No configuration for this skin? Bail out! - if ( !$wgAdConfig[self::determineSkin()] ) { + if ( !isset( $wgAdConfig[self::determineSkin()] ) ) { return false; } @@ -52,7 +65,7 @@ * Check if the current wiki's language is supported by the ad provider * (currently checks against Google's list). * - * @return Boolean: true if the language is supported, otherwise false + * @return bool True if the language is supported, otherwise false */ public static function isSupportedLanguage() { global $wgLanguageCode; @@ -79,7 +92,7 @@ 'id', ); - if( in_array( $wgLanguageCode, $supportedAdLanguages ) ) { + if ( in_array( $wgLanguageCode, $supportedAdLanguages ) ) { return true; } else { return false; @@ -89,12 +102,15 @@ /** * Check if the current namespace is allowed to show ads. * - * @return Boolean: true if the namespace is supported, otherwise false + * @return bool True if the namespace is supported, otherwise false */ public static function isEnabledNamespace() { - global $wgAdConfig, $wgTitle; - $namespace = $wgTitle->getNamespace(); - if( in_array( $namespace, $wgAdConfig['namespaces'] ) ) { + global $wgAdConfig; + + $title = RequestContext::getMain()->getTitle(); // @todo FIXME filthy hack + $namespace = $title->getNamespace(); + + if ( in_array( $namespace, $wgAdConfig['namespaces'] ) ) { return true; } else { return false; @@ -102,10 +118,85 @@ } /** - * Skin-agnostic way of getting the HTML for a Google AdSense sidebar - * ad. + * Skin-agnostic way of getting the HTML for a Google AdSense banner ad (468x60px). * - * @return String: HTML code + * @return string HTML code + */ + public static function getBannerHTML() { + global $wgAdConfig; + + $skinName = self::determineSkin(); + + $adSlot = ''; + if ( isset( $wgAdConfig[$skinName . '-banner-ad-slot'] ) ) { + $adSlot = $wgAdConfig[$skinName . '-banner-ad-slot']; + } + + if ( isset( $wgAdConfig['debug'] ) && $wgAdConfig['debug'] === true ) { + return '<!-- Begin banner ad (ShoutWikiAds) --> + <div id="' . $skinName . '-banner-ad" class="' . $skinName . '-ad noprint"> + <img src="http://www.google.com/help/hc/images/adsense/adsense_185665_adformat-text_468x60_en.png" alt="" /> + </div> +<!-- End banner ad (ShoutWikiAds) -->' . "\n"; + } + + if ( isset( $wgAdConfig['mode'] ) && $wgAdConfig['mode'] == 'responsive' ) { + $adHTML = '<ins class="adsbygoogle" + style="display:block" + data-ad-client="ca-pub-' . $wgAdConfig['adsense-client'] . '" + data-ad-slot="' . $adSlot . '" + data-ad-format="auto"></ins> + <script>(adsbygoogle = window.adsbygoogle || []).push({});</script>'; + } else { + $borderColorMsg = wfMessage( 'shoutwiki-' . $skinName . '-banner-ad-color-border' )->inContentLanguage(); + $colorBGMsg = wfMessage( 'shoutwiki-' . $skinName . '-banner-ad-color-bg' )->inContentLanguage(); + $colorLinkMsg = wfMessage( 'shoutwiki-' . $skinName . '-banner-ad-color-link' )->inContentLanguage(); + $colorTextMsg = wfMessage( 'shoutwiki-' . $skinName . '-banner-ad-color-text' )->inContentLanguage(); + $colorURLMsg = wfMessage( 'shoutwiki-' . $skinName . '-banner-ad-color-url' )->inContentLanguage(); + + $colorBorderDefault = 'F6F4C4'; + $colorBGDefault = 'FFFFE0'; + $colorLinkDefault = '000000'; + $colorURLDefault = '002BB8'; + + // different defaults for Truglass from old Truglass ad code + if ( $skinName == 'truglass' ) { + $colorBorderDefault = 'CDCDCD'; + $colorBGDefault = 'FFFFFF'; + $colorLinkDefault = '0066FF'; + $colorURLDefault = '00A000'; + } + + $adHTML = '<script type="text/javascript"><!-- +google_ad_client = "pub-' . $wgAdConfig['adsense-client'] . '"; +google_ad_slot = "' . $adSlot . '"; +google_ad_width = 468; +google_ad_height = 60; +google_ad_format = "468x60_as"; +//google_ad_type = ""; +google_ad_channel = ""; +google_color_border = "' . ( $borderColorMsg->isDisabled() ? $colorBorderDefault : $borderColorMsg->text() ) . '"; +google_color_bg = "' . ( $colorBGMsg->isDisabled() ? $colorBGDefault : $colorBGMsg->text() ) . '"; +google_color_link = "' . ( $colorLinkMsg->isDisabled() ? $colorLinkDefault : $colorLinkMsg->text() ) . '"; +google_color_text = "' . ( $colorTextMsg->isDisabled() ? '000000' : $colorTextMsg->text() ) . '"; +google_color_url = "' . ( $colorURLMsg->isDisabled() ? $colorURLDefault : $colorURLMsg->text() ) . '"; +//--></script> +<script type="text/javascript" + src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> +</script>'; + } + + return '<!-- Begin banner ad (ShoutWikiAds) --> + <div id="' . $skinName . '-banner-ad" class="' . $skinName . '-ad noprint">' . + $adHTML . '</div> + <!-- End banner ad (ShoutWikiAds) -->' . "\n"; + } + + /** + * Skin-agnostic way of getting the HTML for a Google AdSense sidebar + * ad (200x200px). + * + * @return string HTML code */ public static function getSidebarHTML() { global $wgAdConfig; @@ -136,13 +227,7 @@ $adSlot = $wgAdConfig[$skinName . '-small-square-ad-slot']; } - $borderColorMsg = wfMessage( 'shoutwiki-' . $skinName . '-sidebar-ad-color-border' )->inContentLanguage(); - $colorBGMsg = wfMessage( 'shoutwiki-' . $skinName . '-sidebar-ad-color-bg' )->inContentLanguage(); - $colorLinkMsg = wfMessage( 'shoutwiki-' . $skinName . '-sidebar-ad-color-link' )->inContentLanguage(); - $colorTextMsg = wfMessage( 'shoutwiki-' . $skinName . '-sidebar-ad-color-text' )->inContentLanguage(); - $colorURLMsg = wfMessage( 'shoutwiki-' . $skinName . '-sidebar-ad-color-url' )->inContentLanguage(); - - if ( $wgAdConfig['debug'] === true ) { + if ( isset( $wgAdConfig['debug'] ) && $wgAdConfig['debug'] === true ) { return '<!-- Begin sidebar ad (ShoutWikiAds) --> <div id="' . $id . '" class="' . $classes . '"> <img src="http://www.google.com/help/hc/images/adsense_185665_adformat-text_200x200.png" alt="" /> @@ -150,9 +235,21 @@ <!-- End sidebar ad (ShoutWikiAds) -->' . "\n"; } - return '<!-- Begin sidebar ad (ShoutWikiAds) --> - <div id="' . $id . '" class="' . $classes . '"> -<script type="text/javascript"><!-- + if ( isset( $wgAdConfig['mode'] ) && $wgAdConfig['mode'] == 'responsive' ) { + $adHTML = '<ins class="adsbygoogle" + style="display:block" + data-ad-client="ca-pub-' . $wgAdConfig['adsense-client'] . '" + data-ad-slot="' . $adSlot . '" + data-ad-format="auto"></ins> + <script>(adsbygoogle = window.adsbygoogle || []).push({});</script>'; + } else { + $borderColorMsg = wfMessage( 'shoutwiki-' . $skinName . '-sidebar-ad-color-border' )->inContentLanguage(); + $colorBGMsg = wfMessage( 'shoutwiki-' . $skinName . '-sidebar-ad-color-bg' )->inContentLanguage(); + $colorLinkMsg = wfMessage( 'shoutwiki-' . $skinName . '-sidebar-ad-color-link' )->inContentLanguage(); + $colorTextMsg = wfMessage( 'shoutwiki-' . $skinName . '-sidebar-ad-color-text' )->inContentLanguage(); + $colorURLMsg = wfMessage( 'shoutwiki-' . $skinName . '-sidebar-ad-color-url' )->inContentLanguage(); + + $adHTML = '<script type="text/javascript"><!-- google_ad_client = "pub-' . $wgAdConfig['adsense-client'] . '"; google_ad_slot = "' . $adSlot . '"; google_ad_width = 200; @@ -168,17 +265,86 @@ //--></script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> -</script> +</script>'; + } -</div> -<!-- End sidebar ad (ShoutWikiAds) -->' . "\n"; + return '<!-- Begin sidebar ad (ShoutWikiAds) --> + <div id="' . $id . '" class="' . $classes . '">' . $adHTML . '</div> + <!-- End sidebar ad (ShoutWikiAds) -->' . "\n"; + } + + /** + * Skin-agnostic way of getting the HTML for a Google AdSense square ad (250x250px). + * + * @return string HTML code + */ + public static function getSquareHTML() { + global $wgAdConfig; + + $skinName = self::determineSkin(); + + $adSlot = ''; + if ( isset( $wgAdConfig[$skinName . '-square-ad-slot'] ) ) { + $adSlot = $wgAdConfig[$skinName . '-square-ad-slot']; + } + + if ( isset( $wgAdConfig['debug'] ) && $wgAdConfig['debug'] === true ) { + return '<!-- Begin square ad (ShoutWikiAds) --> + <div id="' . $skinName . '-square-ad" class="' . $skinName . '-ad noprint"> + <img src="https://storage.googleapis.com/support-kms-prod/SNP_2922347_en_v0" alt="" /> + </div> +<!-- End banner ad (ShoutWikiAds) -->' . "\n"; + } + + if ( isset( $wgAdConfig['mode'] ) && $wgAdConfig['mode'] == 'responsive' ) { + $adHTML = '<ins class="adsbygoogle" + style="display:block" + data-ad-client="ca-pub-' . $wgAdConfig['adsense-client'] . '" + data-ad-slot="' . $adSlot . '" + data-ad-format="auto"></ins> + <script>(adsbygoogle = window.adsbygoogle || []).push({});</script>'; + } else { + $borderColorMsg = wfMessage( 'shoutwiki-' . $skinName . '-square-ad-color-border' )->inContentLanguage(); + $colorBGMsg = wfMessage( 'shoutwiki-' . $skinName . '-square-ad-color-bg' )->inContentLanguage(); + $colorLinkMsg = wfMessage( 'shoutwiki-' . $skinName . '-square-ad-color-link' )->inContentLanguage(); + $colorTextMsg = wfMessage( 'shoutwiki-' . $skinName . '-square-ad-color-text' )->inContentLanguage(); + $colorURLMsg = wfMessage( 'shoutwiki-' . $skinName . '-square-ad-color-url' )->inContentLanguage(); + + $colorBorderDefault = 'F6F4C4'; + $colorBGDefault = 'FFFFE0'; + $colorLinkDefault = '000000'; + $colorURLDefault = '002BB8'; + + $adHTML = '<script type="text/javascript"><!-- +google_ad_client = "pub-' . $wgAdConfig['adsense-client'] . '"; +google_ad_slot = "' . $adSlot . '"; +google_ad_width = 250; +google_ad_height = 250; +google_ad_format = "250x250_as"; +//google_ad_type = ""; +google_ad_channel = ""; +google_color_border = "' . ( $borderColorMsg->isDisabled() ? $colorBorderDefault : $borderColorMsg->text() ) . '"; +google_color_bg = "' . ( $colorBGMsg->isDisabled() ? $colorBGDefault : $colorBGMsg->text() ) . '"; +google_color_link = "' . ( $colorLinkMsg->isDisabled() ? $colorLinkDefault : $colorLinkMsg->text() ) . '"; +google_color_text = "' . ( $colorTextMsg->isDisabled() ? '000000' : $colorTextMsg->text() ) . '"; +google_color_url = "' . ( $colorURLMsg->isDisabled() ? $colorURLDefault : $colorURLMsg->text() ) . '"; +//--></script> +<script type="text/javascript" + src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> +</script>'; + } + + return '<!-- Begin square ad (ShoutWikiAds) --> + <div id="' . $skinName . '-square-ad" class="' . $skinName . '-ad noprint">' . + $adHTML . '</div> + <!-- End banner ad (ShoutWikiAds) -->' . "\n"; } /** * Skin-agnostic way of getting the HTML for a Google AdSense leaderboard - * ad. + * ad (728x90px). * - * @return String: HTML code + * @return string HTML code */ public static function getLeaderboardHTML() { global $wgAdConfig; @@ -190,26 +356,7 @@ $adSlot = $wgAdConfig[$skinName . '-leaderboard-ad-slot']; } - $borderColorMsg = wfMessage( 'shoutwiki-' . $skinName . '-leaderboard-ad-color-border' )->inContentLanguage(); - $colorBGMsg = wfMessage( 'shoutwiki-' . $skinName . '-leaderboard-ad-color-bg' )->inContentLanguage(); - $colorLinkMsg = wfMessage( 'shoutwiki-' . $skinName . '-leaderboard-ad-color-link' )->inContentLanguage(); - $colorTextMsg = wfMessage( 'shoutwiki-' . $skinName . '-leaderboard-ad-color-text' )->inContentLanguage(); - $colorURLMsg = wfMessage( 'shoutwiki-' . $skinName . '-leaderboard-ad-color-url' )->inContentLanguage(); - - $colorBorderDefault = 'F6F4C4'; - $colorBGDefault = 'FFFFE0'; - $colorLinkDefault = '000000'; - $colorURLDefault = '002BB8'; - - // different defaults for Truglass from old Truglass ad code - if ( $skinName == 'truglass' ) { - $colorBorderDefault = 'CDCDCD'; - $colorBGDefault = 'FFFFFF'; - $colorLinkDefault = '0066FF'; - $colorURLDefault = '00A000'; - } - - if ( $wgAdConfig['debug'] === true ) { + if ( isset( $wgAdConfig['debug'] ) && $wgAdConfig['debug'] === true ) { return '<!-- Begin leaderboard ad (ShoutWikiAds) --> <div id="' . $skinName . '-leaderboard-ad" class="' . $skinName . '-ad noprint"> <img src="http://www.google.com/help/hc/images/adsense_185665_adformat-text_728x90.png" alt="" /> @@ -217,9 +364,34 @@ <!-- End leaderboard ad (ShoutWikiAds) -->' . "\n"; } - return '<!-- Begin leaderboard ad (ShoutWikiAds) --> - <div id="' . $skinName . '-leaderboard-ad" class="' . $skinName . '-ad noprint"> -<script type="text/javascript"><!-- + if ( isset( $wgAdConfig['mode'] ) && $wgAdConfig['mode'] == 'responsive' ) { + $adHTML = '<ins class="adsbygoogle" + style="display:block" + data-ad-client="ca-pub-' . $wgAdConfig['adsense-client'] . '" + data-ad-slot="' . $adSlot . '" + data-ad-format="vertical,horizontal"></ins> + <script>(adsbygoogle = window.adsbygoogle || []).push({});</script>'; + } else { + $borderColorMsg = wfMessage( 'shoutwiki-' . $skinName . '-leaderboard-ad-color-border' )->inContentLanguage(); + $colorBGMsg = wfMessage( 'shoutwiki-' . $skinName . '-leaderboard-ad-color-bg' )->inContentLanguage(); + $colorLinkMsg = wfMessage( 'shoutwiki-' . $skinName . '-leaderboard-ad-color-link' )->inContentLanguage(); + $colorTextMsg = wfMessage( 'shoutwiki-' . $skinName . '-leaderboard-ad-color-text' )->inContentLanguage(); + $colorURLMsg = wfMessage( 'shoutwiki-' . $skinName . '-leaderboard-ad-color-url' )->inContentLanguage(); + + $colorBorderDefault = 'F6F4C4'; + $colorBGDefault = 'FFFFE0'; + $colorLinkDefault = '000000'; + $colorURLDefault = '002BB8'; + + // different defaults for Truglass from old Truglass ad code + if ( $skinName == 'truglass' ) { + $colorBorderDefault = 'CDCDCD'; + $colorBGDefault = 'FFFFFF'; + $colorLinkDefault = '0066FF'; + $colorURLDefault = '00A000'; + } + + $adHTML = '<script type="text/javascript"><!-- google_ad_client = "pub-' . $wgAdConfig['adsense-client'] . '"; google_ad_slot = "' . $adSlot . '"; google_ad_width = 728; @@ -235,15 +407,19 @@ //--></script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> -</script> +</script>'; + } -</div> -<!-- End leaderboard ad (ShoutWikiAds) -->' . "\n"; + return '<!-- Begin leaderboard ad (ShoutWikiAds) --> + <div id="' . $skinName . '-leaderboard-ad" class="' . $skinName . '-ad noprint">' . + $adHTML . '</div> + <!-- End leaderboard ad (ShoutWikiAds) -->' . "\n"; } /** * Get the HTML for a toolbox ad (125x125). - * @return HTML + * + * @return string HTML code */ public static function getToolboxHTML() { global $wgAdConfig; @@ -255,13 +431,7 @@ $adSlot = $wgAdConfig[$skinName . '-button-ad-slot']; } - $borderColorMsg = wfMessage( 'shoutwiki-' . $skinName . '-toolbox-ad-color-border' )->inContentLanguage(); - $colorBGMsg = wfMessage( 'shoutwiki-' . $skinName . '-toolbox-ad-color-bg' )->inContentLanguage(); - $colorLinkMsg = wfMessage( 'shoutwiki-' . $skinName . '-toolbox-ad-color-link' )->inContentLanguage(); - $colorTextMsg = wfMessage( 'shoutwiki-' . $skinName . '-toolbox-ad-color-text' )->inContentLanguage(); - $colorURLMsg = wfMessage( 'shoutwiki-' . $skinName . '-toolbox-ad-color-url' )->inContentLanguage(); - - if ( $wgAdConfig['debug'] === true ) { + if ( isset( $wgAdConfig['debug'] ) && $wgAdConfig['debug'] === true ) { return '<!-- Begin toolbox ad (ShoutWikiAds) --> <div id="p-ads-left" class="noprint"> <img src="http://www.google.com/help/hc/images/adsense_185665_adformat-text_125x125_en.png" alt="" /> @@ -269,9 +439,21 @@ <!-- End toolbox ad (ShoutWikiAds) -->' . "\n"; } - return '<!-- Begin toolbox ad (ShoutWikiAds) --> -<div id="p-ads-left" class="noprint"> -<script type="text/javascript"><!-- + if ( isset( $wgAdConfig['mode'] ) && $wgAdConfig['mode'] == 'responsive' ) { + $adHTML = '<ins class="adsbygoogle" + style="display:block" + data-ad-client="ca-pub-' . $wgAdConfig['adsense-client'] . '" + data-ad-slot="' . $adSlot . '" + data-ad-format="auto"></ins> + <script>(adsbygoogle = window.adsbygoogle || []).push({});</script>'; + } else { + $borderColorMsg = wfMessage( 'shoutwiki-' . $skinName . '-toolbox-ad-color-border' )->inContentLanguage(); + $colorBGMsg = wfMessage( 'shoutwiki-' . $skinName . '-toolbox-ad-color-bg' )->inContentLanguage(); + $colorLinkMsg = wfMessage( 'shoutwiki-' . $skinName . '-toolbox-ad-color-link' )->inContentLanguage(); + $colorTextMsg = wfMessage( 'shoutwiki-' . $skinName . '-toolbox-ad-color-text' )->inContentLanguage(); + $colorURLMsg = wfMessage( 'shoutwiki-' . $skinName . '-toolbox-ad-color-url' )->inContentLanguage(); + + $adHTML = '<script type="text/javascript"><!-- google_ad_client = "pub-' . $wgAdConfig['adsense-client'] . '"; google_ad_slot = "' . $adSlot . '"; google_ad_width = 125; @@ -287,16 +469,18 @@ //--></script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> -</script> +</script>'; + } -</div> + return '<!-- Begin toolbox ad (ShoutWikiAds) --> +<div id="p-ads-left" class="noprint">' . $adHTML . '</div> <!-- End toolbox ad (ShoutWikiAds) -->' . "\n"; } /** * Get the HTML for a normal skyscraper ad (120x600). * - * @return String: HTML + * @return string HTML code */ public static function getSkyscraperHTML() { global $wgAdConfig; @@ -308,14 +492,8 @@ $adSlot = $wgAdConfig[$skinName . '-skyscraper-ad-slot']; } - $borderColorMsg = wfMessage( 'shoutwiki-' . $skinName . '-rightcolumn-ad-color-border' )->inContentLanguage(); - $colorBGMsg = wfMessage( 'shoutwiki-' . $skinName . '-rightcolumn-ad-color-bg' )->inContentLanguage(); - $colorLinkMsg = wfMessage( 'shoutwiki-' . $skinName . '-rightcolumn-ad-color-link' )->inContentLanguage(); - $colorTextMsg = wfMessage( 'shoutwiki-' . $skinName . '-rightcolumn-ad-color-text' )->inContentLanguage(); - $colorURLMsg = wfMessage( 'shoutwiki-' . $skinName . '-rightcolumn-ad-color-url' )->inContentLanguage(); - // Just output an image in debug mode - if ( $wgAdConfig['debug'] === true ) { + if ( isset( $wgAdConfig['debug'] ) && $wgAdConfig['debug'] === true ) { return "\n" . '<!-- Begin skyscraper ad (ShoutWikiAds) --> <div id="column-google" class="' . $skinName . '-ad noprint"> <img src="http://www.google.com/help/hc/images/adsense_185665_adformat-text_120x600.png" alt="" /> @@ -323,9 +501,21 @@ <!-- End skyscraper ad (ShoutWikiAds) -->' . "\n"; } - return "\n" . '<!-- Begin skyscraper ad (ShoutWikiAds) --> -<div id="column-google" class="' . $skinName . '-ad noprint"> -<script type="text/javascript"><!-- + if ( isset( $wgAdConfig['mode'] ) && $wgAdConfig['mode'] == 'responsive' ) { + $adHTML = '<ins class="adsbygoogle" + style="display:block" + data-ad-client="ca-pub-' . $wgAdConfig['adsense-client'] . '" + data-ad-slot="' . $adSlot . '" + data-ad-format="auto"></ins> + <script>(adsbygoogle = window.adsbygoogle || []).push({});</script>'; + } else { + $borderColorMsg = wfMessage( 'shoutwiki-' . $skinName . '-rightcolumn-ad-color-border' )->inContentLanguage(); + $colorBGMsg = wfMessage( 'shoutwiki-' . $skinName . '-rightcolumn-ad-color-bg' )->inContentLanguage(); + $colorLinkMsg = wfMessage( 'shoutwiki-' . $skinName . '-rightcolumn-ad-color-link' )->inContentLanguage(); + $colorTextMsg = wfMessage( 'shoutwiki-' . $skinName . '-rightcolumn-ad-color-text' )->inContentLanguage(); + $colorURLMsg = wfMessage( 'shoutwiki-' . $skinName . '-rightcolumn-ad-color-url' )->inContentLanguage(); + + $adHTML = '<script type="text/javascript"><!-- google_ad_client = "pub-' . $wgAdConfig['adsense-client'] . '"; google_ad_slot = "' . $adSlot . '"; google_ad_width = 120; @@ -341,16 +531,80 @@ //--></script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> -</script> +</script>'; + } -</div> + return "\n" . '<!-- Begin skyscraper ad (ShoutWikiAds) --> +<div id="column-google" class="' . $skinName . '-ad noprint">' . $adHTML . '</div> <!-- End skyscraper ad (ShoutWikiAds) -->' . "\n"; + } + + /** + * Get the HTML for a wide skyscraper ad (160x600). + * + * @return string HTML code + */ + public static function getWideSkyscraperHTML() { + global $wgAdConfig; + + $skinName = self::determineSkin(); + + $adSlot = ''; + if ( isset( $wgAdConfig[$skinName . '-wide-skyscraper-ad-slot'] ) ) { + $adSlot = $wgAdConfig[$skinName . '-wide-skyscraper-ad-slot']; + } + + // Just output an image in debug mode + if ( isset( $wgAdConfig['debug'] ) && $wgAdConfig['debug'] === true ) { + return "\n" . '<!-- Begin wide skyscraper ad (ShoutWikiAds) --> +<div id="column-google" class="' . $skinName . '-ad noprint"> + <img src="https://storage.googleapis.com/support-kms-prod/SNP_1DA7588EEB5450EE2A22C2B2F0A6458A61C0_2922342_en_v1" alt="" /> +</div> +<!-- End wide skyscraper ad (ShoutWikiAds) -->' . "\n"; + } + + if ( isset( $wgAdConfig['mode'] ) && $wgAdConfig['mode'] == 'responsive' ) { + $adHTML = '<ins class="adsbygoogle" + style="display:block" + data-ad-client="ca-pub-' . $wgAdConfig['adsense-client'] . '" + data-ad-slot="' . $adSlot . '" + data-ad-format="vertical"></ins> + <script>(adsbygoogle = window.adsbygoogle || []).push({});</script>'; + } else { + $borderColorMsg = wfMessage( 'shoutwiki-' . $skinName . '-wide-skyscraper-ad-color-border' )->inContentLanguage(); + $colorBGMsg = wfMessage( 'shoutwiki-' . $skinName . '-wide-skyscraper-ad-color-bg' )->inContentLanguage(); + $colorLinkMsg = wfMessage( 'shoutwiki-' . $skinName . '-wide-skyscraper-ad-color-link' )->inContentLanguage(); + $colorTextMsg = wfMessage( 'shoutwiki-' . $skinName . '-wide-skyscraper-ad-color-text' )->inContentLanguage(); + $colorURLMsg = wfMessage( 'shoutwiki-' . $skinName . '-wide-skyscraper-ad-color-url' )->inContentLanguage(); + + $adHTML = '<script type="text/javascript"><!-- +google_ad_client = "pub-' . $wgAdConfig['adsense-client'] . '"; +google_ad_slot = "' . $adSlot . '"; +google_ad_width = 160; +google_ad_height = 600; +google_ad_format = "160x600_as"; +//google_ad_type = "text"; +google_ad_channel = ""; +google_color_border = "' . ( $borderColorMsg->isDisabled() ? 'F6F4C4' : $borderColorMsg->text() ) . '"; +google_color_bg = "' . ( $colorBGMsg->isDisabled() ? 'FFFFE0' : $colorBGMsg->text() ) . '"; +google_color_link = "' . ( $colorLinkMsg->isDisabled() ? '000000' : $colorLinkMsg->text() ) . '"; +google_color_text = "' . ( $colorTextMsg->isDisabled() ? '000000' : $colorTextMsg->text() ) . '"; +google_color_url = "' . ( $colorURLMsg->isDisabled() ? '002BB8' : $colorURLMsg->text() ) . '"; +//--></script> +<script type="text/javascript" + src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> +</script>'; + } + + return "\n" . '<!-- Begin wide skyscraper ad (ShoutWikiAds) --> +<div id="column-google" class="' . $skinName . '-ad noprint">' . $adHTML . '</div> +<!-- End wide skyscraper ad (ShoutWikiAds) -->' . "\n"; } /** * Get the HTML for a small square ad (200x200). * - * @return String: HTML + * @return string HTML code */ public static function getSmallSquareHTML() { global $wgAdConfig; @@ -362,14 +616,8 @@ $adSlot = $wgAdConfig[$skinName . '-small-square-ad-slot']; } - $borderColorMsg = wfMessage( 'shoutwiki-' . $skinName . '-smallsquare-ad-color-border' )->inContentLanguage(); - $colorBGMsg = wfMessage( 'shoutwiki-' . $skinName . '-smallsquare-ad-color-bg' )->inContentLanguage(); - $colorLinkMsg = wfMessage( 'shoutwiki-' . $skinName . '-smallsquare-ad-color-link' )->inContentLanguage(); - $colorTextMsg = wfMessage( 'shoutwiki-' . $skinName . '-smallsquare-ad-color-text' )->inContentLanguage(); - $colorURLMsg = wfMessage( 'shoutwiki-' . $skinName . '-smallsquare-ad-color-url' )->inContentLanguage(); - // Just output an image in debug mode - if ( $wgAdConfig['debug'] === true ) { + if ( isset( $wgAdConfig['debug'] ) && $wgAdConfig['debug'] === true ) { /* Strangely enough when trying to display the text-only ad (located at http://www.google.com/help/hc/images/adsense_185665_adformat-text_200x200.png), @@ -385,9 +633,21 @@ <!-- End small square (ShoutWikiAds) -->' . "\n"; } - return "\n" . '<!-- Begin small square ad (ShoutWikiAds) --> -<div id="small-square-ad" class="' . $skinName . '-ad noprint"> -<script type="text/javascript"><!-- + if ( isset( $wgAdConfig['mode'] ) && $wgAdConfig['mode'] == 'responsive' ) { + $adHTML = '<ins class="adsbygoogle" + style="display:block" + data-ad-client="ca-pub-' . $wgAdConfig['adsense-client'] . '" + data-ad-slot="' . $adSlot . '" + data-ad-format="auto"></ins> + <script>(adsbygoogle = window.adsbygoogle || []).push({});</script>'; + } else { + $borderColorMsg = wfMessage( 'shoutwiki-' . $skinName . '-smallsquare-ad-color-border' )->inContentLanguage(); + $colorBGMsg = wfMessage( 'shoutwiki-' . $skinName . '-smallsquare-ad-color-bg' )->inContentLanguage(); + $colorLinkMsg = wfMessage( 'shoutwiki-' . $skinName . '-smallsquare-ad-color-link' )->inContentLanguage(); + $colorTextMsg = wfMessage( 'shoutwiki-' . $skinName . '-smallsquare-ad-color-text' )->inContentLanguage(); + $colorURLMsg = wfMessage( 'shoutwiki-' . $skinName . '-smallsquare-ad-color-url' )->inContentLanguage(); + + $adHTML = '<script type="text/javascript"><!-- google_ad_client = "pub-' . $wgAdConfig['adsense-client'] . '"; google_ad_slot = "' . $adSlot . '"; google_ad_width = 200; @@ -403,9 +663,11 @@ //--></script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> -</script> +</script>'; + } -</div> + return "\n" . '<!-- Begin small square ad (ShoutWikiAds) --> +<div id="small-square-ad" class="' . $skinName . '-ad noprint">' . $adHTML . '</div> <!-- End small square ad (ShoutWikiAds) -->' . "\n"; } @@ -418,16 +680,16 @@ * @return bool */ public static function setupAdCSS( &$out, &$sk ) { - global $wgAdConfig, $wgRequest, $wgUser; + global $wgAdConfig, $wgResourceModules, $wgRequest, $wgUser; - if( !$wgAdConfig['enabled'] ) { + if ( !$wgAdConfig['enabled'] ) { return true; } // In order for us to load ad-related CSS, the user must either be // a mortal (=not staff) or have supplied the forceads parameter in // the URL - if( + if ( !in_array( 'staff', $wgUser->getEffectiveGroups() ) || $wgRequest->getVal( 'forceads' ) ) @@ -436,48 +698,47 @@ $namespace = $title->getNamespace(); // Okay, the variable name sucks but anyway...normal page != not login page - list( $alias, /*..*/ ) = SpecialPageFactory::resolveAlias( $title->getDBkey() ); $isNormalPage = $title instanceof Title && - $alias !== 'Userlogin'; + !$title->isSpecial( 'Userlogin' ); // Load ad CSS file when ads are enabled - if( + if ( $isNormalPage && in_array( $namespace, $wgAdConfig['namespaces'] ) ) { - if ( get_class( $sk ) == 'SkinMonaco' ) { // Monaco - $out->addModuleStyles( 'ext.ShoutWikiAds.monaco' ); - } elseif( get_class( $sk ) == 'SkinMonoBook' ) { // Monobook - if ( $wgAdConfig['monobook']['skyscraper'] ) { - $out->addModuleStyles( 'ext.ShoutWikiAds.monobook.skyscraper' ); + $skinClass = str_replace( 'Skin', '', get_class( $sk ) ); + $skinClass = strtolower( $skinClass ); + + if ( isset( $wgAdConfig[$skinClass] ) ) { + $modules = array(); + + // Iterate over the enabled + foreach ( $wgAdConfig[$skinClass] as $enabledAdType => $unused ) { + $moduleName = "ext.ShoutWikiAds.{$skinClass}.{$enabledAdType}"; + + // Aurora's sitenotice leaderboard doesn't need any additional CSS + if ( $skinClass == 'aurora' && $enabledAdType == 'leaderboard-bottom' ) { + continue; + } + + if ( $skinClass == 'monaco' ) { + $moduleName = "ext.ShoutWikiAds.{$skinClass}"; + } + + if ( $enabledAdType == 'toolbox' ) { + $moduleName = str_replace( 'toolbox', 'button', $moduleName ); + } + + // Sanity check -- is there such a module? + if ( isset( $wgResourceModules[$moduleName] ) && $wgResourceModules[$moduleName] ) { + $modules[] = $moduleName; + } } - if ( $wgAdConfig['monobook']['toolbox'] ) { - $out->addModuleStyles( 'ext.ShoutWikiAds.monobook.button' ); + + if ( !empty( $modules ) ) { + $out->addModuleStyles( $modules ); } - } elseif ( get_class( $sk ) == 'SkinVector' ) { // Vector - if ( $wgAdConfig['vector']['skyscraper'] ) { - $out->addModuleStyles( 'ext.ShoutWikiAds.vector.skyscraper' ); - } - if ( $wgAdConfig['vector']['toolbox'] ) { - $out->addModuleStyles( 'ext.ShoutWikiAds.vector.button' ); - } - } elseif ( get_class( $sk ) == 'SkinModern' ) { // Modern - if ( $wgAdConfig['modern']['leaderboard'] ) { - $out->addModuleStyles( 'ext.ShoutWikiAds.modern.leaderboard' ); - } - // No, the "monobook" here isn't a typo. SkinModern extends - // Monobook's base class so there's no specific toggle to - // turn off the button ads for Modern... - if ( $wgAdConfig['monobook']['toolbox'] ) { - $out->addModuleStyles( 'ext.ShoutWikiAds.modern.button' ); - } - } elseif ( get_class( $sk ) == 'SkinCologneBlue' ) { // Cologne Blue - if ( $wgAdConfig['cologneblue']['leaderboard'] ) { - $out->addModuleStyles( 'ext.ShoutWikiAds.cologneblue.leaderboard' ); - } - } elseif ( get_class( $sk ) == 'SkinTruglass' ) { // Truglass - $out->addModuleStyles( 'ext.ShoutWikiAds.truglass' ); } } } @@ -486,24 +747,41 @@ } /** - * Load toolbox ad for Monobook skin. - * @return Boolean: true + * Load toolbox ad for Monobook *and* Modern skins. + * + * @return bool */ public static function onMonoBookAfterToolbox() { global $wgAdConfig; - if ( $wgAdConfig['monobook']['toolbox'] ) { + + // Modern extends Monobook's base class, and therefore this is needed + // so that we can, for example, have the toolbox button ad *enabled* + // for Monobook and disabled for Modern. :-( + $skin = self::determineSkin(); + + if ( + isset( $wgAdConfig[$skin]['toolbox'] ) && + $wgAdConfig[$skin]['toolbox'] + ) + { echo self::loadAd( 'toolbox-button' ); } + return true; } /** * Load skyscraper ad for Monobook skin. - * @return Boolean: true + * + * @return bool */ public static function onMonoBookAfterContent() { global $wgAdConfig; - if ( $wgAdConfig['monobook']['skyscraper'] ) { + if ( + isset( $wgAdConfig['monobook']['skyscraper'] ) && + $wgAdConfig['monobook']['skyscraper'] + ) + { echo self::loadAd( 'right-column' ); } return true; @@ -512,11 +790,15 @@ /** * Load skyscraper ad for the Vector skin. * - * @return Boolean: true + * @return bool */ public static function onVectorBeforeFooter() { global $wgAdConfig; - if ( $wgAdConfig['vector']['skyscraper'] ) { + if ( + isset( $wgAdConfig['vector']['skyscraper'] ) && + $wgAdConfig['vector']['skyscraper'] + ) + { echo self::loadAd( 'right-column' ); } return true; @@ -525,11 +807,15 @@ /** * Load the ad box after the toolbox on the Vector skin. * - * @return Boolean: true + * @return bool */ public static function onVectorAfterToolbox() { global $wgAdConfig; - if ( $wgAdConfig['vector']['toolbox'] ) { + if ( + isset( $wgAdConfig['vector']['toolbox'] ) && + $wgAdConfig['vector']['toolbox'] + ) + { echo self::loadAd( 'toolbox-button' ); } return true; @@ -537,11 +823,16 @@ /** * Load sidebar ad for Monaco skin. - * @return Boolean: true + * + * @return bool */ public static function onMonacoSidebar() { global $wgAdConfig; - if ( $wgAdConfig['monaco']['sidebar'] ) { + if ( + isset( $wgAdConfig['monaco']['sidebar'] ) && + $wgAdConfig['monaco']['sidebar'] + ) + { echo self::loadAd( 'sidebar' ); } return true; @@ -549,12 +840,97 @@ /** * Load leaderboard ad in Monaco skin's footer. - * @return Boolean: true + * + * @return bool */ public static function onMonacoFooter() { global $wgAdConfig; - if ( $wgAdConfig['monaco']['leaderboard'] ) { + if ( + isset( $wgAdConfig['monaco']['leaderboard'] ) && + $wgAdConfig['monaco']['leaderboard'] + ) + { echo self::loadAd( 'leaderboard' ); + } + return true; + } + + /** + * Load a skyscraper ad in Aurora's left-hand sidebar, below the "page history" + * link. + * + * @param AuroraTemplate $auroraTemplate + * @return bool + */ + public static function onAuroraLeftSidebar( $auroraTemplate ) { + global $wgAdConfig; + if ( + isset( $wgAdConfig['aurora']['skyscraper'] ) && + $wgAdConfig['aurora']['skyscraper'] + ) + { + // Only show this ad on existing pages as it'd strech nonexistent ones + // quite a bit + if ( $auroraTemplate->getSkin()->getTitle()->exists() ) { + // My naming conventions suck, I know. + echo self::loadAd( 'right-column' ); + } + } + return true; + } + + /** + * Load a leaderboard ad in Aurora's footer. + * + * @param string $data + * @param Skin $skin + * @return bool + */ + public static function onSkinAfterContent( &$data, Skin $skin ) { + global $wgAdConfig; + + if ( + get_class( $skin ) == 'SkinAurora' && + isset( $wgAdConfig['aurora']['leaderboard-bottom'] ) && + $wgAdConfig['aurora']['leaderboard-bottom'] + ) + { + $adHTML = self::loadAd( 'leaderboard' ); + $data = str_replace( + // Quick HTML validation fix + '<div id="aurora-leaderboard-ad"', + '<div id="aurora-leaderboard-ad-2"', + $adHTML + ); + } + + if ( + get_class( $skin ) == 'SkinHome' && + isset( $wgAdConfig['home']['leaderboard-bottom'] ) && + $wgAdConfig['home']['leaderboard-bottom'] + ) + { + $data = self::loadAd( 'leaderboard' ); + } + + return true; + } + + /** + * Load a small button ad in Dusk's toolbox (well, this code runs in the + * toolbox() function, but after the #p-tb div has been closed). + * + * @param DuskTemplate $dusk + * @return bool + */ + public static function onDuskAfterToolbox( $dusk ) { + global $wgAdConfig; + if ( + isset( $wgAdConfig['dusk']['toolbox'] ) && + $wgAdConfig['dusk']['toolbox'] + ) + { + echo self::loadAd( 'toolbox-button' ); } return true; } @@ -567,21 +943,100 @@ * The fugly logic here is pretty much the same as in renderTruglassAd() * below. * - * @return Boolean: true + * @return bool */ public static function onGamesSideBox() { global $wgAdConfig; - if ( $wgAdConfig['games']['skyscraper'] ) { + if ( + isset( $wgAdConfig['games']['skyscraper'] ) && + $wgAdConfig['games']['skyscraper'] + ) + { $skyscraperHTML = self::loadAd( 'right-column' ); if ( empty( $skyscraperHTML ) ) { return true; } - $leaderboardHTML = str_replace( + $skyscraperHTML = str_replace( '<div id="column-google"', '<div id="sideads"', - $leaderboardHTML + $skyscraperHTML ); echo $skyscraperHTML; + } + return true; + } + + /** + * Skyscraper ads -- two of 'em -- for the Home skin. + * + * @param HomeTemplate $homeTemplate + * @return bool + */ + public static function onHomeAfterEverything( $homeTemplate ) { + global $wgAdConfig; + if ( + isset( $wgAdConfig['home']['skyscraper'] ) && + $wgAdConfig['home']['skyscraper'] + ) + { + $adHTML = self::loadAd( 'skyscraper' ); + if ( $adHTML ) { + // Remove the IDs altogether + $adHTML = str_replace( + 'id="column-google"', + '', + $adHTML + ); + // And instead hackily inject the appropriate classes + $adLeft = str_replace( 'class="', 'class="column-google-left ', $adHTML ); + $adRight = str_replace( 'class="', 'class="column-google-right ', $adHTML ); + $output = $adLeft . $adRight; + // Finally display 'em, too! + echo $output; + } + } + return true; + } + + /** + * Metrolook toolbox 125x125px ad. + * + * @param MetrolookTemplate $metrolookTemplate + * @return bool + */ + public static function onMetrolookAfterToolbox( $metrolookTemplate ) { + global $wgAdConfig; + if ( + isset( $wgAdConfig['metrolook']['toolbox'] ) && + $wgAdConfig['metrolook']['toolbox'] + ) + { + echo self::loadAd( 'toolbox-button' ); + } + return true; + } + + /** + * Metrolook's right sidebar has a wider skyscraper ad than MonoBook & co. + * + * @param MetrolookTemplate $metrolookTemplate + * @return bool + */ + public static function onMetrolookRightPanel( $metrolookTemplate ) { + global $wgAdConfig; + if ( + isset( $wgAdConfig['metrolook']['wide-skyscraper'] ) && + $wgAdConfig['metrolook']['wide-skyscraper'] + ) + { + // Oh gods why... + $s = self::loadAd( 'wide-skyscraper' ); + $s = str_replace( + array( '<div id="column-google" class="metrolook-ad noprint">', '</div>' ), + '', + $s + ); + echo $s; } return true; } @@ -590,7 +1045,7 @@ * Gets a small square ad to display on Nimbus' left side, after the search * box and above the "Did you know" bit. * - * @return Boolean: true + * @return bool */ public static function onNimbusLeftSide() { global $wgAdConfig; @@ -603,14 +1058,60 @@ } /** - * Called *only* by Truglass skin. + * Load a square ad on the Quartz skin, in the sidebar. * - * @return Boolean: true + * @param QuartzTemplate $quartz + * @param string $adBody + * @return bool + */ + public static function onQuartzSidebarWidgets( $quartz, &$adBody ) { + global $wgAdConfig; + if ( + isset( $wgAdConfig['quartz']['square'] ) && + $wgAdConfig['quartz']['square'] + ) + { + $adBody = self::loadAd( 'square' ); + } + return true; + } + + /** + * Load a square ad on the Quartz skin, in the sidebar. + * + * @param QuartzTemplate $quartz + * @param string $adBody + * @return bool + */ + public static function onQuartzSidebarWidgetAdvertiser( $quartz, &$adBody ) { + global $wgAdConfig; + if ( + isset( $wgAdConfig['quartz']['square'] ) && + $wgAdConfig['quartz']['square'] + ) + { + $adBody = str_replace( + 'id="quartz-square-ad', + 'id="quartz-square-ad-2', + self::loadAd( 'square' ) + ); + } + return true; + } + + /** + * Called *only* by the Truglass skin. + * + * @return bool */ public static function renderTruglassAd() { global $wgAdConfig; - if ( $wgAdConfig['truglass']['leaderboard'] ) { + if ( + isset( $wgAdConfig['truglass']['leaderboard'] ) && + $wgAdConfig['truglass']['leaderboard'] + ) + { // Use the universal loader method so that ads aren't shown to // privileged users or on login pages, etc. $leaderboardHTML = self::loadAd( 'leaderboard' ); @@ -622,21 +1123,13 @@ return true; } - // Hack to replace the ad div ID with the "correct" one because - // I'm too lazy to edit Truglass' CSS file(s) - $leaderboardHTML = str_replace( - '<div id="truglass-leaderboard-ad"', - '<div id="topadsleft"', - $leaderboardHTML - ); - echo '<!-- Begin Truglass ad (ShoutWikiAds) --> - <table border="0" cellpadding="0" cellspacing="0" width="100%"> + <table class="fullwidth truglass-ad-container"> <tbody> <tr> - <td valign="top" id="contentBox"> + <td id="contentBox"> <div id="contentCont"> - <table id="topsector" width="100%"> + <table id="topsector" class="fullwidth"> <tr> <td>' . $leaderboardHTML . '</td> </tr> @@ -653,36 +1146,77 @@ } /** - * Render a leaderboard ad in the site notice area for certain skins. + * Render a leaderboard ad in the site notice area for almost all skins, + * provided that the leaderboard ad for the said skin(s) is enabled in + * advertising configuration (or a banner ad for Dusk). * - * @param $siteNotice String: existing site notice HTML (etc.), if any - * @return Boolean: true + * @param string $siteNotice Existing site notice HTML (etc.), if any + * @return bool */ public static function onSiteNoticeAfter( &$siteNotice ) { global $wgAdConfig; $skinName = self::determineSkin(); - $allowedSkins = array( 'cologneblue', 'modern', 'monobook', 'nimbus', 'vector' ); // Monaco and Truglass have a different leaderboard ad implementation // and AdSense's terms of use state that one page may have up to three - // ads + // ads; Dusk & DuskToDawn are handled below, as you can see. + $blacklist = array( + 'dusk', 'dusktodawn', 'monaco', 'truglass' + ); if ( - in_array( $skinName, $allowedSkins ) && + !in_array( $skinName, $blacklist ) && isset( $wgAdConfig[$skinName]['leaderboard'] ) && $wgAdConfig[$skinName]['leaderboard'] === true ) { $siteNotice .= self::loadAd( 'leaderboard' ); + } elseif ( + // Both Dusk* skins have a damn small content area; in fact, it's + // so small it can't fit a normal leaderboard, so we display a banner + // in the sitenotice area instead (when enabled in config, of course) + ( $skinName == 'dusk' || $skinName == 'dusktodawn' ) && + isset( $wgAdConfig[$skinName]['banner'] ) && + $wgAdConfig[$skinName]['banner'] === true + ) + { + $siteNotice .= self::loadAd( 'banner' ); } return true; } /** + * If a page has ads, load the AdSense JS in the bottom of the page. + * This works because we don't need to fiddle with ResourceLoader 'cause + * AdSense JS is hosted by Google. + * + * We also don't need to load these <script> tags more than once per page, + * so this is the perfect place for that. Instead of calling the script up + * to three times per page, we can do it only once. Yay performance! + * + * @param Skin $skin + * @param string $text + * @return bool + */ + public static function onSkinAfterBottomScripts( $skin, &$text ) { + if ( + self::$PAGE_HAS_ADS && + isset( $wgAdConfig['mode'] ) && + $wgAdConfig['mode'] == 'responsive' && + isset( $wgAdConfig['debug'] ) && + $wgAdConfig['debug'] === false + ) + { + $text .= '<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>' . "\n"; + } + return true; + } + + /** * Get the current skin's name for CSS ID & classes and system message names. * - * @return String: skin name in lowercase + * @return string Skin name in lowercase */ public static function determineSkin() { global $wgOut; @@ -692,13 +1226,11 @@ /** * Load ads for a defined "slot" - * Ad code (div element + JS) is echoed back and no value is returned - * except in special cases we return true (early return cases/unrecognized slot) + * Ad code (div element + JS) is returned, and in case if we hit an early + * return/unrecognized slot, we return an empty string. * - * @param $type String: what kind of ads to load? Valid values are: - * 'leaderboard', 'sidebar', 'toolbox-button' and - * 'right-column' (=skyscraper) so far - * @return String: HTML to output (if any) + * @param string $type What kind of ads to load? + * @return string HTML to output (if any) */ public static function loadAd( $type ) { // Early return cases: @@ -707,30 +1239,49 @@ // ** if the wiki's language code isn't supported by Google AdSense // ** if ads aren't enabled for the current namespace if ( !self::canShowAds() ) { + wfDebugLog( 'ShoutWikiAds', 'Early return case #1: can\'t show ads' ); return ''; } if ( !self::isSupportedLanguage() ) { + wfDebugLog( 'ShoutWikiAds', 'Early return case #2: language code is not suppored by AdSense' ); return ''; } if ( !self::isEnabledNamespace() ) { + wfDebugLog( 'ShoutWikiAds', 'Early return case #3: ads not enabled for this namespace' ); return ''; } // Main ad logic starts here - if( $type === 'leaderboard' ) { - return self::getLeaderboardHTML(); - } elseif( $type === 'sidebar' ) { - return self::getSidebarHTML(); - } elseif ( $type === 'toolbox-button' ) { - return self::getToolboxHTML(); - } elseif ( $type === 'right-column' ) { - return self::getSkyscraperHTML(); - } elseif ( $type === 'small-square' ) { - return self::getSmallSquareHTML(); - } else { // invalid type/these ads not enabled in $wgAdConfig - return ''; + $allowedAdTypes = array( + 'banner', 'leaderboard', 'sidebar', 'toolbox-button', + 'right-column', 'skyscraper', 'small-square', 'square', 'wide-skyscraper' + ); + if ( in_array( $type, $allowedAdTypes ) ) { + self::$PAGE_HAS_ADS = true; + } + + switch ( $type ) { + case 'banner': + return self::getBannerHTML(); + case 'leaderboard': + return self::getLeaderboardHTML(); + case 'sidebar': + return self::getSidebarHTML(); + case 'toolbox-button': + return self::getToolboxHTML(); + case 'right-column': // old and ugly name + case 'skyscraper': // standard name used by AdSense documentation, etc. + return self::getSkyscraperHTML(); + case 'small-square': + return self::getSmallSquareHTML(); + case 'square': + return self::getSquareHTML(); + case 'wide-skyscraper': + return self::getWideSkyscraperHTML(); + default: // invalid type/these ads not enabled in $wgAdConfig + return ''; } } diff --git a/ShoutWikiAds.php b/ShoutWikiAds.php index 6d5aa91..7fb106f 100644 --- a/ShoutWikiAds.php +++ b/ShoutWikiAds.php @@ -4,51 +4,67 @@ * * @file * @ingroup Extensions - * @version 0.3.3 - * @date 3 July 2013 + * @version 0.4.2 + * @date 25 December 2015 * @author Jack Phoenix <[email protected]> - * @license http://en.wikipedia.org/wiki/Public_domain Public domain - * @link http://www.mediawiki.org/wiki/Extension:ShoutWiki_Ads Documentation + * @license https://en.wikipedia.org/wiki/Public_domain Public domain + * @link https://www.mediawiki.org/wiki/Extension:ShoutWiki_Ads Documentation */ - -if ( !defined( 'MEDIAWIKI' ) ) { - die( 'Go away.' ); -} // Extension credits that will show up on Special:Version $wgExtensionCredits['other'][] = array( 'name' => 'ShoutWiki Ads', - 'namemsg' => 'shoutwikiads-extensionname', - 'version' => '0.3.3', + 'version' => '0.4.2', 'author' => 'Jack Phoenix', - 'descriptionmsg' => 'shoutwikiads-desc', + 'description' => 'Delicious advertisements for everyone!', 'url' => 'https://www.mediawiki.org/wiki/Extension:ShoutWiki_Ads', ); -$wgMessagesDirs['ShoutWikiAds'] = __DIR__ . '/i18n'; - // Autoload the class so that we can actually use its functions -$wgAutoloadClasses['ShoutWikiAds'] = dirname( __FILE__ ) . '/ShoutWikiAds.class.php'; +$wgAutoloadClasses['ShoutWikiAds'] = __DIR__ . '/ShoutWikiAds.class.php'; + +// CSS module loading for virtually all skins supported by this extension +$wgHooks['BeforePageDisplay'][] = 'ShoutWikiAds::setupAdCSS'; + +// Loads AdSense JS in the bottom of the page if a page has ads +$wgHooks['SkinAfterBottomScripts'][] = 'ShoutWikiAds::onSkinAfterBottomScripts'; + +// Aurora +$wgHooks['AuroraLeftSidebar'][] = 'ShoutWikiAds::onAuroraLeftSidebar'; +$wgHooks['SkinAfterContent'][] = 'ShoutWikiAds::onSkinAfterContent'; // BlueCloud was designed by StrategyWiki with ads in mind, so removing them // from it will mess up the display, which is exactly why we don't handle // BlueCloud ads here +// Dusk +$wgHooks['DuskAfterToolbox'][] = 'ShoutWikiAds::onDuskAfterToolbox'; + +// Home +$wgHooks['HomeAfterEverything'][] = 'ShoutWikiAds::onHomeAfterEverything'; + // Games $wgHooks['GamesSideBox'][] = 'ShoutWikiAds::onGamesSideBox'; + +// Metrolook +$wgHooks['MetrolookRightPanel'][] = 'ShoutWikiAds::onMetrolookRightPanel'; +$wgHooks['MetrolookAfterToolbox'][] = 'ShoutWikiAds::onMetrolookAfterToolbox'; // Monaco $wgHooks['MonacoSetupSkinUserCss'][] = 'ShoutWikiAds::setupAdCSS'; $wgHooks['MonacoSidebar'][] = 'ShoutWikiAds::onMonacoSidebar'; $wgHooks['MonacoFooter'][] = 'ShoutWikiAds::onMonacoFooter'; -// MonoBook -$wgHooks['BeforePageDisplay'][] = 'ShoutWikiAds::setupAdCSS'; +// MonoBook & Modern $wgHooks['MonoBookAfterContent'][] = 'ShoutWikiAds::onMonoBookAfterContent'; $wgHooks['MonoBookAfterToolbox'][] = 'ShoutWikiAds::onMonoBookAfterToolbox'; // Nimbus $wgHooks['NimbusLeftSide'][] = 'ShoutWikiAds::onNimbusLeftSide'; + +// Quartz +$wgHooks['QuartzSidebarWidgets'][] = 'ShoutWikiAds::onQuartzSidebarWidgets'; +$wgHooks['QuartzSidebarWidgetAdvertiser'][] = 'ShoutWikiAds::onQuartzSidebarWidgetAdvertiser'; // Truglass $wgHooks['TruglassInContent'][] = 'ShoutWikiAds::renderTruglassAd'; @@ -57,17 +73,46 @@ $wgHooks['VectorAfterToolbox'][] = 'ShoutWikiAds::onVectorAfterToolbox'; $wgHooks['VectorBeforeFooter'][] = 'ShoutWikiAds::onVectorBeforeFooter'; -// Generic (Cologne Blue, Modern, Monobook, Nimbus & Vector) leaderboard ad +// Generic leaderboard ad for most core skins and some custom skins $wgHooks['SiteNoticeAfter'][] = 'ShoutWikiAds::onSiteNoticeAfter'; // ResourceLoader support for MediaWiki 1.17+ $resourceTemplate = array( - 'localBasePath' => dirname( __FILE__ ), - 'remoteExtPath' => 'ShoutWikiAds' + 'localBasePath' => __DIR__, + 'remoteExtPath' => 'ShoutWikiAds', + 'position' => 'top' +); + +$wgResourceModules['ext.ShoutWikiAds.aurora.leaderboard'] = $resourceTemplate + array( + 'styles' => 'css/aurora-leaderboard-ad.css' +); + +$wgResourceModules['ext.ShoutWikiAds.aurora.skyscraper'] = $resourceTemplate + array( + 'styles' => 'css/aurora-skyscraper-ad.css' ); $wgResourceModules['ext.ShoutWikiAds.cologneblue.leaderboard'] = $resourceTemplate + array( 'styles' => 'css/cologneblue-leaderboard-ad.css' +); + +$wgResourceModules['ext.ShoutWikiAds.home.leaderboard-bottom'] = $resourceTemplate + array( + 'styles' => 'css/home-leaderboard-bottom-ad.css' +); + +$wgResourceModules['ext.ShoutWikiAds.home.skyscraper'] = $resourceTemplate + array( + 'styles' => 'css/home-skyscraper-ad.css' +); + +$wgResourceModules['ext.ShoutWikiAds.metrolook.button'] = $resourceTemplate + array( + 'styles' => 'css/metrolook-button-ad.css' +); + +$wgResourceModules['ext.ShoutWikiAds.metrolook.leaderboard'] = $resourceTemplate + array( + 'styles' => 'css/metrolook-leaderboard-ad.css' +); + +$wgResourceModules['ext.ShoutWikiAds.metrolook.wide-skyscraper'] = $resourceTemplate + array( + 'styles' => 'css/metrolook-wide-skyscraper-ad.less' ); $wgResourceModules['ext.ShoutWikiAds.modern.button'] = $resourceTemplate + array( @@ -90,6 +135,10 @@ 'styles' => 'css/monobook-skyscraper-ad.css' ); +$wgResourceModules['ext.ShoutWikiAds.quartz.square'] = $resourceTemplate + array( + 'styles' => 'css/quartz-square-ad.css' +); + $wgResourceModules['ext.ShoutWikiAds.vector.button'] = $resourceTemplate + array( 'styles' => 'css/vector-button-ad.css' ); @@ -98,8 +147,8 @@ 'styles' => 'css/vector-skyscraper-ad.css' ); -$wgResourceModules['ext.ShoutWikiAds.truglass'] = $resourceTemplate + array( - 'styles' => 'css/truglass-ads.css' +$wgResourceModules['ext.ShoutWikiAds.truglass.leaderboard'] = $resourceTemplate + array( + 'styles' => 'css/truglass-leaderboard-ad.css' ); /* Configuration @@ -107,6 +156,7 @@ 'enabled' => true, // enabled or not? :P 'adsense-client' => '', // provider number w/o the "pub-" part 'namespaces' => array( NS_MAIN, NS_TALK ), // array of enabled namespaces + 'mode' => 'static', // set to 'responsive' for responsive ads instead of fixed-width ads // set this to true when developing locally to serve ad *images* (as // opposed to JS code to render ads) from Google's servers @@ -118,15 +168,24 @@ 'monobook-button-ad-slot' => '', // 125x125 Monobook ad slot number [Montecito] 'vector-button-ad-slot' => '', // 125x125 Vector ad slot number [Montecito] - 'monobook-skyscraper-ad-slot' => '', [Dothan] - 'vector-skyscraper-ad-slot' => '', [Dothan] + 'monobook-skyscraper-ad-slot' => '', // [Dothan] + 'vector-skyscraper-ad-slot' => '', // [Dothan] - 'truglass-leaderboard-ad-slot' => '', [Tabor] + 'truglass-leaderboard-ad-slot' => '', // [Tabor] // Skin-specific ad configuration + 'aurora' => array( + 'leaderboard' => true, // leaderboard ad in the site notice area + 'leaderboard-bottom' => true, // leaderboard ad after categories, in the bottom of the page + 'skyscraper' => true, // skyscraper ad in the left column, below "Page history" on longer pages + ), 'cologneblue' => array( 'leaderboard' => true, // leaderboard ad in the site notice area ), + 'dusk' => array( + 'banner' => true, // banner in the site notice area + 'toolbox' => true, // small 125x125px ad below the toolbox in the right-hand sidebar + ), 'modern' => array( 'leaderboard' => true, // leaderboard ad in the site notice area ), diff --git a/css/aurora-leaderboard-ad.css b/css/aurora-leaderboard-ad.css new file mode 100644 index 0000000..f5534fc --- /dev/null +++ b/css/aurora-leaderboard-ad.css @@ -0,0 +1,5 @@ +/** Leaderboard ad styling for the Aurora skin */ +#aurora-leaderboard-ad-2 { + margin: 5px; + text-align: center; +} \ No newline at end of file diff --git a/css/aurora-skyscraper-ad.css b/css/aurora-skyscraper-ad.css new file mode 100644 index 0000000..a7f9cde --- /dev/null +++ b/css/aurora-skyscraper-ad.css @@ -0,0 +1,14 @@ +/** Skyscraper ad styling for the Aurora skin */ +#column-google { + height: 600px; + margin-bottom: 10px; + margin-left: -15px; + margin-right: 10px; + margin-top: 10px; + width: 120px; +} + +/* Need to stretch the content area a "bit" to make the skyscraper fit in the left-hand sidebar... */ +div#content { + min-height: 1000px; +} \ No newline at end of file diff --git a/css/cologneblue-leaderboard-ad.css b/css/cologneblue-leaderboard-ad.css new file mode 100644 index 0000000..0a37425 --- /dev/null +++ b/css/cologneblue-leaderboard-ad.css @@ -0,0 +1,7 @@ +/** + * Leaderboard ad styling for the Cologne Blue skin + */ +#cologneblue-leaderboard-ad { + padding-top: 5px; + text-align: center; +} \ No newline at end of file diff --git a/css/home-leaderboard-bottom-ad.css b/css/home-leaderboard-bottom-ad.css new file mode 100644 index 0000000..3845992 --- /dev/null +++ b/css/home-leaderboard-bottom-ad.css @@ -0,0 +1,6 @@ +/** + * Bottom leaderboard ad styling for the Home skin + */ +div#home-leaderboard-ad { + margin-left: -5px; +} \ No newline at end of file diff --git a/css/home-skyscraper-ad.css b/css/home-skyscraper-ad.css new file mode 100644 index 0000000..ef014a7 --- /dev/null +++ b/css/home-skyscraper-ad.css @@ -0,0 +1,23 @@ +/** + * Skyscraper ad styling for the Home skin + */ +.column-google-left { + float: left; + width: 120px; + height: 600px; + left: 200px; + position: absolute; + top: 150px; + z-index: 1; +} + +.column-google-right { + float: right; + right: 200px; + top: 150px; + width: 120px; + height: 600px; + float: left; + position: absolute; + z-index: 1; +} \ No newline at end of file diff --git a/css/metrolook-button-ad.css b/css/metrolook-button-ad.css new file mode 100644 index 0000000..4385dbd --- /dev/null +++ b/css/metrolook-button-ad.css @@ -0,0 +1,12 @@ +/** + * Button ad styling for the Metrolook skin + */ +#p-ads-left { + padding-left: 5px; + margin-top: 20px; + margin-bottom: 20px; + right: 0px; + text-align: center; + width: 150px; + z-index: 1; +} diff --git a/css/metrolook-leaderboard-ad.css b/css/metrolook-leaderboard-ad.css new file mode 100644 index 0000000..da83606 --- /dev/null +++ b/css/metrolook-leaderboard-ad.css @@ -0,0 +1,5 @@ +@media screen and (max-width: 800px) { + div#metrolook-leaderboard-ad { + padding-top: 30px; + } +} \ No newline at end of file diff --git a/css/metrolook-wide-skyscraper-ad.less b/css/metrolook-wide-skyscraper-ad.less new file mode 100644 index 0000000..3425c02 --- /dev/null +++ b/css/metrolook-wide-skyscraper-ad.less @@ -0,0 +1,30 @@ +/* Right panel (wide skyscraper ad column, 160x600px by default) */ +div#mw-panel-right { + display: none; + position: absolute; + top: 40px; + bottom: 0px; + height: auto; + overflow: hidden; + padding-top: 0.25em; + width: 160px; + right: 0; + z-index: 5; +} + +/** + * Don't show the wide skyscraper ad for mobile and other lame clients + * The usage of the @media query here is the reason why this is a LESS file + * and not a CSS file. With a .css file ext, only the first rule (!) would be + * inside the media rule container. + */ +@media screen and (min-width: 1300px) { + div#mw-panel-right { + display: block; + } + + /* Don't have page content obscured by the ad column... */ + div#content { + width: 73%; + } +} \ No newline at end of file diff --git a/css/modern-button-ad.css b/css/modern-button-ad.css new file mode 100644 index 0000000..71bd040 --- /dev/null +++ b/css/modern-button-ad.css @@ -0,0 +1,9 @@ +/** + * Button ad styling for the Modern skin + */ +#p-ads-left { + right: 0px; + top: 10px; + z-index: 1; + text-align: center; +} \ No newline at end of file diff --git a/css/modern-leaderboard-ad.css b/css/modern-leaderboard-ad.css new file mode 100644 index 0000000..a8ee38d --- /dev/null +++ b/css/modern-leaderboard-ad.css @@ -0,0 +1,7 @@ +/** + * Leaderboard ad styling for the Modern skin + */ +#modern-leaderboard-ad { + padding-top: 5px; + text-align: center; +} \ No newline at end of file diff --git a/css/monobook-button-ad.css b/css/monobook-button-ad.css index 9e466d6..8d17373 100644 --- a/css/monobook-button-ad.css +++ b/css/monobook-button-ad.css @@ -6,4 +6,5 @@ top: 10px; width: 150px; z-index: 1; -} \ No newline at end of file + text-align: center; +} diff --git a/css/monobook-skyscraper-ad.css b/css/monobook-skyscraper-ad.css index b179fac..4cb1cfa 100644 --- a/css/monobook-skyscraper-ad.css +++ b/css/monobook-skyscraper-ad.css @@ -1,19 +1,17 @@ /** * Skyscraper ad styling for Monobook skin */ -#content { +div#content { + border-right: solid 1px #aaaaaa !important; /* yes, the important is needed...lame */ margin-top: 2.8em !important; margin-right: 125px !important; margin-bottom: 0 !important; margin-left: 12.2em !important; } -#content { - border-right: solid 1px rgb(170,170,170); -} - #column-google { width: 120px; + height: 600px; clear: left; position: absolute; padding-top: 35px; @@ -27,5 +25,5 @@ } #footer { - width: 91%; -} \ No newline at end of file + width: 90%; +} diff --git a/css/quartz-square-ad.css b/css/quartz-square-ad.css new file mode 100644 index 0000000..c1f307a --- /dev/null +++ b/css/quartz-square-ad.css @@ -0,0 +1,4 @@ +/** Styling for Quartz's ads -- the selector also matches the sitenotice leaderboard, but that's perfectly fine */ +.quartz-ad { + text-align: center; +} \ No newline at end of file diff --git a/css/truglass-leaderboard-ad.css b/css/truglass-leaderboard-ad.css new file mode 100644 index 0000000..ccdddc9 --- /dev/null +++ b/css/truglass-leaderboard-ad.css @@ -0,0 +1,22 @@ +#truglass-leaderboard-ad { + text-align: center; + padding-top: 3px; + padding-bottom: 5px; +} + +table.truglass-ad-container { + border-collapse: collapse; /* cellspacing=0 equivalent */ +} + +table.truglass-ad-container td { + border: none; + outline: none; +} + +table.truglass-ad-container td, table.truglass-ad-container th { + padding: 0; /* cellpadding=0 equivalent */ +} + +td#contentBox { + vertical-align: top; +} \ No newline at end of file diff --git a/css/vector-button-ad.css b/css/vector-button-ad.css new file mode 100644 index 0000000..03cbc8b --- /dev/null +++ b/css/vector-button-ad.css @@ -0,0 +1,10 @@ +/** + * Button ad styling for the Vector skin + */ +#p-ads-left { + margin-bottom: 20px; + right: 0px; + text-align: center; + width: 150px; + z-index: 1; +} diff --git a/css/vector-skyscraper-ad.css b/css/vector-skyscraper-ad.css new file mode 100644 index 0000000..05b0a59 --- /dev/null +++ b/css/vector-skyscraper-ad.css @@ -0,0 +1,27 @@ +/** + * Skyscraper ad styling for the Vector skin + */ +div#content { + border-right: solid 1px #a7d7f9 !important; /* the color is from skins/vector/images/border.png */ + margin-right: 125px !important; +} + +#column-google { + width: 120px; + height: 600px; + clear: left; + position: absolute; + padding-top: 0px; + padding-right: 0px; + padding-bottom: 0px; + padding-left: 3px; + float: right; + right: 0px; + top: 85px; + z-index: 1; +} + +#footer { + /* 75% is not enough, 76% is too much... */ + width: 75.5%; +} -- To view, visit https://gerrit.wikimedia.org/r/272729 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If0f8e72389ede63a98eb4d08b209633e314b839e Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/ShoutWikiAds Gerrit-Branch: master Gerrit-Owner: Jack Phoenix <[email protected]> _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
