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