jenkins-bot has submitted this change and it was merged.

Change subject: bannerChoiceData and bannerController.lib modules
......................................................................


bannerChoiceData and bannerController.lib modules

Also introduces two new globals:

$wgCentralNoticeChooseBannerOnClient: Enable choosing banners on the
  client. In this patch, leaving it set to false (the default)
  prevents the sending of banner choice data.

$wgCentralNoticeBannerChoiceDataCacheExpiry: Seconds to cache the
  banner choice data in memcached.

This is part of a series of changes to shift banner selection partly
to the client. This change itself does not modify CN functionality
when serving banners.

Change-Id: If942f571df57410b6b6e3ba27b3c160fc37d881c
---
M CentralNotice.hooks.php
M CentralNotice.modules.php
M CentralNotice.php
A includes/CNBannerChoiceDataResourceLoaderModule.php
M modules/ext.centralNotice.bannerController/bannerController.js
A modules/ext.centralNotice.bannerController/bannerController.lib.js
6 files changed, 253 insertions(+), 0 deletions(-)

Approvals:
  Awight: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/CentralNotice.hooks.php b/CentralNotice.hooks.php
index 87a1c59..9f51cac 100644
--- a/CentralNotice.hooks.php
+++ b/CentralNotice.hooks.php
@@ -70,6 +70,7 @@
        $wgAutoloadClasses[ 'BannerChooser' ] = $includeDir . 
'BannerChooser.php';
        $wgAutoloadClasses[ 'BannerRenderer' ] = $includeDir . 
'BannerRenderer.php';
        $wgAutoloadClasses[ 'BannerChoiceDataProvider' ] = $includeDir . 
'BannerChoiceDataProvider.php';
+       $wgAutoloadClasses[ 'CNBannerChoiceDataResourceLoaderModule' ] = 
$includeDir . 'CNBannerChoiceDataResourceLoaderModule.php';
        $wgAutoloadClasses[ 'Campaign' ] = $includeDir . 'Campaign.php';
        $wgAutoloadClasses[ 'CampaignLog' ] = $includeDir . 'CampaignLog.php';
        $wgAutoloadClasses[ 'GeoTarget' ] = $includeDir . 'GeoTarget.php';
@@ -226,6 +227,8 @@
        // Using global $wgUser for compatibility with 1.18
        global $wgNoticeProject, $wgUser, $wgMemc;
 
+       // FIXME Is this no longer used anywhere in JS following the switch to
+       // client-side banner selection? If so, remove it.
        $vars[ 'wgNoticeProject' ] = $wgNoticeProject;
 
        // Output the user's registration date, total edit count, and past 
year's edit count.
diff --git a/CentralNotice.modules.php b/CentralNotice.modules.php
index 50f1bb1..c631063 100644
--- a/CentralNotice.modules.php
+++ b/CentralNotice.modules.php
@@ -123,8 +123,22 @@
        'dependencies'  => array(
                'jquery.cookie',
                'json',
+               'ext.centralNotice.bannerController.lib',
+               'ext.centralNotice.bannerChoiceData'
        ),
 );
+$wgResourceModules[ 'ext.centralNotice.bannerChoiceData' ] = array(
+       // The following settings are brought in via this PHP class:
+       // 'position' => 'top',
+       // 'dependencies' => array( 'ext.centralNotice.bannerController.lib' )
+       'class'         => 'CNBannerChoiceDataResourceLoaderModule'
+);
+$wgResourceModules[ 'ext.centralNotice.bannerController.lib' ] = array(
+       'localBasePath' => $dir . '/modules/ext.centralNotice.bannerController',
+       'remoteExtPath' => 
'CentralNotice/modules/ext.centralNotice.bannerController',
+       'scripts'       => 'bannerController.lib.js',
+       'position'      => 'top'
+);
 $wgResourceModules[ 'ext.centralNotice.adminUi.campaignManager' ] = array(
        'localBasePath' => $dir . '/modules',
        'remoteExtPath' => 'CentralNotice/modules',
diff --git a/CentralNotice.php b/CentralNotice.php
index 100dfb0..e659a3b 100644
--- a/CentralNotice.php
+++ b/CentralNotice.php
@@ -89,6 +89,19 @@
 // Leave this set to false to use the Web API instead.
 $wgCentralNoticeInfrastructureId = false;
 
+// The API path on the wiki that hosts the CentralNotice infrastructure
+// For example 'http://meta.wikimedia.org/api.php'
+// This must be set if you enable the selection of banners on the client and
+// you don't have direct access to the infrastructure database (see
+// $wgCentralNoticeInfrastructureId).
+$wgCentralNoticeApiUrl = false;
+
+// How long to cache the banner choice data in memcached, in seconds
+$wgCentralNoticeBannerChoiceDataCacheExpiry = 300;
+
+// Enable the new mechanism for making the banner selection on the client
+$wgCentralNoticeChooseBannerOnClient = false;
+
 // Enable the loader itself
 // Allows to control the loader visibility, without destroying infrastructure
 // for cached content
diff --git a/includes/CNBannerChoiceDataResourceLoaderModule.php 
b/includes/CNBannerChoiceDataResourceLoaderModule.php
new file mode 100644
index 0000000..2251868
--- /dev/null
+++ b/includes/CNBannerChoiceDataResourceLoaderModule.php
@@ -0,0 +1,201 @@
+<?php
+
+/***
+ * ResourceLoader module for sending banner choices to the client.
+ *
+ * Note: this module does nothing if $wgCentralNoticeChooseBannerOnClient
+ * is false.
+ *
+ * HTTP query and caching modeled after EventLogging's RemoteSchema class.
+ * See 
https://github.com/wikimedia/mediawiki-extensions-EventLogging/blob/master/includes/RemoteSchema.php
+ */
+class CNBannerChoiceDataResourceLoaderModule extends ResourceLoaderModule {
+
+       /**
+        * @see ResourceLoaderModule::targets
+        */
+       protected $targets = array( 'desktop', 'mobile' );
+
+       const API_REQUEST_TIMEOUT = 20;
+
+       protected $choices;
+       protected $key;
+
+       public function __construct() {
+               $this->http = new Http();
+       }
+
+       protected function getChoices( ResourceLoaderContext $context ) {
+               global $wgNoticeProject,
+                       $wgUser,
+                       $wgCentralNoticeInfrastructureId,
+                       $wgCentralNoticeApiUrl,
+                       $wgCentralNoticeBannerChoiceDataCacheExpiry;
+
+               $project = $wgNoticeProject;
+               $language = $context->getLanguage();
+
+               // TODO Find out what's up with $context->getUser()
+               $status = ( $wgUser->isAnon() ) ? 'anonymous' : 'loggedin';
+               $key = $wgNoticeProject . '|' . $language . '|' .  $status;
+
+               // Get via state variable if it's there and the key is the same
+               if ( ( $this->key === $key ) && $this->choices ) {
+                       return $this->choices;
+               }
+
+               $this->key = $key;
+
+               // Hmmm, try the cache (if configured to)
+               $useCache = ( $wgCentralNoticeBannerChoiceDataCacheExpiry !== 0 
);
+
+               if ( $useCache ) {
+
+                       $cache = wfGetCache( CACHE_ANYTHING );
+                       $this->choices = $cache->get( $key );
+
+                       if ( $this->choices ) {
+                               return $this->choices;
+                       }
+               }
+
+               // OK, fetch the data via the DB or the API. Decide which to 
use based
+               // on whether the appropriate global variables are set.
+               // If something's amiss, we warn and return an empty array, but 
don't
+               // bring everything to a standstill.
+
+               if ( $wgCentralNoticeInfrastructureId ) {
+                        $choices = $this->getFromDb( $project, $language, 
$status );
+
+               } else if ( $wgCentralNoticeApiUrl ) {
+
+                       $choices = $this->getFromApi( $project, $language, 
$status );
+
+                       if ( !$choices ) {
+                               wfLogWarning( 'Couldn\'t fetch banner choice 
data via API. ' .
+                                       '$$wgCentralNoticeApiUrl = ' . 
$wgCentralNoticeApiUrl );
+
+                               return array();
+                       }
+
+               } else {
+                       // No way to get the choices?
+                       wfLogWarning( 'No route to fetch banner choice data 
configured.' );
+                       return array();
+               }
+
+               if ( $useCache ) {
+                       $cache->set( $key, $choices,
+                               $wgCentralNoticeBannerChoiceDataCacheExpiry );
+               }
+
+               $this->choices = $choices;
+               return $choices;
+       }
+
+       /**
+        * Get the banner choices data via a direct DB call using
+        * $wgCentralNoticeInfrastructureId.
+        *
+        * @param string $project
+        * @param string $language
+        * @param string $status Can be 'loggedin' or 'anonymous'
+        */
+       protected function getFromDb( $project, $language, $status ) {
+
+               $status = ( $status === 'loggedin' ) ?
+                       BannerChoiceDataProvider::LOGGED_IN :
+                       BannerChoiceDataProvider::ANONYMOUS;
+
+               $choicesProvider = new BannerChoiceDataProvider(
+                       $project, $language, $status,
+                       BannerChoiceDataProvider::USE_INFRASTRUCTURE_DB );
+
+               return $choicesProvider->getChoices();
+       }
+
+       /**
+        * Get the banner choices data via an API call to the infrastructure 
wiki.
+        * If the call fails, we return false.
+        *
+        * @param string $project
+        * @param string $language
+        * @param string $status Can be 'loggedin' or 'anonymous'
+        *
+        * @return array|boolean
+        */
+       protected function getFromApi( $project, $language, $status ) {
+               global $wgCentralNoticeApiUrl;
+
+               // Make the URl
+               $q = array(
+                       'action' => 'centralnoticebannerchoicedata',
+                       'project' => $project,
+                       'language' => $language,
+                       'status' => $status,
+                       'format' => 'json'
+               );
+
+               $url = wfAppendQuery( $wgCentralNoticeApiUrl, $q );
+               $http = new Http();
+               $apiResult = $http->get( $url, self::API_REQUEST_TIMEOUT * 0.8 
);
+
+               if ( !$apiResult ) {
+                       return false;
+               }
+
+               $parsedApiResult = FormatJson::parse( $apiResult ) ?: false;
+
+               if ( !isset( $parsedApiResult->value ) ) {
+                       wfLogWarning( 'Error fetching banner choice data via 
API: ' .
+                               'no "value" property in result object.' );
+
+                       return false;
+               }
+
+               $result = $parsedApiResult->value;
+
+               if ( isset( $result->error ) ) {
+                       wfLogWarning( 'Error fetching banner choice data via 
API: ' .
+                               $result->error->info . ': ' . 
$result->error->code );
+
+                       return false;
+               }
+
+               return $result; 
+       }
+
+       /**
+        * This is a no-op if $wgCentralNoticeChooseBannerOnClient is false
+        *
+        * @see ResourceLoaderModule::getScript()
+        */
+       public function getScript( ResourceLoaderContext $context ) {
+               global $wgCentralNoticeChooseBannerOnClient;
+
+               // Only send in data if we'll choose banners on the client
+               if ( $wgCentralNoticeChooseBannerOnClient ) {
+
+                       return Xml::encodeJsCall( 
'mw.cnBannerControllerLib.setChoiceData',
+                                       array( $this->getChoices( $context ) ) 
);
+
+               } else {
+                       // Otherwise, make this a no-op
+                       return '';
+               }
+       }
+
+       /**
+        * @see ResourceLoaderModule::getPosition()
+        */
+       public function getPosition() {
+               return 'top';
+       }
+
+       /**
+        * @see ResourceLoaderModule::getDependencies()
+        */
+       public function getDependencies() {
+               return array( 'ext.centralNotice.bannerController.lib' );
+       }
+}
\ No newline at end of file
diff --git a/modules/ext.centralNotice.bannerController/bannerController.js 
b/modules/ext.centralNotice.bannerController/bannerController.js
index 556b288..8aca1f2 100644
--- a/modules/ext.centralNotice.bannerController/bannerController.js
+++ b/modules/ext.centralNotice.bannerController/bannerController.js
@@ -77,6 +77,10 @@
                };
        } ).apply( null, ( $.cookie( 'GeoIP' ) || '' ).match( 
/([^:]*):([^:]*):([^:]*):([^:]*):([^;]*)/ || [] ) );
 
+       // FIXME Following the switch to client-side banner selection, it would
+       // make more sense for this to be defined in bannerController.lib. 
Before
+       // changing it and moving these methods to an inner property thereof,
+       // let's make very sure that won't cause problems, here or elsewhere.
        mw.centralNotice = {
                /**
                 * Central Notice Required Data
diff --git a/modules/ext.centralNotice.bannerController/bannerController.lib.js 
b/modules/ext.centralNotice.bannerController/bannerController.lib.js
new file mode 100644
index 0000000..bd53bfb
--- /dev/null
+++ b/modules/ext.centralNotice.bannerController/bannerController.lib.js
@@ -0,0 +1,18 @@
+( function ( $, mw ) {
+
+       // FIXME Temporary location of this object on the mw hierarchy. See 
FIXME
+       // in bannerController.js.
+       mw.cnBannerControllerLib = {
+
+               /**
+                * Set possible campaign and banner choices. Called by
+                * ext.centralNotice.bannerChoices.
+                */
+               'setChoiceData': function ( choices ) {
+                       this.choiceData = choices;
+               },
+
+               'choiceData': null
+       };
+
+} )( jQuery, mediaWiki );
\ No newline at end of file

-- 
To view, visit https://gerrit.wikimedia.org/r/172299
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: If942f571df57410b6b6e3ba27b3c160fc37d881c
Gerrit-PatchSet: 10
Gerrit-Project: mediawiki/extensions/CentralNotice
Gerrit-Branch: master
Gerrit-Owner: AndyRussG <[email protected]>
Gerrit-Reviewer: AndyRussG <[email protected]>
Gerrit-Reviewer: Awight <[email protected]>
Gerrit-Reviewer: Ejegg <[email protected]>
Gerrit-Reviewer: Katie Horn <[email protected]>
Gerrit-Reviewer: Mwalker <[email protected]>
Gerrit-Reviewer: Ssmith <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to