/**
  * BeforePageDisplay hook handler
  * @see https://www.mediawiki.org/wiki/Manual:Hooks/BeforePageDisplay
  *
  * @param OutputPage $out
  * @param Skin $sk
  * @return bool
  */
 public static function onBeforePageDisplay(&$out, &$sk)
 {
     global $wgWPBSkinBlacklist, $wgWPBEnableDefaultBanner;
     $context = MobileContext::singleton();
     $config = $context->getMFConfig();
     $mfEnableXAnalyticsLogging = $config->get('MFEnableXAnalyticsLogging');
     $mfAppPackageId = $config->get('MFAppPackageId');
     $mfAppScheme = $config->get('MFAppScheme');
     $mfNoIndexPages = $config->get('MFNoindexPages');
     $mfMobileUrlTemplate = $context->getMobileUrlTemplate();
     $tabletSize = $config->get('MFDeviceWidthTablet');
     // show banners using WikidataPageBanner, if installed and all pre-conditions fulfilled
     if (ExtensionRegistry::getInstance()->isLoaded('WikidataPageBanner') && $context->isBetaGroupMember()) {
         // turn default banners on
         $wgWPBEnableDefaultBanner = true;
         // Turn on the banner experiment
         $needle = array_search('minerva', $wgWPBSkinBlacklist);
         if ($needle !== false) {
             unset($wgWPBSkinBlacklist[$needle]);
         }
     }
     $title = $sk->getTitle();
     $request = $context->getRequest();
     // Migrate prefixed disableImages cookie to unprefixed cookie.
     if (isset($_COOKIE[$config->get('CookiePrefix') . 'disableImages'])) {
         if ((bool) $request->getCookie('disableImages')) {
             $context->setDisableImagesCookie(true);
         }
         $request->response()->clearCookie('disableImages');
     }
     # Add deep link to a mobile app specified by $wgMFAppScheme
     if ($mfAppPackageId !== false && $title->isContentPage() && $request->getRawQueryString() === '') {
         $fullUrl = $title->getFullURL();
         $mobileUrl = $context->getMobileUrl($fullUrl);
         $path = preg_replace("/^([a-z]+:)?(\\/)*/", '', $mobileUrl, 1);
         $scheme = 'http';
         if ($mfAppScheme !== false) {
             $scheme = $mfAppScheme;
         } else {
             $protocol = $request->getProtocol();
             if ($protocol != '') {
                 $scheme = $protocol;
             }
         }
         $hreflink = 'android-app://' . $mfAppPackageId . '/' . $scheme . '/' . $path;
         $out->addLink(array('rel' => 'alternate', 'href' => $hreflink));
     }
     // an canonical/alternate link is only useful, if the mobile and desktop URL are different
     // and $wgMFNoindexPages needs to be true
     if ($mfMobileUrlTemplate && $mfNoIndexPages) {
         if (!$context->shouldDisplayMobileView()) {
             // add alternate link to desktop sites - bug T91183
             $desktopUrl = $title->getFullUrl();
             $link = array('rel' => 'alternate', 'media' => 'only screen and (max-width: ' . $tabletSize . 'px)', 'href' => $context->getMobileUrl($desktopUrl));
         } else {
             // add canonical link to mobile pages, instead of noindex - bug T91183
             $link = array('rel' => 'canonical', 'href' => $title->getFullUrl());
         }
         $out->addLink($link);
     }
     // Set X-Analytics HTTP response header if necessary
     if ($context->shouldDisplayMobileView()) {
         $analyticsHeader = $mfEnableXAnalyticsLogging ? $context->getXAnalyticsHeader() : false;
         if ($analyticsHeader) {
             $resp = $out->getRequest()->response();
             $resp->header($analyticsHeader);
         }
         // in mobile view: always add vary header
         $out->addVaryHeader('Cookie');
         // Allow modifications in mobile only mode
         Hooks::run('BeforePageDisplayMobile', array(&$out, &$sk));
     }
     return true;
 }
 /**
  * BeforePageDisplay hook handler
  * @see https://www.mediawiki.org/wiki/Manual:Hooks/BeforePageDisplay
  *
  * @param OutputPage $out
  * @param Skin $sk
  * @return bool
  */
 public static function onBeforePageDisplay(&$out, &$sk)
 {
     $context = MobileContext::singleton();
     $config = $context->getMFConfig();
     $mfEnableXAnalyticsLogging = $config->get('MFEnableXAnalyticsLogging');
     $mfAppPackageId = $config->get('MFAppPackageId');
     $mfAppScheme = $config->get('MFAppScheme');
     $mfNoIndexPages = $config->get('MFNoindexPages');
     $mfMobileUrlTemplate = $context->getMobileUrlTemplate();
     $tabletSize = $config->get('MFDeviceWidthTablet');
     $title = $sk->getTitle();
     $request = $context->getRequest();
     # Add deep link to a mobile app specified by $wgMFAppScheme
     if ($mfAppPackageId !== false && $title->isContentPage() && $request->getRawQueryString() === '') {
         $fullUrl = $title->getFullURL();
         $mobileUrl = $context->getMobileUrl($fullUrl);
         $path = preg_replace("/^([a-z]+:)?(\\/)*/", '', $mobileUrl, 1);
         $scheme = 'http';
         if ($mfAppScheme !== false) {
             $scheme = $mfAppScheme;
         } else {
             $protocol = $request->getProtocol();
             if ($protocol != '') {
                 $scheme = $protocol;
             }
         }
         $hreflink = 'android-app://' . $mfAppPackageId . '/' . $scheme . '/' . $path;
         $out->addLink(array('rel' => 'alternate', 'href' => $hreflink));
     }
     // an canonical/alternate link is only useful, if the mobile and desktop URL are different
     // and $wgMFNoindexPages needs to be true
     if ($mfMobileUrlTemplate && $mfNoIndexPages) {
         if (!$context->shouldDisplayMobileView()) {
             // add alternate link to desktop sites - bug T91183
             $desktopUrl = $title->getFullUrl();
             $link = array('rel' => 'alternate', 'media' => 'only screen and (max-width: ' . $tabletSize . 'px)', 'href' => $context->getMobileUrl($desktopUrl));
         } else {
             // add canonical link to mobile pages, instead of noindex - bug T91183
             $link = array('rel' => 'canonical', 'href' => $title->getFullUrl());
         }
         $out->addLink($link);
     }
     // Set X-Analytics HTTP response header if necessary
     if ($context->shouldDisplayMobileView()) {
         $analyticsHeader = $mfEnableXAnalyticsLogging ? $context->getXAnalyticsHeader() : false;
         if ($analyticsHeader) {
             $resp = $out->getRequest()->response();
             $resp->header($analyticsHeader);
         }
         // in mobile view: always add vary header
         $out->addVaryHeader('Cookie');
     }
     return true;
 }