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

Change subject: Revert "Revert "Merge branch 'master' into deployment""
......................................................................


Revert "Revert "Merge branch 'master' into deployment""

This reverts commit 5630b749388391c44193359abbf17336317f4e1d.

Change-Id: I583965ca942ec377cb9dd3ba78f76855c4980f67
---
M DonationInterface.php
M amazon_gateway/amazon.api.php
M amazon_gateway/amazon.js
M amazon_gateway/amazon_gateway.body.php
A extras/banner_history/BannerHistoryLogIdProcessor.php
M gateway_common/GatewayPage.php
M gateway_common/MessageUtils.php
M gateway_common/WmfFramework.drupal.php
M gateway_common/WmfFramework.mediawiki.php
M gateway_common/gateway.adapter.php
M gateway_common/i18n/interface/ast.json
M gateway_common/i18n/interface/de.json
M gateway_common/i18n/interface/en.json
M gateway_common/i18n/interface/es.json
M gateway_common/i18n/interface/fr.json
M gateway_common/i18n/interface/he.json
M gateway_common/i18n/interface/it.json
M gateway_common/i18n/interface/mk.json
M gateway_common/i18n/interface/mr.json
M gateway_common/i18n/interface/pl.json
M gateway_common/i18n/interface/qqq.json
M gateway_common/i18n/interface/sr-ec.json
M gateway_common/i18n/interface/zh-hans.json
M gateway_forms/mustache/index.html.mustache
M globalcollect_gateway/globalcollect_resultswitcher.body.php
M paypal_gateway/i18n/sr-ec.json
M paypal_gateway/paypal_resultswitcher.body.php
M worldpay_gateway/forms/js/esop.js
M worldpay_gateway/worldpay.adapter.php
M worldpay_gateway/worldpay_gateway.body.php
M worldpay_gateway/worldpay_resultswitcher.body.php
31 files changed, 230 insertions(+), 43 deletions(-)

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



diff --git a/DonationInterface.php b/DonationInterface.php
index c5dfa3a..39657a7 100644
--- a/DonationInterface.php
+++ b/DonationInterface.php
@@ -121,6 +121,8 @@
 $wgAutoloadClasses['Gateway_Extras_CustomFilters_Functions'] = __DIR__ . 
'/extras/custom_filters/filters/functions/functions.body.php';
 $wgAutoloadClasses['Gateway_Extras_CustomFilters_IP_Velocity'] = __DIR__ . 
'/extras/custom_filters/filters/ip_velocity/ip_velocity.body.php';
 
+$wgAutoloadClasses['BannerHistoryLogIdProcessor'] = __DIR__ . 
'/extras/banner_history/BannerHistoryLogIdProcessor.php';
+
 $wgAutoloadClasses['Gateway_Extras_SessionVelocityFilter'] = __DIR__ . 
'/extras/session_velocity/session_velocity.body.php';
 $wgAutoloadClasses['GatewayFormChooser'] = __DIR__ . 
'/special/GatewayFormChooser.php';
 $wgAutoloadClasses['SystemStatus'] = __DIR__ . '/special/SystemStatus.php';
@@ -386,6 +388,8 @@
  */
 $wgWorldpayGatewayNoFraudIntegrationTest = false;
 
+$wgWorldpayGatewayTokenTimeout = '1800000';
+
 /*
 $wgWorldpayGatewayAccountInfo['default'] = array(
        'Test' => 1,
@@ -510,8 +514,14 @@
        // These messages will be shoved into the fraud database (see
        // crm/modules/fredge).
        'payments-antifraud' => array(),
+
        // These are shoved into the payments-initial database.
        'payments-init' => array(),
+
+       // Banner history log ID-contribution tracking ID associations that go 
in
+       // Drupal in banner_history_contribution_associations. See
+       // crm/modules/queue2civicrm/banner_history
+       'banner-history' => array(),
 );
 
 //Custom Filters globals
@@ -793,6 +803,8 @@
 $wgDonationInterfaceGatewayAdapters[] = 'WorldpayAdapter';
 
 //Custom Filters hooks
+$wgHooks['GatewayReady'][] = array( 
'BannerHistoryLogIdProcessor::onGatewayReady' );
+
 $wgHooks['GatewayValidate'][] = array( 
'Gateway_Extras_CustomFilters::onValidate' );
 
 $wgHooks['GatewayCustomFilter'][] = array( 
'Gateway_Extras_CustomFilters_Referrer::onFilter' );
@@ -864,7 +876,10 @@
        'scripts' => 'esop.js',
        'dependencies' => 'di.form.core.validate',
        'localBasePath' => __DIR__ . '/worldpay_gateway/forms/js',
-       'remoteExtPath' => 'DonationInterface/worldpay_gateway/forms/js'
+       'remoteExtPath' => 'DonationInterface/worldpay_gateway/forms/js',
+       'messages' => array(
+               'donate_interface-cc-token-expired',
+       )
 );
 
 $wgResourceModules['ext.donationinterface.worldpay.iframecss'] = array (
diff --git a/amazon_gateway/amazon.api.php b/amazon_gateway/amazon.api.php
index f0eb4aa..b0162cd 100644
--- a/amazon_gateway/amazon.api.php
+++ b/amazon_gateway/amazon.api.php
@@ -13,12 +13,14 @@
        public function execute() {
                $output = $this->getResult();
                $recurring = $this->getParameter( 'recurring');
+               $token = $this->getParameter( 'token' );
                $adapterParams = array(
                        'api_request' => true,
                        'external_data' => array(
                                'amount' => $this->getParameter( 'amount' ),
                                'currency_code' => $this->getParameter( 
'currency_code' ),
-                               'recurring' => $this->getParameter( 'recurring' 
),
+                               'recurring' => $recurring,
+                               'token' => $token,
                        ),
                );
 
@@ -30,7 +32,7 @@
                                'errors',
                                $adapter->getValidationErrors()
                        );
-               } else if ( $adapter->checkTokens() ) {
+               } else if ( $token && $adapter->checkTokens() ) {
                        if ( $recurring ) {
                                $adapter->addRequestData( array(
                                        'subscr_id' => $this->getParameter( 
'billingAgreementId' ),
@@ -65,7 +67,7 @@
                        $output->addValue(
                                null,
                                'errors',
-                               array( 'token-mismatch' => $this->msg( 
'donate_interface-token-mismatch' )->text() )
+                               array( 'token-mismatch' => $this->msg( 
'donate_interface-cc-token-expired' )->text() )
                        );
                }
        }
diff --git a/amazon_gateway/amazon.js b/amazon_gateway/amazon.js
index 435ea45..5735f13 100644
--- a/amazon_gateway/amazon.js
+++ b/amazon_gateway/amazon.js
@@ -64,6 +64,11 @@
                );
        }
 
+       function reloadPage() {
+               var qsParams = $( '#payment-form' ).serializeArray();
+               document.location.replace( mw.util.getUrl( 
'Special:AmazonGateway', qsParams ) );
+       }
+
        function showErrorAndLoginButton( message ) {
                if ( message ) {
                        addErrorMessage( message );
@@ -75,7 +80,7 @@
                                type: 'PwA',
                                color: 'Gold',
                                size: 'large',
-                               authorization: redirectToLogin
+                               authorization: reloadPage
                        }
                );
        }
@@ -229,6 +234,12 @@
                        if ( !errors.hasOwnProperty( code ) ) {
                                continue;
                        }
+                       if ( code === 'token-mismatch' ) {
+                               // Session has expired, we need to reload the 
whole page.
+                               // FIXME: something nicer than an alert box
+                               alert( errors[code] );
+                               reloadPage();
+                       }
                        addErrorMessage( errors[code] );
                        if ( code === 'InvalidPaymentMethod' ) {
                                // Card declined, but they can try another
@@ -271,9 +282,10 @@
                var postdata = {
                        action: 'di_amazon_bill',
                        format: 'json',
-                       amount: $( '#amount' ).val(),
                        recurring: isRecurring,
-                       currency_code: $( '#currency_code' ).val()
+                       amount: $( '#amount' ).val(),
+                       currency_code: $( '#currency_code' ).val(),
+                       token: $( '#token' ).val()
                };
 
                if ( isRecurring ) {
diff --git a/amazon_gateway/amazon_gateway.body.php 
b/amazon_gateway/amazon_gateway.body.php
index 87dbcf8..cff7ead 100644
--- a/amazon_gateway/amazon_gateway.body.php
+++ b/amazon_gateway/amazon_gateway.body.php
@@ -30,13 +30,10 @@
         */
        protected function handleRequest() {
                Hooks::register( 'MakeGlobalVariablesScript', array( 
$this->adapter, 'setClientVariables' ) );
-               $this->getOutput()->allowClickjacking();
-
-               $this->setHeaders();
                $this->getOutput()->addModules( 
'ext.donationinterface.amazon.styles' );
                $this->getOutput()->addModules( 
'ext.donationinterface.amazon.scripts' );
 
                $this->validateForm();
-               $this->displayForm();
+               $this->handleDonationRequest();
        }
 }
diff --git a/extras/banner_history/BannerHistoryLogIdProcessor.php 
b/extras/banner_history/BannerHistoryLogIdProcessor.php
new file mode 100644
index 0000000..1e4c3c6
--- /dev/null
+++ b/extras/banner_history/BannerHistoryLogIdProcessor.php
@@ -0,0 +1,92 @@
+<?php
+
+/**
+ * Processor for banner history log ID. Handles the GatewayReady hook. (See
+ * below.)
+ */
+class BannerHistoryLogIdProcessor {
+
+       /**
+        * The URL parameter used to send the banner history log ID. Must 
correspond
+        * with Javascript used in banners.
+        */
+       const BANNER_HISTORY_LOG_ID_PARAM = 'bannerhistlog';
+
+       /**
+        * @var \Psr\Log\LoggerInterface
+        */
+       protected $logger;
+
+       /**
+        * @var GatewayAdapter
+        */
+       protected $gatewayAdapter;
+
+       protected static function singleton( $gatewayAdapter ) {
+               static $instance;
+
+               if ( !$instance ) {
+                       $instance = new BannerHistoryLogIdProcessor( 
$gatewayAdapter );
+               }
+               return $instance;
+       }
+
+       protected function __construct( $gatewayAdapter ) {
+               $this->gatewayAdapter = $gatewayAdapter;
+
+               $this->logger = DonationLoggerFactory::getLogger(
+                       $gatewayAdapter, '_banner_history' );
+       }
+
+       /**
+        * Queue a message with the banner history ID sent on the URL, the
+        * contribution tracking ID from DonationData, and some additional data.
+        */
+       protected function queueAssociationOfIds() {
+
+               $this->logger->debug(
+                       'BannerHistoryLogIdProcessor::queueAssociationOfIds(): 
will ' .
+                       'push to banner-history queue if required info is 
available.' );
+
+               $bannerHistoryId = RequestContext::getMain()->getRequest()
+                       ->getText( self::BANNER_HISTORY_LOG_ID_PARAM );
+
+               // Campaigns may not have banner history enabled. For now, at 
least,
+               // bow out silently if no banner history ID was sent.
+               if ( !$bannerHistoryId ) {
+                       return;
+               }
+
+               $contributionTrackingId = $this->gatewayAdapter
+                       ->getData_Unstaged_Escaped( 'contribution_tracking_id' 
);
+
+               if ( !$contributionTrackingId ) {
+                       $this->logger->info( 'No contribution tracking ID for ' 
.
+                                       'banner-history queue ' . 
$bannerHistoryId . '.' );
+                       return;
+               }
+
+               $data = array(
+                       'freeform' => true,
+                       'banner_history_id' => $bannerHistoryId,
+                       'contribution_tracking_id' => $contributionTrackingId,
+               );
+
+               $this->logger->info( 'Pushing to banner-history queue.' );
+               DonationQueue::instance()->push( $data, 'banner-history' );
+       }
+
+       /**
+        * Handler for the GatewayReady hook. This is the class's entry point.
+        *
+        * @param GatewayAdapter $gatewayAdapter
+        * @param DonationData $donationData
+        */
+       public static function onGatewayReady( $gatewayAdapter ) {
+
+               self::singleton( $gatewayAdapter )
+                       ->queueAssociationOfIds();
+
+               return true;
+       }
+}
\ No newline at end of file
diff --git a/gateway_common/GatewayPage.php b/gateway_common/GatewayPage.php
index e0b7484..780f5b3 100644
--- a/gateway_common/GatewayPage.php
+++ b/gateway_common/GatewayPage.php
@@ -71,6 +71,7 @@
                }
 
                if ( $this->adapter->getGlobal( 'Enabled' ) !== true ) {
+                       $this->logger->info( 'Displaying fail page for disabled 
gateway' );
                        $this->displayFailPage();
                        return;
                }
@@ -84,7 +85,7 @@
                try {
                        $this->handleRequest();
                } catch ( Exception $ex ) {
-                       $this->logger->error( "Gateway page errored out due to: 
" . $ex->getMessage() );
+                       $this->logger->error( "Displaying fail page for 
exception: " . $ex->getMessage() );
                        $this->displayFailPage();
                }
        }
@@ -142,6 +143,7 @@
                        $wgOut->addModules( $form_obj->getResources() );
                        $wgOut->addHTML( $form );
                } else {
+                       $this->logger->error( "Displaying fail page for bad 
form class '$form_class'" );
                        $this->displayFailPage();
                }
        }
@@ -418,12 +420,15 @@
                        // communication_type of 'incoming' and a way to 
provide the
                        // adapter the GET/POST params harvested here.
                        $this->adapter->processResponse( $response );
-                       switch ( $this->adapter->getFinalStatus() ) {
+                       $status = $this->adapter->getFinalStatus();
+                       switch ( $status ) {
                        case FinalStatus::COMPLETE:
                        case FinalStatus::PENDING:
+                               $this->logger->info( "Displaying thank you page 
for status $status." );
                                $this->getOutput()->redirect( 
$this->adapter->getThankYouPage() );
                                return;
                        }
+                       $this->logger->info( "Displaying fail page for final 
status $status" );
                } else {
                        $this->logger->error( "Resultswitcher: Token Check 
Failed. Order ID: $oid" );
                }
@@ -444,6 +449,7 @@
         */
        protected function renderResponse( PaymentResult $result ) {
                if ( $result->isFailed() ) {
+                       $this->logger->info( 'Displaying fail page for failed 
PaymentResult' );
                        $this->displayFailPage();
                } elseif ( $url = $result->getRedirect() ) {
                        $this->getOutput()->redirect( $url );
@@ -482,6 +488,7 @@
                        $this->displayForm();
                } else {
                        // Success.
+                       $this->logger->info( 'Displaying thank you page for 
successful PaymentResult' );
                        $this->getOutput()->redirect( 
$this->adapter->getThankYouPage() );
                }
        }
diff --git a/gateway_common/MessageUtils.php b/gateway_common/MessageUtils.php
index 77c9fb5..df84960 100644
--- a/gateway_common/MessageUtils.php
+++ b/gateway_common/MessageUtils.php
@@ -91,6 +91,6 @@
                $stripped = preg_replace( '/[^-_\w]/', '', $string );
 
                // theoretically this is overkill, but better safe than sorry
-               return wfEscapeWikiText( htmlspecialchars( $stripped ) );
+               return WmfFramework::sanitize( htmlspecialchars( $stripped ) );
        }
 }
diff --git a/gateway_common/WmfFramework.drupal.php 
b/gateway_common/WmfFramework.drupal.php
index 35b56ac..26e3b98 100644
--- a/gateway_common/WmfFramework.drupal.php
+++ b/gateway_common/WmfFramework.drupal.php
@@ -86,4 +86,8 @@
        static function isPosted() {
                return false;
        }
+
+       static function sanitize( $text ) {
+               return filter_xss( $text );
+       }
 }
diff --git a/gateway_common/WmfFramework.mediawiki.php 
b/gateway_common/WmfFramework.mediawiki.php
index d513c5d..02a355d 100644
--- a/gateway_common/WmfFramework.mediawiki.php
+++ b/gateway_common/WmfFramework.mediawiki.php
@@ -69,4 +69,8 @@
                global $wgRequest;
                return $wgRequest->wasPosted();
        }
+
+       static function sanitize( $text ) {
+               return wfEscapeWikiText( $text );
+       }
 }
diff --git a/gateway_common/gateway.adapter.php 
b/gateway_common/gateway.adapter.php
index 7b16c0d..d64b3e4 100644
--- a/gateway_common/gateway.adapter.php
+++ b/gateway_common/gateway.adapter.php
@@ -420,6 +420,8 @@
 
                $this->setGatewayDefaults( $options );
                $this->stageData();
+
+               WmfFramework::runHooks( 'GatewayReady', array( $this ) );
        }
 
        /**
diff --git a/gateway_common/i18n/interface/ast.json 
b/gateway_common/i18n/interface/ast.json
index 23e51cf..9c3be3d 100644
--- a/gateway_common/i18n/interface/ast.json
+++ b/gateway_common/i18n/interface/ast.json
@@ -211,6 +211,7 @@
        "donate_interface-otherways-alt": "Hai <a 
href=\"//wikimediafoundation.org/wiki/Ways_to_Give/en\">otres maneres de 
contribuir</a>, incluyendo por cheque.",
        "donate_interface-otherways-short": "Otres maneres de contribuir",
        "donate_interface-token-mismatch": "La sesión caducó. Intenta rellenar 
y unviar el formulariu otra vegada.",
+       "donate_interface-cc-token-expired": "El token caducó, fai clic en OK 
p'actualizar.",
        "donate_interface-try-again": "Temporalmente nun podemos procesar la to 
donación. Por favor, vuelve a intentalo pronto.",
        "donate_interface-cc-form-header-personal": "Información de 
facturación",
        "donate_interface-cc-form-header-payment": "Información del pagu",
@@ -352,9 +353,33 @@
        "donate_interface-email-unsub-warning": "Esto va dar de baxa la to 
suscripción a los correos electrónicos que la Fundación Wikimedia t'unvia como 
donante. Inda puedes recibir correos nesta dirección de corréu electrónicu si 
ta asociada con una cuenta n'unu de los nuesos proyectos. Si tienes dalguna 
entruga, comunícate con <a 
href=\"mailto:donati...@wikimedia.org\";>donati...@wikimedia.org</a>.",
        "donate_interface-faqs": "Entrugues más frecuentes",
        "donate_interface-tax-info": "Información de desgravación d'impuestos",
+       "donate_interface-informationsharing": "Al donar, aceptes compartir la 
to información personal cola Fundación Wikimedia, la organización ensin fines 
d'arriquecimientu qu'agospia Wikipedia y otros proyectos de Wikimedia, y colos 
sos fornidores de servicios conforme a la nuesa <a 
href=\"//wikimediafoundation.org/wiki/Donor_policy\">política de donantes</a>. 
La Fundación Wikimedia y los sos fornidores de servicios tán allugaos nos 
Estaos Xuníos y n'otros paises que les sos lleis de privacidá pueden nun ser 
equivalentes a les tuyes. Nun vamos vender nin comerciar cola to información 
con naide. Pa más información, llei la nuesa <a 
href=\"//wikimediafoundation.org/wiki/Donor_policy\">política de donantes</a>.",
        "donate_interface-currency-change": "¿Camudar?",
+       "donate_interface-bank_transfer_message": "Ten en cuenta que la to 
declaración va amosar \"Global Collect\" como'l destinatariu d'esti regalu. 
Global Collect ta autorizáu p'aceptar y procesar los pagos en nome de la 
Fundación Wikimedia. Recuerda incluyir el númberu de referencia que s'amuesa 
equí na to tresferencia bancaria y nun dudes en comunicate con nós en 
@donati...@wikimedia.org si tienes dalguna entruga o esmolición.",
+       "donate_interface-globalcollect-proxy": "Ten en cuenta que l'estractu 
bancariu va amosar a «Global Collect» como destinatariu d'esti regalu. Global 
Collect ta autorizáu p'aceptar y procesar pagos en nome de la Fundación 
Wikimedia.",
+       "donate_interface-taxded-link-int": "Impuestos ya otra información 
llegal",
+       "donate_interface-taxded-link-us": "Información de desgravación 
d'impuestos",
+       "donate_interface-taxded-msg-int": "La Fundación Wikimedia ye una 
organización de caridá ensin fines d'arriquecimientu establecida n'Estaos 
Xuníos so la sección de códigu de IRS  501(c)(3), y, por esa razón, les 
donaciones de persones o entidaes que s'atopen nos Estaos Xuníos pueden 
beneficiase de la desgravación d'impuestos. Les donaciones de persones o 
entidaes asitiaes fora de los Estaos Xuníos puede que nun tengan drechu a 
deducciones d'impuestos nos Estaos Xuníos y n'otros llugares; en tales casos, 
los donantes tienen de buscar asesoramientu fiscal llocal. Lo importante, 
Wikimedia nun busca donaciones de persones o entidaes asitiaes en cualquier 
xurisdicción que torgue o acute les actividaes de collecha de fondos pa 
organizaciones benéfiques internacionales como Wikimedia o aplique impuestos 
sobre les donaciones feches a tales organizaciones benéfiques internacionales.",
+       "donate_interface-taxded-msg-us": "La Fundación Wikimedia ye una 
organización de caridá ensin fines d'arriquecimientu establecida n'Estaos 
Xuníos so la sección de códigu US IRS  501(c)(3), y, por esa razón, les 
donaciones de persones o entidaes que s'atopen nos Estaos Xuníos pueden 
beneficiase de la desgravación d'impuestos.",
+       "donate_interface-legal-original": "Esta ye una traducción de cortesía. 
Nel casu d'un conflictu ente esta traducción y la versión n'inglés, rexirá la 
versión n'inglés.",
+       "donate_interface-monthlybox-title": "¿Faela mensualmente?",
+       "donate_interface-monthlybox-content": "Les donaciones mensuales 
procésense'l segundu día de cada mes. Puedes atayales en cualquier momentu.",
+       "donate_interface-monthlybox-amount": "Cantidá de la donación mensual",
+       "donate_interface-monthlybox-yes": "Ensin dulda, faela mensual",
+       "donate_interface-monthlybox-no": "NON, faer una donación única",
+       "donate_interface-monthlybox-bottom": "La donación va procesase de 
forma segura.",
+       "donate_interface-monthly-cancel": "Nel casu de los donantes 
periódicos, la Fundación Wikimedia va realizar tolos meses el cargu 
correspondiente'l mesmu día del mes de la primer donación, hasta'l momentu en 
que nos avises de que quies atayar el pagu. Les donaciones empecipiaes nos díes 
29, 30 o 31 van cargase l'últimu día del mes nos meses que sían más curtios, lo 
más cerca posible de la fecha orixinal. Pa cualquier entruga o dulda, 
comunícate con @don...@wikimedia.org.",
+       "donate_interface-onetime": "Faer una donación única",
        "donate_interface-monthly-short": "Mensual",
        "donate_interface-onetime-short": "Una sola vegada",
+       "donate_interface-securelogo-title": "Pulsia pa comprobar - Esti sitiu 
escoyó VeriSign SSL pal comerciu en llinia seguru y comunicaciones reservaes.",
+       "donate_interface-secureLogo-text": "Tocante a los certificaos SSL",
+       "donate_interface-error-http-403": "Nun tienes permisu d'accesu pa esta 
páxina.",
+       "donate_interface-statement": "Wikimedia $1",
+       "apihelp-donate-description": "Esta API te permite unviar una donación 
a la Fundación Wikimedia, usando dellos procesadores de pagu.",
+       "apihelp-donate-param-gateway": "Qué pasera de pagu utilizar: adyen, 
globalcollect, etc.",
+       "apihelp-donate-param-amount": "La cantidá donada.",
+       "apihelp-donate-param-currency_code": "Códigu de moneda.",
        "apihelp-donate-param-fname": "Nome(s).",
        "apihelp-donate-param-lname": "Apellíu(os).",
        "apihelp-donate-param-street": "Primera llinia de la direición.",
diff --git a/gateway_common/i18n/interface/de.json 
b/gateway_common/i18n/interface/de.json
index 8a103d4..4e4a5c5 100644
--- a/gateway_common/i18n/interface/de.json
+++ b/gateway_common/i18n/interface/de.json
@@ -222,6 +222,7 @@
        "donate_interface-otherways-alt": "Es gibt auch <a 
href=\"//wikimediafoundation.org/wiki/Donate/WaysToGive/de\">andere 
Möglichkeiten zu spenden, auch per Scheck</a>.",
        "donate_interface-otherways-short": "Andere Möglichkeiten zu spenden",
        "donate_interface-token-mismatch": "Ihre Sitzung ist abgelaufen. Bitte 
füllen Sie das Formular erneut aus und senden es nochmals ab.",
+       "donate_interface-cc-token-expired": "Ihr Token ist abgelaufen. Klicken 
Sie Okay zum Aktualisieren.",
        "donate_interface-try-again": "Wir können derzeit Ihre Spende nicht 
verarbeiten. Bitte später erneut versuchen.",
        "donate_interface-cc-form-header-personal": "Persönliche Informationen",
        "donate_interface-cc-form-header-payment": "Zahlungsinformationen",
diff --git a/gateway_common/i18n/interface/en.json 
b/gateway_common/i18n/interface/en.json
index 72397d1..fae32cf 100644
--- a/gateway_common/i18n/interface/en.json
+++ b/gateway_common/i18n/interface/en.json
@@ -235,6 +235,7 @@
        "donate_interface-otherways-alt": "There are <a 
href=\"//wikimediafoundation.org/wiki/Ways_to_Give/en\">other ways to give</a>, 
including by check.",
        "donate_interface-otherways-short": "Other ways to give",
        "donate_interface-token-mismatch": "Your session has expired. Please 
try filling out and submitting the form again.",
+       "donate_interface-cc-token-expired": "Your token has expired, click OK 
to refresh.",
        "donate_interface-try-again": "We are temporarily unable to process 
your donation. Please try again shortly.",
        "donate_interface-cc-form-header-personal": "Billing information",
        "donate_interface-cc-form-header-payment": "Payment information",
diff --git a/gateway_common/i18n/interface/es.json 
b/gateway_common/i18n/interface/es.json
index da0259f..4dd87e6 100644
--- a/gateway_common/i18n/interface/es.json
+++ b/gateway_common/i18n/interface/es.json
@@ -243,6 +243,7 @@
        "donate_interface-otherways-alt": "Hay <a 
href=\"//wikimediafoundation.org/wiki/Ways_to_Give/es\">otras maneras de 
donar</a>, incluido el cheque.",
        "donate_interface-otherways-short": "Otras maneras de donar",
        "donate_interface-token-mismatch": "Tu sesión ha expirado. Intenta 
llenar y enviar el formulario otra vez.",
+       "donate_interface-cc-token-expired": "El token ha caducado. Haz clic en 
OK para actualizar.",
        "donate_interface-try-again": "Temporalmente no podemos procesar tu 
donación. Intenta de nuevo en breve.",
        "donate_interface-cc-form-header-personal": "Datos de facturación",
        "donate_interface-cc-form-header-payment": "Información de pago",
diff --git a/gateway_common/i18n/interface/fr.json 
b/gateway_common/i18n/interface/fr.json
index 7814c55..5e32c5a 100644
--- a/gateway_common/i18n/interface/fr.json
+++ b/gateway_common/i18n/interface/fr.json
@@ -245,6 +245,7 @@
        "donate_interface-otherways-alt": "Il y a <a 
href=\"//wikimediafoundation.org/wiki/Donate/WaysToGive/fr\">d’autres moyens de 
donner</a>, y compris par chèque.",
        "donate_interface-otherways-short": "Autres moyens de donner",
        "donate_interface-token-mismatch": "Votre session a expiré. Veuillez 
essayer à nouveau de remplir et d’envoyer le formulaire.",
+       "donate_interface-cc-token-expired": "Votre session a expiré, cliquez 
sur OK pour la rafraîchir.",
        "donate_interface-try-again": "Nous sommes temporairement incapables de 
traiter votre don. S’il vous plaît, essayez à nouveau dans un peu de temps.",
        "donate_interface-cc-form-header-personal": "Informations de 
facturation",
        "donate_interface-cc-form-header-payment": "Informations sur le 
paiement",
diff --git a/gateway_common/i18n/interface/he.json 
b/gateway_common/i18n/interface/he.json
index 34d9594..d8686bf 100644
--- a/gateway_common/i18n/interface/he.json
+++ b/gateway_common/i18n/interface/he.json
@@ -219,6 +219,7 @@
        "donate_interface-otherways-alt": "ישנן <a 
href=\"//wikimediafoundation.org/wiki/Ways_to_Give/en\">דרכים נוספות לתרום</a>, 
לרבות המחאה.",
        "donate_interface-otherways-short": "דרכים אחרות לתרום",
        "donate_interface-token-mismatch": "פג תוקף השיחה. אנא נסו למלא את 
הטופס מחדש.",
+       "donate_interface-cc-token-expired": "האסימון שלך פג, נא ללחוץ אישור 
לרענון.",
        "donate_interface-try-again": "זמנית לא יכולנו לעבד את התרומה שלך. נא 
לנסות שוב בקרוב.",
        "donate_interface-cc-form-header-personal": "פרטי החיוב",
        "donate_interface-cc-form-header-payment": "פרטי התשלום",
diff --git a/gateway_common/i18n/interface/it.json 
b/gateway_common/i18n/interface/it.json
index 284dd0a..61b8c4c 100644
--- a/gateway_common/i18n/interface/it.json
+++ b/gateway_common/i18n/interface/it.json
@@ -226,6 +226,7 @@
        "donate_interface-otherways-alt": "Sono possibili <a 
href=\"//wikimediafoundation.org/wiki/Ways_to_Give/en\">altri modi per 
donare</a>, anche con assegno.",
        "donate_interface-otherways-short": "Altri modi per donare",
        "donate_interface-token-mismatch": "La sessione è scaduta. Prova 
compilando e inviando nuovamente il modulo.",
+       "donate_interface-cc-token-expired": "Il tuo token è scaduto, clicca su 
OK per aggiornare.",
        "donate_interface-try-again": "Non siamo temporaneamente in grado di 
elaborare la vostra donazione. Si prega di provare di nuovo a breve.",
        "donate_interface-cc-form-header-personal": "Dati di fatturazione",
        "donate_interface-cc-form-header-payment": "Informazioni sul pagamento",
diff --git a/gateway_common/i18n/interface/mk.json 
b/gateway_common/i18n/interface/mk.json
index b454fad..88a3416 100644
--- a/gateway_common/i18n/interface/mk.json
+++ b/gateway_common/i18n/interface/mk.json
@@ -218,6 +218,7 @@
        "donate_interface-otherways-alt": "Постојат и <a 
href=\"//wikimediafoundation.org/wiki/Ways_to_Give/en\">други начини на 
дарување</a>, вклучувајќи со чек.",
        "donate_interface-otherways-short": "Други начини на дарување",
        "donate_interface-token-mismatch": "Седницата ви истече.  Пополнете го 
образецот и поднесете го повторно.",
+       "donate_interface-cc-token-expired": "Шифрата ви истече. Стиснете на ОК 
за да превчитате.",
        "donate_interface-try-again": "Привремено не сме во можност да ја 
обработиме вашата уплата. Обидете се повторно за кратко време.",
        "donate_interface-cc-form-header-personal": "Наплатни податоци",
        "donate_interface-cc-form-header-payment": "Лични податоци",
diff --git a/gateway_common/i18n/interface/mr.json 
b/gateway_common/i18n/interface/mr.json
index e9b8ce6..229ab86 100644
--- a/gateway_common/i18n/interface/mr.json
+++ b/gateway_common/i18n/interface/mr.json
@@ -28,6 +28,7 @@
        "donate_interface-donor-postal": "पिनकोड",
        "donate_interface-donor-country": "देश/विभाग",
        "donate_interface-donor-address": "पत्ता",
+       "donate_interface-cc-token-expired": "आपले ओळखचिन्ह समाप्त झाले 
आहे.तरोताजे करण्यास OK टिचका.",
        "donate_interface-anon-message": "कृपया माझे नाव सार्वजनिक देणगीदार 
यादीत दाखवा.",
        "donate_interface-cardholders-name": "कार्डधारकाचे नाव",
        "donate_interface-card-type": "कार्ड प्रकार",
diff --git a/gateway_common/i18n/interface/pl.json 
b/gateway_common/i18n/interface/pl.json
index f6148ce..e6b1316 100644
--- a/gateway_common/i18n/interface/pl.json
+++ b/gateway_common/i18n/interface/pl.json
@@ -10,7 +10,8 @@
                        "Sp5uhe",
                        "WTM",
                        "Darellur",
-                       "Saper"
+                       "Saper",
+                       "The Polish"
                ]
        },
        "donate_interface": "Wspomóż Wikimedia",
@@ -186,8 +187,8 @@
        "donate_interface-error-msg-country": "państwo",
        "donate_interface-error-msg-card_type": "typ karty kredytowej",
        "donate_interface-error-msg-card_num": "numer karty kredytowej",
-       "donate_interface-error-msg-expiration": "datę ważności karty",
-       "donate_interface-error-msg-cvv": "kod CVV umieszczony z tyłu karty",
+       "donate_interface-error-msg-expiration": "Wprowadź proszę datę ważności 
karty",
+       "donate_interface-error-msg-cvv": "Wprowadź proszę kod CVV, wyświetlany 
zazwyczaj na tylnej części karty",
        "donate_interface-error-msg-account_name": "Nazwa konta",
        "donate_interface-error-msg-account_number": "Numer konta",
        "donate_interface-error-msg-authorization_id": "Identyfikator 
autoryzacji",
diff --git a/gateway_common/i18n/interface/qqq.json 
b/gateway_common/i18n/interface/qqq.json
index 80c87c8..52ab120 100644
--- a/gateway_common/i18n/interface/qqq.json
+++ b/gateway_common/i18n/interface/qqq.json
@@ -260,6 +260,7 @@
        "donate_interface-otherways-alt": "Message informing people about other 
ways to donate. Shown below donation form.",
        "donate_interface-otherways-short": "Link to page informing about other 
ways to give. Shown below donate form.",
        "donate_interface-token-mismatch": "Error message shown when the 
session has expired.",
+       "donate_interface-cc-token-expired": "Error message shown when the 
credit card token has expired.",
        "donate_interface-try-again": "Error message shown when a transient 
problem occurs, such as the payment processor being overloaded.  Asks the donor 
to attempt their donation again in a short time.",
        "donate_interface-cc-form-header-personal": "{{Identical|Billing 
information}}",
        "donate_interface-cc-form-header-payment": "Header for part of form 
with information about payment (credit card).",
diff --git a/gateway_common/i18n/interface/sr-ec.json 
b/gateway_common/i18n/interface/sr-ec.json
index 43bf394..754cac7 100644
--- a/gateway_common/i18n/interface/sr-ec.json
+++ b/gateway_common/i18n/interface/sr-ec.json
@@ -4,7 +4,8 @@
                        "Nikola Smolenski",
                        "Rancher",
                        "Михајло Анђелковић",
-                       "Milicevic01"
+                       "Milicevic01",
+                       "Сербијана"
                ]
        },
        "donate_interface": "Подржите Викимедију",
@@ -21,8 +22,8 @@
        "donate_interface-email-agreement": "Слажем се да повремено добијам 
е-обавештења од Задужбине Викимедија.",
        "donate_interface-comment-title": "Јавни коментар",
        "donate_interface-monthly-donation-description": "Месечни прилози 
Задужбини Викимедије",
-       "donate_interface-amount-error": "Унесите исправан износ",
-       "donate_interface-smallamount-error": "Прилог мора да износи барем $1.",
+       "donate_interface-amount-error": "Изаберите исправан износ да донирате",
+       "donate_interface-smallamount-error": "Изаберите износ (минимално $1)",
        "donate_interface-processing-error": "Дошло је до грешке при обрађивању 
захтева.\nНема доступних обрађивача.",
        "donate_interface-AED": "Емиратски дирхам",
        "donate_interface-ARS": "Аргентински пезос",
@@ -122,8 +123,8 @@
        "donate_interface-donor-legend": "Подаци о даваоцу",
        "donate_interface-donor-amount": "Износ:",
        "donate_interface-donor-currency-label": "Валута:",
-       "donate_interface-donor-email": "Е-адреса:",
-       "donate_interface-donor-emailAdd": "Е-адреса",
+       "donate_interface-donor-email": "Имејл адреса",
+       "donate_interface-donor-emailAdd": "Имејл адреса",
        "donate_interface-donor-name": "Име",
        "donate_interface-donor-fname": "Име",
        "donate_interface-donor-mname": "Средње име",
@@ -156,14 +157,14 @@
        "donate_interface-error-msg-js": "Унесите",
        "donate_interface-error-msg-validation": "Исправите грешке у обрасцу.",
        "donate_interface-error-msg-invalid-amount": "Унесите исправан износ",
-       "donate_interface-error-msg-email": "Унесите исправну е-адресу",
+       "donate_interface-error-msg-email": "Унесите исправну имејл адресу тј. 
име@домен.com",
        "donate_interface-error-msg-card-num": "Унесите исправан број кредитне 
картице од прихваћених врста",
        "donate_interface-error-msg-amex": "Унесите исправан број Американ 
експрес картице.",
        "donate_interface-error-msg-mc": "Унесите исправан број Мастеркард 
картице.",
        "donate_interface-error-msg-visa": "Унесите исправан број Виза 
картице.",
        "donate_interface-error-msg-discover": "Унесите исправан број Дискавер 
картице.",
        "donate_interface-error-msg-amount": "износ прилога",
-       "donate_interface-error-msg-emailAdd": "е-адреса",
+       "donate_interface-error-msg-emailAdd": "имејл адреса",
        "donate_interface-error-msg-fname": "име",
        "donate_interface-error-msg-lname": "презиме",
        "donate_interface-error-msg-street": "кућна адреса",
@@ -233,7 +234,7 @@
        "donate_interface-billing-code": "Поштански број за плаћање",
        "donate_interface-country": "Земља",
        "donate_interface-select-country": "Изаберите земљу",
-       "donate_interface-confirm-email": "Потврдите е-пошту",
+       "donate_interface-confirm-email": "Потврдите имејл",
        "donate_interface-phone": "Телефон",
        "donate_interface-telephone": "Телефон",
        "donate_interface-telephone-home": "Кућни телефон",
@@ -353,7 +354,7 @@
        "apihelp-donate-param-lname": "Презиме.",
        "apihelp-donate-param-city": "Град.",
        "apihelp-donate-param-zip": "Поштански број.",
-       "apihelp-donate-param-emailAdd": "Е-пошта.",
+       "apihelp-donate-param-emailAdd": "Имејл адреса.",
        "apihelp-donate-param-country": "Код државе.",
        "apihelp-donate-param-card_num": "Број кредитне картице.",
        "apihelp-donate-param-card_type": "Врста кредитне картице.",
diff --git a/gateway_common/i18n/interface/zh-hans.json 
b/gateway_common/i18n/interface/zh-hans.json
index f671d29..027c785 100644
--- a/gateway_common/i18n/interface/zh-hans.json
+++ b/gateway_common/i18n/interface/zh-hans.json
@@ -244,6 +244,7 @@
        "donate_interface-otherways-alt": "还可以通过<a 
href=\"//wikimediafoundation.org/wiki/Ways_to_Give/zh-hans\">其他方式</a>捐款,包括使用支票。",
        "donate_interface-otherways-short": "其他捐赠方式",
        "donate_interface-token-mismatch": "会话已经过期。请您重新填写并提交表单。",
+       "donate_interface-cc-token-expired": "您的令牌已过期,点击确定刷新。",
        "donate_interface-try-again": "我们目前无法处理您的捐款。请稍后重试。",
        "donate_interface-cc-form-header-personal": "账户信息",
        "donate_interface-cc-form-header-payment": "付款信息",
diff --git a/gateway_forms/mustache/index.html.mustache 
b/gateway_forms/mustache/index.html.mustache
index 8157e1c..539b418 100644
--- a/gateway_forms/mustache/index.html.mustache
+++ b/gateway_forms/mustache/index.html.mustache
@@ -31,22 +31,20 @@
                                                </tbody>
                                        </table>
                                </div>
-                               <input type="hidden" name="gateway" value="{{ 
gateway }}" id="gateway" />
                                <input type="hidden" value="{{ country }}" 
name="country" id="country" />
-                               <input type="hidden" value="0" 
name="PaypalRedirect" id="PaypalRedirect">
                                <input type="hidden" value="{{ expiration }}" 
name="expiration" id="expiration"/>
-                               <input type="hidden" value="{{ utm_source }}" 
name="utm_source"/>
-                               <input type="hidden" value="{{ utm_medium }}" 
name="utm_medium"/>
-                               <input type="hidden" value="{{ utm_campaign }}" 
name="utm_campaign"/>
-                               <input type="hidden" value="{{ language }}" 
name="language"/>
-                               <input type="hidden" value="{{ referrer }}" 
name="referrer"/>
-                               <input type="hidden" value="{{ token }}" 
name="token"/>
-                               <input type="hidden" value="{{ order_id }}"  
name="order_id"/>
-                               <input type="hidden" value="{{ 
contribution_tracking_id }}" name="contribution_tracking_id"/>
-                               <input type="hidden" value="{{ data_hash }}" 
name="data_hash"/>
-                               <input type="hidden" value="{{ gateway }}" 
name="gateway"/>
+                               <input type="hidden" value="{{ utm_source }}" 
name="utm_source" id="utm_source"/>
+                               <input type="hidden" value="{{ utm_medium }}" 
name="utm_medium" id="utm_medium"/>
+                               <input type="hidden" value="{{ utm_campaign }}" 
name="utm_campaign" id="utm_campaign"/>
+                               <input type="hidden" value="{{ language }}" 
name="language" id="language"/>
+                               <input type="hidden" value="{{ referrer }}" 
name="referrer" id="referrer"/>
+                               <input type="hidden" value="{{ token }}" 
name="token" id="token"/>
+                               <input type="hidden" value="{{ order_id }}" 
name="order_id" id="order_id"/>
+                               <input type="hidden" value="{{ 
contribution_tracking_id }}" name="contribution_tracking_id" 
id="contribution_tracking_id"/>
+                               <input type="hidden" value="{{ data_hash }}" 
name="data_hash" id="data_hash"/>
+                               <input type="hidden" value="{{ gateway }}" 
name="gateway" id="gateway"/>
                                <input type="hidden" value="{{ recurring }}" 
name="recurring" id="recurring"/>
-                               <input type="hidden" value="{{ payment_method 
}}" name="payment_method"/>
+                               <input type="hidden" value="{{ payment_method 
}}" name="payment_method" id=payment_method"/>
                        </form>
                        </div>
                        <p id="informationsharing">{{{ l10n 
"donate_interface-informationsharing" "url" }}}</p>
diff --git a/globalcollect_gateway/globalcollect_resultswitcher.body.php 
b/globalcollect_gateway/globalcollect_resultswitcher.body.php
index e7fc7e0..c194cb9 100644
--- a/globalcollect_gateway/globalcollect_resultswitcher.body.php
+++ b/globalcollect_gateway/globalcollect_resultswitcher.body.php
@@ -124,14 +124,17 @@
                                $this->displayResultsForDebug( $result );
                                //do the switching between the... stuff. 
 
-                               if ( $this->adapter->getFinalStatus() ){
-                                       switch ( 
$this->adapter->getFinalStatus() ) {
+                               $status = $this->adapter->getFinalStatus();
+                               if ( $status ) {
+                                       switch ( $status ) {
                                                case FinalStatus::COMPLETE:
                                                case FinalStatus::PENDING:
                                                case FinalStatus::PENDING_POKE:
+                                                       $this->logger->info( 
"Displaying thank you page for final status $status" );
                                                        $go = 
$this->adapter->getThankYouPage();
                                                        break;
                                                case FinalStatus::FAILED:
+                                                       $this->logger->info( 
'Displaying fail page for final status failed.' );
                                                        
$this->displayFailPage();
                                                        return;
                                        }
@@ -151,6 +154,7 @@
                } else {
                        $this->logger->error("Resultswitcher: Token Check 
Failed. Order ID: $oid" );
                }
+               $this->displayFailPage();
        }
 
        function popout_if_iframe() {
diff --git a/paypal_gateway/i18n/sr-ec.json b/paypal_gateway/i18n/sr-ec.json
index 9d6d11f..c4290ef 100644
--- a/paypal_gateway/i18n/sr-ec.json
+++ b/paypal_gateway/i18n/sr-ec.json
@@ -1,8 +1,9 @@
 {
        "@metadata": {
                "authors": [
-                       "Михајло Анђелковић"
+                       "Михајло Анђелковић",
+                       "Сербијана"
                ]
        },
-       "paypal_gateway-desc": "Региструје PayPal као механизам за донације"
+       "paypal_gateway-desc": "PayPal механизам плаћања"
 }
diff --git a/paypal_gateway/paypal_resultswitcher.body.php 
b/paypal_gateway/paypal_resultswitcher.body.php
index 0f763cd..4ab6534 100644
--- a/paypal_gateway/paypal_resultswitcher.body.php
+++ b/paypal_gateway/paypal_resultswitcher.body.php
@@ -61,6 +61,7 @@
                        }
                        $this->getOutput()->redirect( 
$this->adapter->getFailPage() );
 */
+                       $this->logger->info( "Displaying thank you page" );
                        $this->getOutput()->redirect( 
$this->adapter->getThankYouPage() );
                } else {
                        $this->logger->info( "Resultswitcher: Token Check 
Failed. Order ID: $oid" );
diff --git a/worldpay_gateway/forms/js/esop.js 
b/worldpay_gateway/forms/js/esop.js
index b1d6a94..07b51ba 100644
--- a/worldpay_gateway/forms/js/esop.js
+++ b/worldpay_gateway/forms/js/esop.js
@@ -71,6 +71,10 @@
                                                '</div>'
                                        );
                                        $( '#payment-iframe' ).show( 'blind' );
+                                       setTimeout( function () {
+                                               window.alert( mw.msg( 
'donate_interface-cc-token-expired' ) );
+                                               window.location.reload( true );
+                                       }, mw.config.get( 
'wgWorldpayGatewayTokenTimeout' ) );
                                } else {
                                        window.alert( mw.msg( 
'donate_interface-error-msg-general' ) );
                                        $( '#paymentContinue' ).show();
diff --git a/worldpay_gateway/worldpay.adapter.php 
b/worldpay_gateway/worldpay.adapter.php
index a1b4b10..3a7c634 100644
--- a/worldpay_gateway/worldpay.adapter.php
+++ b/worldpay_gateway/worldpay.adapter.php
@@ -1004,6 +1004,10 @@
                }
        }
 
+       public function setClientVariables( &$vars ) {
+               $vars['wgWorldpayGatewayTokenTimeout'] = $this->getGlobal( 
'TokenTimeout' );
+       }
+
        /**
         * Adds required data from the response to our staged collection
         * @param array $data parsed out of payment processor API response
diff --git a/worldpay_gateway/worldpay_gateway.body.php 
b/worldpay_gateway/worldpay_gateway.body.php
index e1b3527..bc336c8 100644
--- a/worldpay_gateway/worldpay_gateway.body.php
+++ b/worldpay_gateway/worldpay_gateway.body.php
@@ -39,6 +39,7 @@
        protected function handleRequest() {
                if ( $this->adapter->isESOP() ) {
                        $this->getOutput()->addModules( 
'ext.donationinterface.worldpay.esopjs' );
+                       Hooks::register( 'MakeGlobalVariablesScript', array( 
$this->adapter, 'setClientVariables' ) );
                } else {
                        $this->getOutput()->addModules( 
'ext.donationinterface.worldpay.styles' ); //loads early
                        $this->getOutput()->addModules( 
'ext.donationinterface.worldpay.code' ); //loads at normal time
diff --git a/worldpay_gateway/worldpay_resultswitcher.body.php 
b/worldpay_gateway/worldpay_resultswitcher.body.php
index b7fe881..c89cabc 100644
--- a/worldpay_gateway/worldpay_resultswitcher.body.php
+++ b/worldpay_gateway/worldpay_resultswitcher.body.php
@@ -28,9 +28,11 @@
                                case FinalStatus::COMPLETE:
                                case FinalStatus::PENDING:
                                case FinalStatus::PENDING_POKE:
+                                       $this->logger->info( "Displaying thank 
you page for status $status." );
                                        $this->getOutput()->redirect( 
$this->adapter->getThankYouPage() );
                                        break;
                                case FinalStatus::FAILED:
+                                       $this->logger->info( 'Displaying fail 
page for final status failed.' );
                                        $this->displayFailPage();
                                        return;
                        }

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I583965ca942ec377cb9dd3ba78f76855c4980f67
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/DonationInterface
Gerrit-Branch: deployment
Gerrit-Owner: Awight <awi...@wikimedia.org>
Gerrit-Reviewer: AndyRussG <andrew.green...@gmail.com>
Gerrit-Reviewer: Awight <awi...@wikimedia.org>
Gerrit-Reviewer: Cdentinger <cdentin...@wikimedia.org>
Gerrit-Reviewer: Ejegg <eeggles...@wikimedia.org>
Gerrit-Reviewer: Siebrand <siebr...@kitano.nl>
Gerrit-Reviewer: Ssmith <ssm...@wikimedia.org>
Gerrit-Reviewer: XenoRyet <dkozlow...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to