Ejegg has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/172914

Change subject: WIP: start using BannerChoiceDataProvider for allocations
......................................................................

WIP: start using BannerChoiceDataProvider for allocations

This commit leaves the old logic in to view calculated
percentages side by side

Change-Id: Ida4e62ea0ad2434246a923fbcc879b4b50e95489
---
M special/SpecialBannerAllocation.php
1 file changed, 74 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/CentralNotice 
refs/changes/14/172914/1

diff --git a/special/SpecialBannerAllocation.php 
b/special/SpecialBannerAllocation.php
index 9b70f87..8bd4b63 100644
--- a/special/SpecialBannerAllocation.php
+++ b/special/SpecialBannerAllocation.php
@@ -203,6 +203,25 @@
                // Begin Allocation list fieldset
                $htmlOut .= Html::openElement( 'fieldset', array( 'class' => 
'prefsection' ) );
 
+               // Given our project and language combination, get banner 
choice data
+               // for logged in and anonymous users.
+               $login_statuses = array(
+                       BannerChoiceDataProvider::ANONYMOUS,
+                       BannerChoiceDataProvider::LOGGED_IN
+               );
+
+               foreach ( $login_statuses as $provider_status ) {
+                       $provider = new BannerChoiceDataProvider( $project, 
$language, $provider_status );
+                       $choice_data[$provider_status] = 
$provider->getChoices();
+
+                       // Remove campaigns that are geotargetted but not to 
selected country
+                       foreach( $choice_data[$provider_status] as $index => 
$campaign ) {
+                               if ( $campaign['geotargetted'] && !in_array( 
$country, $campaign['countries'] ) ) {
+                                       unset( 
$choice_data[$provider_status][$index] );
+                               }
+                       }
+               }
+
                // Iterate through each possible device type and get allocation 
information
                $devices = CNDeviceTarget::getAvailableDevices();
                foreach( $devices as $device_id => $device_data ) {
@@ -253,13 +272,64 @@
                                );
                                if ( $target['anonymous'] === 'true' ) {
                                        $label = $this->msg( 
'centralnotice-banner-anonymous' )->text();
+                                       $provider_campaigns = 
$choice_data[BannerChoiceDataProvider::ANONYMOUS];
                                } else {
                                        $label = $this->msg( 
'centralnotice-banner-logged-in' )->text();
+                                       $provider_campaigns = 
$choice_data[BannerChoiceDataProvider::LOGGED_IN];
                                }
                                $label .= ' -- ' . $this->msg( 
'centralnotice-bucket-letter' )->
                                        rawParams( chr( $target['bucket'] + 65 
) )->text();
 
-                               $htmlOut .= $this->getTable( $label, $banners );
+                               $provider_banners = [];
+                               $preferred_max = 1;
+                               $total_traffic = 0; // used to normalize 
throttle percentage
+
+                               // Determine the banner allocation for this 
device / bucket combination
+                               foreach( $provider_campaigns as $campaign ) {
+                                       // Ignore campaigns with lower priority 
than the highest
+                                       // we've found so far
+                                       if ( $campaign['preferred'] < 
$preferred_max ) {
+                                               continue;
+                                       }
+                                       $campaign_weight = 0;
+                                       $included_banners = array();
+                                       // Select banners in this 
device/bucket, and get a total weight
+                                       foreach ( $campaign['banners'] as 
$banner ) {
+                                               if ( !in_array( 
$device_data['header'], $banner['devices'] ) ) {
+                                                       continue;
+                                               }
+                                               if ( $target['bucket'] % 
$campaign['bucket_count'] != $banner['bucket'] ) {
+                                                       continue;
+                                               }
+                                               $included_banners[] = $banner;
+                                               $campaign_weight += 
$banner['weight'];
+                                       }
+                                       // Ignore campaigns with no banners for 
this device / bucket
+                                       if ( empty( $included_banners ) ) {
+                                               continue;
+                                       }
+                                       // If a campaign with banners is higher 
priority than we've
+                                       // seen so far, throw out the existing 
banners and reset max
+                                       if ( $campaign['preferred'] > 
$preferred_max ) {
+                                               $provider_banners = [];
+                                               $total_traffic = 0;
+                                               $preferred_max = 
$campaign['preferred'];
+                                       }
+                                       $total_traffic += $campaign['throttle'];
+                                       // Normalize the campaign-specific 
weights for each banner
+                                       // and add a property to track their 
banner
+                                       foreach( $included_banners as $banner ) 
{
+                                               $banner['weight'] = 
$banner['weight'] / $campaign_weight;
+                                               $banner['campaign'] = 
$campaign['name'];
+                                               $banner['throttle'] = 
$campaign['throttle'];
+                                               $provider_banners[] = $banner;
+                                       }
+                               }
+                               // Normalize allocations for throttling across 
all campaigns
+                               foreach( $provider_banners as $index => $banner 
) {
+                                       $provider_banners[$index]['allocation'] 
= $banner['weight'] * $banner['throttle'] / $total_traffic;
+                               }
+                               $htmlOut .= $this->getTable( $label, $banners, 
$provider_banners );
                        }
 
                        $htmlOut .= Html::closeElement( 'div' );
@@ -277,7 +347,7 @@
         * @param $banners array The banners to list
         * @return string HTML for the table
         */
-       public function getTable( $type, $banners ) {
+       public function getTable( $type, $banners, $provider_banners ) {
                $viewCampaign = $this->getTitleFor( 'CentralNotice' );
 
                $htmlOut = Html::openElement( 'table',
@@ -285,6 +355,8 @@
                );
                $htmlOut .= Html::element( 'h4', array(), $type );
 
+               $banners = array_merge( $banners, $provider_banners );
+
                if (count($banners) > 0) {
 
                        $htmlOut .= Html::openElement( 'tr' );

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ida4e62ea0ad2434246a923fbcc879b4b50e95489
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/CentralNotice
Gerrit-Branch: master
Gerrit-Owner: Ejegg <[email protected]>

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

Reply via email to