Index: trunk/extensions/ArticleFeedback/ArticleFeedback.hooks.php |
— | — | @@ -204,10 +204,12 @@ |
205 | 205 | public static function resourceLoaderGetConfigVars( &$vars ) { |
206 | 206 | global $wgArticleFeedbackCategories, |
207 | 207 | $wgArticleFeedbackLotteryOdds, |
208 | | - $wgArticleFeedbackTrackingVersion; |
| 208 | + $wgArticleFeedbackTrackingVersion, |
| 209 | + $wgArticleFeedbackTrackingOdds; |
209 | 210 | $vars['wgArticleFeedbackCategories'] = $wgArticleFeedbackCategories; |
210 | 211 | $vars['wgArticleFeedbackLotteryOdds'] = $wgArticleFeedbackLotteryOdds; |
211 | 212 | $vars['wgArticleFeedbackTrackingVersion'] = $wgArticleFeedbackTrackingVersion; |
| 213 | + $vars['wgArticleFeedbackTrackingOdds'] = $wgArticleFeedbackTrackingOdds; |
212 | 214 | return true; |
213 | 215 | } |
214 | 216 | } |
Index: trunk/extensions/ArticleFeedback/modules/jquery.articleFeedback/jquery.articleFeedback.js |
— | — | @@ -4,6 +4,9 @@ |
5 | 5 | |
6 | 6 | ( function( $, mw ) { |
7 | 7 | |
| 8 | +// Only track users who have been assigned to the tracking group |
| 9 | +var tracked = Number( $.cookie( 'ext.articleFeedback-tracking' ) ); |
| 10 | + |
8 | 11 | /** |
9 | 12 | * Prefixes a key for cookies or events, with extension and version information |
10 | 13 | * |
— | — | @@ -396,7 +399,7 @@ |
397 | 400 | prefix( 'pitch-' + key ), 'hide', { 'expires': 3 } |
398 | 401 | ); |
399 | 402 | // Track that a pitch was dismissed |
400 | | - if ( typeof $.trackAction == 'function' ) { |
| 403 | + if ( tracked && typeof $.trackAction == 'function' ) { |
401 | 404 | $.trackAction( prefix( 'pitch-' + key + '-reject' ) ); |
402 | 405 | } |
403 | 406 | $pitch.fadeOut( 'fast', function() { |
— | — | @@ -491,7 +494,7 @@ |
492 | 495 | .fadeIn( 'fast' ); |
493 | 496 | context.$ui.find( '.articleFeedback-ui' ).hide(); |
494 | 497 | // Track that a pitch was presented |
495 | | - if ( typeof $.trackAction == 'function' ) { |
| 498 | + if ( tracked && typeof $.trackAction == 'function' ) { |
496 | 499 | $.trackAction( prefix( 'pitch-' + key + '-show' ) ); |
497 | 500 | } |
498 | 501 | } else { |
Index: trunk/extensions/ArticleFeedback/modules/ext.articleFeedback/ext.articleFeedback.js |
— | — | @@ -4,6 +4,9 @@ |
5 | 5 | |
6 | 6 | ( function( $, mw ) { |
7 | 7 | |
| 8 | +// Only track users who have been assigned to the tracking group |
| 9 | +var tracked = Number( $.cookie( 'ext.articleFeedback-tracking' ) ); |
| 10 | + |
8 | 11 | /** |
9 | 12 | * Prefixes a key for cookies or events, with extension and version information |
10 | 13 | * |
— | — | @@ -37,13 +40,13 @@ |
38 | 41 | |
39 | 42 | function trackClick( id ) { |
40 | 43 | // Track the click so we can figure out how useful this is |
41 | | - if ( typeof $.trackActionWithInfo == 'function' ) { |
| 44 | + if ( tracked && typeof $.trackActionWithInfo == 'function' ) { |
42 | 45 | $.trackActionWithInfo( prefix( id ), mediaWiki.config.get( 'wgTitle' ) ) |
43 | 46 | } |
44 | 47 | } |
45 | 48 | |
46 | 49 | function trackClickURL( url, id ) { |
47 | | - if ( typeof $.trackActionURL == 'function' ) { |
| 50 | + if ( tracked && typeof $.trackActionURL == 'function' ) { |
48 | 51 | return $.trackActionURL( url, prefix( id ) ); |
49 | 52 | } else { |
50 | 53 | return url; |
Index: trunk/extensions/ArticleFeedback/modules/ext.articleFeedback/ext.articleFeedback.startup.js |
— | — | @@ -12,6 +12,36 @@ |
13 | 13 | && mw.util.getParamValue( 'diff' ) === null |
14 | 14 | && mw.util.getParamValue( 'oldid' ) === null |
15 | 15 | ) { |
| 16 | + // If the version in the client's cookie doesn't match wgArticleFeedbackTrackingVersion, |
| 17 | + // then we need to disregard the bucket they may already be in to ensure accurate |
| 18 | + // redistribution when the odds are changed |
| 19 | + var previousVersion = $.cookie( 'ext.articleFeedback-version' ); |
| 20 | + var currentVersion = Number( mw.config.get( 'wgArticleFeedbackTrackingVersion', 0 ) ); |
| 21 | + var tracking = null; |
| 22 | + if ( previousVersion === null || Number( previousVersion ) != currentVersion ) { |
| 23 | + $.cookie( 'ext.articleFeedback-version', currentVersion ); |
| 24 | + } else { |
| 25 | + tracking = $.cookie( 'ext.articleFeedback-tracking' ); |
| 26 | + } |
| 27 | + if ( tracking === null ) { |
| 28 | + // Percentage chance of being tracked |
| 29 | + var odds = Math.min( 100, Math.max( 0, |
| 30 | + Number( mw.config.get( 'wgArticleFeedbackTrackingOdds', 0 ) ) |
| 31 | + ) ); |
| 32 | + // 0 = not tracked, 1 = tracked |
| 33 | + tracking = Number( Math.random() * 100 < odds ); |
| 34 | + // Let the cookie expire after 30 days, allowing rotation in which users are tracked |
| 35 | + $.cookie( 'ext.articleFeedback-tracking', tracking, { 'path': '/', 'expires': 30 } ); |
| 36 | + // To be extra-sure that the odds are being applied properly, track whether a user is to |
| 37 | + // be tracked or not - this way we can compare the number of people in each bucket to |
| 38 | + // the intended percentages defined by wgArticleFeedbackTrackingOdds |
| 39 | + if ( 'trackAction' in $ ) { |
| 40 | + $.trackAction( |
| 41 | + 'ext.articleFeedback@' + currentVersion + '-tracking-' + |
| 42 | + ( tracking ? 'on' : 'off' ) |
| 43 | + ); |
| 44 | + } |
| 45 | + } |
16 | 46 | // Category activation |
17 | 47 | var articleFeedbackCategories = mw.config.get( 'wgArticleFeedbackCategories', [] ); |
18 | 48 | var articleCategories = mw.config.get( 'wgCategories', [] ); |
Index: trunk/extensions/ArticleFeedback/ArticleFeedback.php |
— | — | @@ -35,6 +35,13 @@ |
36 | 36 | // corrupt the data being collected. Bump this when you want to start a new "experiment". |
37 | 37 | $wgArticleFeedbackTrackingVersion = 0; |
38 | 38 | |
| 39 | +// Not all users need to be tracked, but we do want to track some users over time - this value is |
| 40 | +// used when deciding to track someone or not, placing them in one of two buckets: tracked and not. |
| 41 | +// When $wgArticleFeedbackTrackingVersion changes, users will be re-bucketed, so you should always |
| 42 | +// increment $wgArticleFeedbackTrackingVersion when changing this number to ensure the new odds |
| 43 | +// are applied to everyone, not just people who have yet to be placed in a bucket. |
| 44 | +$wgArticleFeedbackTrackingOdds = 100; |
| 45 | + |
39 | 46 | // Would ordinarily call this articlefeedback but survey names are 16 chars max |
40 | 47 | $wgPrefSwitchSurveys['articlerating'] = array( |
41 | 48 | 'updatable' => false, |