Index: branches/wmf/1.17wmf1/extensions/ClickTracking/ClickTracking.hooks.php |
— | — | @@ -21,6 +21,7 @@ |
22 | 22 | global $wgExtNewTables, $wgExtNewIndexes, $wgExtNewFields; |
23 | 23 | $wgExtNewTables[] = array( 'click_tracking', $dir . 'patches/ClickTracking.sql' ); |
24 | 24 | $wgExtNewTables[] = array( 'click_tracking_events', $dir . 'patches/ClickTrackingEvents.sql' ); |
| 25 | + $wgExtNewTables[] = array( 'click_tracking_user_properties', $dir . 'patches/ClickTrackingUserProperties.sql' ); |
25 | 26 | $wgExtNewIndexes[] = array( |
26 | 27 | 'click_tracking', |
27 | 28 | 'click_tracking_action_time', |
— | — | @@ -36,6 +37,8 @@ |
37 | 38 | $dir . 'patches/ClickTracking.sql', true ) ); |
38 | 39 | $updater->addExtensionUpdate( array( 'addTable', 'click_tracking_events', |
39 | 40 | $dir . 'patches/ClickTrackingEvents.sql', true ) ); |
| 41 | + $updater->addExtensionUpdate( array( 'addTable', 'click_tracking_user_properties', |
| 42 | + $dir . 'patches/ClickTrackingUserProperties.sql', true ) ); |
40 | 43 | $updater->addExtensionUpdate( array( 'addIndex', 'click_tracking', 'click_tracking_action_time', |
41 | 44 | $dir . 'patches/patch-action_time.sql', true ) ); |
42 | 45 | $updater->addExtensionUpdate( array( 'addField', 'click_tracking', 'additional_info', |
— | — | @@ -53,6 +56,7 @@ |
54 | 57 | public static function parserTestTables( &$tables ) { |
55 | 58 | $tables[] = 'click_tracking'; |
56 | 59 | $tables[] = 'click_tracking_events'; |
| 60 | + $tables[] = 'click_tracking_user_properties'; |
57 | 61 | return true; |
58 | 62 | } |
59 | 63 | |
— | — | @@ -66,6 +70,7 @@ |
67 | 71 | */ |
68 | 72 | public static function beforePageDisplay( $out, $skin ) { |
69 | 73 | global $wgClickTrackThrottle; |
| 74 | + $out->addModules( 'ext.UserBuckets' ); |
70 | 75 | |
71 | 76 | if ( $wgClickTrackThrottle >= 0 && rand() % $wgClickTrackThrottle == 0 ) { |
72 | 77 | $out->addModules( 'ext.clickTracking' ); |
— | — | @@ -86,6 +91,26 @@ |
87 | 92 | return true; |
88 | 93 | } |
89 | 94 | |
| 95 | + |
| 96 | + //adds a bucket-testing campaign to the active campaigns |
| 97 | + public static function addCampaign($localBasePath, $remoteExtPath, $name ){ |
| 98 | + global $wgResourceModules; |
| 99 | + |
| 100 | + $cusResourceTemplate = array( |
| 101 | + 'localBasePath' => $localBasePath, |
| 102 | + 'remoteExtPath' => $remoteExtPath, |
| 103 | + ); |
| 104 | + $wgResourceModules["ext.UserBuckets.$name"] = array( |
| 105 | + 'scripts' => "$name.js", |
| 106 | + 'dependencies' => 'jquery.clickTracking', |
| 107 | + ) + $cusResourceTemplate; |
| 108 | + $wgResourceModules['ext.UserBuckets']['dependencies'] = array_merge( |
| 109 | + ( array ) $wgResourceModules['ext.UserBuckets']['dependencies'], |
| 110 | + array("ext.UserBuckets.$name")); |
| 111 | + } |
| 112 | + |
| 113 | + |
| 114 | + |
90 | 115 | /** |
91 | 116 | * Get event ID from name |
92 | 117 | * |
— | — | @@ -115,7 +140,36 @@ |
116 | 141 | return $id_num === false ? 0 : $id_num; |
117 | 142 | } |
118 | 143 | |
| 144 | + |
| 145 | + |
| 146 | + |
119 | 147 | /** |
| 148 | + * Returns bucket information |
| 149 | + * @return Array array of buckets, or null |
| 150 | + */ |
| 151 | + public static function unpackBucketInfo(){ |
| 152 | + global $wgRequest; |
| 153 | + |
| 154 | + //JSON-encoded because it's simple, can be replaced with any other encoding scheme |
| 155 | + return json_decode($wgRequest->getCookie('userbuckets',""), true); |
| 156 | + } |
| 157 | + |
| 158 | + /** |
| 159 | + * Takes in an array of buckets |
| 160 | + * @param unknown_type $buckets |
| 161 | + * @return unknown_type |
| 162 | + */ |
| 163 | + public static function packBucketInfo( $buckets ){ |
| 164 | + global $wgRequest; |
| 165 | + //Can be another encoding scheme, just needs to match unpackBucketInfo |
| 166 | + $packedBuckets = json_encode( $buckets ); |
| 167 | + |
| 168 | + //NOTE: $wgRequest->response setCookie sets it with a prefix and httponly by default |
| 169 | + setcookie( 'userbuckets' , $packedBuckets , |
| 170 | + time() + 60 * 60 * 24 * 365 ); //expire in 1 year |
| 171 | + } |
| 172 | + |
| 173 | + /** |
120 | 174 | * Track particular event |
121 | 175 | * |
122 | 176 | * @param $sessionId String: unique session id for this editing sesion |
— | — | @@ -129,10 +183,13 @@ |
130 | 184 | * (defined by ClickTracking/$wgClickTrackContribGranularity2) |
131 | 185 | * @param $contribs_in_timespan3 Integer: number of contributions user has made in timespan of granularity 3 |
132 | 186 | * (defined by ClickTracking/$wgClickTrackContribGranularity3) |
| 187 | + * @param $additional String: catch-all for any additional information we want to record about this click |
| 188 | + * @param $relevantBucket String: name/index of the particular bucket we're concerned with for this event |
133 | 189 | * @return Boolean: true if the event was stored in the DB |
134 | 190 | */ |
135 | 191 | public static function trackEvent( $sessionId, $isLoggedIn, $namespace, $eventId, $contribs = 0, |
136 | | - $contribs_in_timespan1 = 0, $contribs_in_timespan2 = 0, $contribs_in_timespan3 = 0, $additional = null ) { |
| 192 | + $contribs_in_timespan1 = 0, $contribs_in_timespan2 = 0, $contribs_in_timespan3 = 0, $additional = null, $recordBucketInfo = true ) { |
| 193 | + |
137 | 194 | $dbw = wfGetDB( DB_MASTER ); |
138 | 195 | $dbw->begin(); |
139 | 196 | // Builds insert information |
— | — | @@ -148,9 +205,33 @@ |
149 | 206 | 'event_id' => (int) $eventId, |
150 | 207 | 'additional_info' => ( isset( $additional ) ? (string) $additional : null ) |
151 | 208 | ); |
| 209 | + $db_status_buckets = true; |
152 | 210 | $db_status = $dbw->insert( 'click_tracking', $data, __METHOD__ ); |
153 | 211 | $dbw->commit(); |
154 | | - return $db_status; |
| 212 | + |
| 213 | + if( $recordBucketInfo && $db_status ){ |
| 214 | + $buckets = self::unpackBucketInfo(); |
| 215 | + if( $buckets ){ |
| 216 | + foreach( $buckets as $bucketName => $bucketValue ){ |
| 217 | + $db_current_bucket_insert = $dbw->insert( 'click_tracking_user_properties', |
| 218 | + array( |
| 219 | + 'session_id' => (string) $sessionId, |
| 220 | + 'property_name' => (string) $bucketName, |
| 221 | + 'property_value' => (string) $bucketValue[0], |
| 222 | + 'property_version' => (int) $bucketValue[1] |
| 223 | + ), |
| 224 | + __METHOD__, |
| 225 | + array( 'IGNORE' ) |
| 226 | + ); |
| 227 | + $db_status_buckets = $db_status_buckets && $db_current_bucket_insert; |
| 228 | + } |
| 229 | + }//ifbuckets |
| 230 | + }//ifrecord |
| 231 | + |
| 232 | + $dbw->commit(); |
| 233 | + return ($db_status && $db_status_buckets); |
| 234 | + |
| 235 | + |
155 | 236 | } |
156 | 237 | |
157 | 238 | public static function editPageShowEditFormFields( $editPage, $output ) { |
— | — | @@ -159,36 +240,40 @@ |
160 | 241 | // Add clicktracking fields to form, if given |
161 | 242 | $session = $wgRequest->getVal( 'clicktrackingsession' ); |
162 | 243 | $event = $wgRequest->getVal( 'clicktrackingevent' ); |
| 244 | + $info = $wgRequest->getVal( 'clicktrackinginfo' ); |
163 | 245 | if ( $session !== null && $event !== null ) { |
164 | 246 | $editPage->editFormTextAfterContent .= Html::hidden( 'clicktrackingsession', $session ); |
165 | 247 | $editPage->editFormTextAfterContent .= Html::hidden( 'clicktrackingevent', $event ); |
| 248 | + $editPage->editFormTextAfterContent .= Html::hidden( 'clicktrackinginfo', $info ); |
166 | 249 | } |
167 | 250 | |
168 | 251 | return true; |
169 | 252 | } |
170 | 253 | |
171 | 254 | public static function articleSave( $editpage ) { |
172 | | - self::trackRequest( 'save-attempt' ); |
| 255 | + self::trackRequest( '-save-attempt' ); |
173 | 256 | return true; |
174 | 257 | } |
175 | 258 | |
176 | 259 | public static function articleSaveComplete( $article, $user, $text, $summary, $minoredit, |
177 | 260 | $watchthis, $sectionanchor, $flags, $revision, $baseRevId ) { |
178 | | - self::trackRequest( 'save-complete' ); |
| 261 | + self::trackRequest( '-save-complete' ); |
179 | 262 | return true; |
180 | 263 | } |
181 | 264 | |
182 | | - protected static function trackRequest( $info ) { |
183 | | - global $wgRequest; |
| 265 | + protected static function trackRequest( $suffix ) { |
| 266 | + global $wgRequest, $wgTitle; |
184 | 267 | |
185 | 268 | $session = $wgRequest->getVal( 'clicktrackingsession' ); |
186 | 269 | $event = $wgRequest->getVal( 'clicktrackingevent' ); |
| 270 | + $info = $wgRequest->getVal( 'clicktrackinginfo' ); |
187 | 271 | if ( $session !== null && $event !== null ) { |
188 | 272 | $params = new FauxRequest( array( |
189 | 273 | 'action' => 'clicktracking', |
190 | | - 'eventid' => $event, |
| 274 | + 'eventid' => $event . $suffix, |
191 | 275 | 'token' => $session, |
192 | | - 'additional' => $info, |
| 276 | + 'info' => $info, |
| 277 | + 'namespacenumber' => $wgTitle->getNamespace(), |
193 | 278 | ) ); |
194 | 279 | $api = new ApiMain( $params, true ); |
195 | 280 | $api->execute(); |
Index: branches/wmf/1.17wmf1/extensions/ClickTracking/patches/ClickTrackingUserProperties.sql |
— | — | @@ -0,0 +1,23 @@ |
| 2 | +-- |
| 3 | +-- Schema for ClickTrackingUserProperties |
| 4 | +-- |
| 5 | + |
| 6 | +CREATE TABLE IF NOT EXISTS /*_*/click_tracking_user_properties ( |
| 7 | + |
| 8 | + -- session id from clicktracking table |
| 9 | + session_id varbinary(255) NOT NULL, |
| 10 | + |
| 11 | + -- property name |
| 12 | + property_name varbinary(255), |
| 13 | + |
| 14 | + -- property value |
| 15 | + property_value varbinary(255), |
| 16 | + |
| 17 | + -- property version |
| 18 | + property_version INTEGER |
| 19 | + |
| 20 | +) /*$wgDBTableOptions*/; |
| 21 | + |
| 22 | +CREATE INDEX /*i*/click_tracking_user_properties_session_idx ON /*_*/click_tracking_user_properties (session_id); |
| 23 | + |
| 24 | +CREATE UNIQUE INDEX ct_user_prop_id_name_value_version ON /*_*/click_tracking_user_properties(session_id, property_name, property_value, property_version); |
\ No newline at end of file |
Property changes on: branches/wmf/1.17wmf1/extensions/ClickTracking/patches/ClickTrackingUserProperties.sql |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 25 | + native |
Index: branches/wmf/1.17wmf1/extensions/ClickTracking/patches/ClickTracking.sql |
— | — | @@ -36,3 +36,5 @@ |
37 | 37 | ) /*$wgDBTableOptions*/; |
38 | 38 | |
39 | 39 | CREATE INDEX /*i*/click_tracking_action_time ON /*_*/click_tracking (action_time); |
| 40 | +CREATE INDEX /*i*/click_tracking_event_id ON /*_*/click_tracking (event_id); |
| 41 | +CREATE INDEX /*i*/click_tracking_session_id ON /*_*/click_tracking (session_id); |
Index: branches/wmf/1.17wmf1/extensions/ClickTracking/ApiClickTracking.php |
— | — | @@ -25,7 +25,8 @@ |
26 | 26 | $this->validateParams( $params ); |
27 | 27 | $eventid_to_lookup = $params['eventid']; |
28 | 28 | $sessionId = $params['token']; |
29 | | - |
| 29 | + $namespace = $params['namespacenumber']; |
| 30 | + |
30 | 31 | $additional = null; |
31 | 32 | |
32 | 33 | if ( isset( $params['additional'] ) && strlen( $params['additional'] ) > 0 ) { |
— | — | @@ -50,7 +51,7 @@ |
51 | 52 | ClickTrackingHooks::trackEvent( |
52 | 53 | $sessionId, // randomly generated session ID |
53 | 54 | $isLoggedIn, // is the user logged in? |
54 | | - $wgTitle->getNamespace(), // what namespace are they editing? |
| 55 | + (int)$namespace, // what namespace are they editing? |
55 | 56 | $eventId, // event ID passed in |
56 | 57 | ( $isLoggedIn ? $wgUser->getEditCount() : 0 ), // total edit count or 0 if anonymous |
57 | 58 | $granularity1, // contributions made in granularity 1 time frame |
— | — | @@ -85,7 +86,7 @@ |
86 | 87 | * @param $params params extracted from the POST |
87 | 88 | */ |
88 | 89 | protected function validateParams( $params ) { |
89 | | - $required = array( 'eventid', 'token' ); |
| 90 | + $required = array( 'eventid', 'token', 'namespacenumber' ); |
90 | 91 | foreach ( $required as $arg ) { |
91 | 92 | if ( !isset( $params[$arg] ) ) { |
92 | 93 | $this->dieUsageMsg( array( 'missingparam', $arg ) ); |
— | — | @@ -97,6 +98,7 @@ |
98 | 99 | return array( |
99 | 100 | 'eventid' => 'string of eventID', |
100 | 101 | 'token' => 'unique edit ID for this edit session', |
| 102 | + 'namespacenumber' => 'the namespace number being edited', |
101 | 103 | 'redirectto' => 'URL to redirect to (only used for links that go off the page)', |
102 | 104 | 'additional' => 'additional info for the event, like state information' |
103 | 105 | ); |
— | — | @@ -112,12 +114,14 @@ |
113 | 115 | return array_merge( parent::getPossibleErrors(), array( |
114 | 116 | array( 'missingparam', 'eventid' ), |
115 | 117 | array( 'missingparam', 'token' ), |
| 118 | + array( 'missingparam', 'namespacenumber'), |
116 | 119 | ) ); |
117 | 120 | } |
118 | 121 | |
119 | 122 | public function getAllowedParams() { |
120 | 123 | return array( |
121 | 124 | 'eventid' => null, |
| 125 | + 'namespacenumber' => null, |
122 | 126 | 'token' => null, |
123 | 127 | 'redirectto' => null, |
124 | 128 | 'additional' => null |
Index: branches/wmf/1.17wmf1/extensions/ClickTracking/modules/jquery.clickTracking.js |
— | — | @@ -28,6 +28,7 @@ |
29 | 29 | $.post( |
30 | 30 | mediaWiki.config.get( 'wgScriptPath' ) + '/api.php', { |
31 | 31 | 'action': 'clicktracking', |
| 32 | + 'namespacenumber': mediaWiki.config.get( 'wgNamespaceNumber' ), |
32 | 33 | 'eventid': id, |
33 | 34 | 'token': $.cookie( 'clicktracking-session' ) |
34 | 35 | } |
— | — | @@ -44,6 +45,7 @@ |
45 | 46 | mediaWiki.config.get( 'wgScriptPath' ) + '/api.php', { |
46 | 47 | 'action': 'clicktracking', |
47 | 48 | 'eventid': id, |
| 49 | + 'namespacenumber': mediaWiki.config.get( 'wgNamespaceNumber' ), |
48 | 50 | 'token': $.cookie( 'clicktracking-session' ), |
49 | 51 | 'additional': info |
50 | 52 | } |
— | — | @@ -60,6 +62,7 @@ |
61 | 63 | return mediaWiki.config.get( 'wgScriptPath' ) + '/api.php?' + $.param( { |
62 | 64 | 'action': 'clicktracking', |
63 | 65 | 'eventid': id, |
| 66 | + 'namespacenumber': mediaWiki.config.get( 'wgNamespaceNumber' ), |
64 | 67 | 'token': $.cookie( 'clicktracking-session' ), |
65 | 68 | 'redirectto': url |
66 | 69 | } ); |
Index: branches/wmf/1.17wmf1/extensions/ClickTracking/modules/ext.UserBuckets.js |
— | — | @@ -0,0 +1,107 @@ |
| 2 | + |
| 3 | +var JSON; |
| 4 | +if (!JSON) { |
| 5 | + JSON = {}; |
| 6 | + |
| 7 | + if(!JSON.stringify){ |
| 8 | + /* Very limited JSON encoder */ |
| 9 | + JSON.stringify = function( js_obj ) { |
| 10 | + var returnstr = "{ "; |
| 11 | + |
| 12 | + // trailing commas and json don't mix |
| 13 | + var propertynum = 0; |
| 14 | + for ( property in js_obj ) { |
| 15 | + if ( propertynum > 0 ) { |
| 16 | + returnstr += ", "; |
| 17 | + } |
| 18 | + returnstr += "\"" + property + "\"" + " : "; |
| 19 | + if ( typeof js_obj[property] == 'object' ) { |
| 20 | + returnstr += JSON.stringify( js_obj[property] ); |
| 21 | + } else { |
| 22 | + returnstr += "\"" + js_obj[property] + "\" "; |
| 23 | + } |
| 24 | + propertynum++; |
| 25 | + } |
| 26 | + |
| 27 | + returnstr += " }"; |
| 28 | + return returnstr; |
| 29 | + }; |
| 30 | + } |
| 31 | +} |
| 32 | + |
| 33 | +( function( $ ) { |
| 34 | +//lazy-load |
| 35 | +$.getBuckets = function (force){ |
| 36 | + if (typeof($j.userBuckets) == 'undefined' || force ){ |
| 37 | + $j.userBuckets = $.parseJSON( $.cookie('userbuckets') ); |
| 38 | + } |
| 39 | + return $j.userBuckets; |
| 40 | +}; |
| 41 | + |
| 42 | +$.setBucket = function ( bucketName, bucketValue, bucketVersion ){ |
| 43 | + var bucketCookies = $.getBuckets(); |
| 44 | + if(!bucketCookies) { bucketCookies ={};} |
| 45 | + bucketCookies[ bucketName ] = [ bucketValue, bucketVersion ]; |
| 46 | + $j.cookie('userbuckets', JSON.stringify( bucketCookies ) , { expires: 365 }); //expires in 1 year |
| 47 | + bucketCookies = $.getBuckets(true); //force it to rerun and update |
| 48 | +}; |
| 49 | + |
| 50 | +$.setupActiveBuckets = function(){ |
| 51 | + var buckets = $.getBuckets(); |
| 52 | + for(iter in MW.activeCampaigns){ |
| 53 | + var campaign = MW.activeCampaigns[iter]; |
| 54 | + // if bucket has been set, or bucket version is out of date, |
| 55 | + // set up a user bucket |
| 56 | + if(campaign.all){ |
| 57 | + campaign.all(); |
| 58 | + } |
| 59 | + |
| 60 | + if(campaign.preferences && !campaign.preferences.setBuckets){ |
| 61 | + continue; |
| 62 | + } |
| 63 | + |
| 64 | + if(!buckets || !buckets[campaign.name] || buckets[campaign.name][1] < campaign.version){ |
| 65 | + //add up all rates |
| 66 | + var bucketTotal = 0; |
| 67 | + for ( var rate in campaign.rates ){ |
| 68 | + bucketTotal += campaign.rates[rate]; |
| 69 | + } |
| 70 | + |
| 71 | + //give the user a random number in those rates |
| 72 | + var currentUser = Math.floor(Math.random() * (bucketTotal+1)); |
| 73 | + |
| 74 | + // recurse through the rates until we get into the range the user falls in, |
| 75 | + // assign them to that range |
| 76 | + var prev_val = -1; |
| 77 | + var next_val = 0; |
| 78 | + for( rate in campaign.rates ){ |
| 79 | + next_val += campaign.rates[rate]; |
| 80 | + if(prev_val <= currentUser && currentUser < next_val){ |
| 81 | + $.setBucket(campaign.name, rate, campaign.version); |
| 82 | + break; |
| 83 | + } |
| 84 | + prev_val = next_val; |
| 85 | + } |
| 86 | + } |
| 87 | + |
| 88 | + // do the actual code in the campaign based on the bucket |
| 89 | + if($.getBuckets() && $.getBuckets()[campaign.name] && $.getBuckets()[campaign.name][0] != "none"){ |
| 90 | + if(typeof(campaign[$.getBuckets()[campaign.name][0]]) == "function"){ |
| 91 | + campaign[$.getBuckets()[campaign.name][0]](); //function to execute |
| 92 | + } |
| 93 | + if(campaign.allActive){ |
| 94 | + campaign.allActive(); |
| 95 | + } |
| 96 | + } |
| 97 | + |
| 98 | + } |
| 99 | + |
| 100 | +}; |
| 101 | + |
| 102 | +//no need to do any of this if there are no active campaigns |
| 103 | +if( (typeof(MW) != "undefined") && MW.activeCampaigns){ |
| 104 | + $j( document ).ready( jQuery.setupActiveBuckets ); |
| 105 | +} |
| 106 | + |
| 107 | + |
| 108 | +} )( jQuery ); |
Property changes on: branches/wmf/1.17wmf1/extensions/ClickTracking/modules/ext.UserBuckets.js |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 109 | + native |
Index: branches/wmf/1.17wmf1/extensions/ClickTracking/modules/sampleCampaign.js |
— | — | @@ -0,0 +1,53 @@ |
| 2 | + |
| 3 | +//checks |
| 4 | +if(typeof(MW) == "undefined"){ MW={};} |
| 5 | +if(!MW.activeCampaigns){ MW.activeCampaigns ={}; } |
| 6 | + |
| 7 | +//define new active campaign |
| 8 | +MW.activeCampaigns.ArticleSave = |
| 9 | + |
| 10 | +{ |
| 11 | + //Treatment name |
| 12 | + "name": "ArticleSave", |
| 13 | + |
| 14 | + //Treatment version. Increment this when altering rates |
| 15 | + "version": 2, |
| 16 | + |
| 17 | + // Rates are calculated out of the total sum, so |
| 18 | + // rates of x:10000, y:3, and z:1 mean users have a |
| 19 | + // chance of being in bucket x at 10000/10004, |
| 20 | + // y at 3/10004 and z at 1/10004 |
| 21 | + // The algorithm is faster if these are ordered in descending order, |
| 22 | + // particularly if there are orders of magnitude differences in the |
| 23 | + // bucket sizes |
| 24 | + // "none" is reserved for control |
| 25 | + "rates": {"none": 10000, "Bold": 3, "Italics": 1 }, |
| 26 | + |
| 27 | + // individual changes, function names corresponding |
| 28 | + // to what is in "rates" object |
| 29 | + // (note: "none" function not needed or used) |
| 30 | + |
| 31 | + "Bold": function(){ |
| 32 | + //change edit button to bold |
| 33 | + $j("#wpSave").css("font-weight", "bolder"); |
| 34 | + |
| 35 | + }, |
| 36 | + "Italics": function(){ |
| 37 | + //change edit button to italics |
| 38 | + $j("#wpSave").css("font-weight", "normal") |
| 39 | + .css("font-style", "italic"); |
| 40 | + |
| 41 | + }, |
| 42 | + |
| 43 | + // "allActive" is reserved. |
| 44 | + // If this function exists, it will be apply to every user not in the "none" bucket |
| 45 | + "allActive": function(){ |
| 46 | + //add click tracking to save |
| 47 | + $j("#wpSave").click(function(){ $j.trackAction('save'); }); |
| 48 | + //add click tracking to preview |
| 49 | + $j("#wpPreview").click(function(){ $j.trackAction('preview'); }); |
| 50 | + $j("#editpage-copywarn").click(function(){ $j.trackAction('copywarn'); }); |
| 51 | + |
| 52 | + } |
| 53 | + |
| 54 | +}; |
\ No newline at end of file |
Property changes on: branches/wmf/1.17wmf1/extensions/ClickTracking/modules/sampleCampaign.js |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 55 | + native |
Index: branches/wmf/1.17wmf1/extensions/ClickTracking/ClickTracking.i18n.php |
— | — | @@ -60,6 +60,14 @@ |
61 | 61 | 'ct-and' => '{{Identical|And}}', |
62 | 62 | ); |
63 | 63 | |
| 64 | +/** کھوار (کھوار) |
| 65 | + * @author Rachitrali |
| 66 | + */ |
| 67 | +$messages['khw'] = array( |
| 68 | + 'ct-beginner' => 'شروع کوراک', |
| 69 | + 'ct-and' => 'وا', |
| 70 | +); |
| 71 | + |
64 | 72 | /** Afrikaans (Afrikaans) |
65 | 73 | * @author Adriaan |
66 | 74 | * @author Naudefj |
— | — | @@ -184,7 +192,7 @@ |
185 | 193 | 'ct-update-table' => 'حدّث الجدول', |
186 | 194 | ); |
187 | 195 | |
188 | | -/** Bashkir (Башҡорт) |
| 196 | +/** Bashkir (Башҡортса) |
189 | 197 | * @author Assele |
190 | 198 | */ |
191 | 199 | $messages['ba'] = array( |
— | — | @@ -212,7 +220,7 @@ |
213 | 221 | 'ct-update-table' => 'Таблицаны яңыртырға', |
214 | 222 | ); |
215 | 223 | |
216 | | -/** Belarusian (Taraškievica orthography) (Беларуская (тарашкевіца)) |
| 224 | +/** Belarusian (Taraškievica orthography) (Беларуская (тарашкевіца)) |
217 | 225 | * @author EugeneZelenko |
218 | 226 | * @author Jim-by |
219 | 227 | * @author Red Winged Duck |
— | — | @@ -1258,14 +1266,29 @@ |
1259 | 1267 | ); |
1260 | 1268 | |
1261 | 1269 | /** Khmer (ភាសាខ្មែរ) |
| 1270 | + * @author គីមស៊្រុន |
1262 | 1271 | * @author វ័ណថារិទ្ធ |
1263 | 1272 | */ |
1264 | 1273 | $messages['km'] = array( |
1265 | 1274 | 'ct-event-name' => 'ឈ្មោះព្រឹត្តិការណ៍', |
| 1275 | + 'ct-expert-header' => 'ចំនួនការចុចរបស់ «អ្នកជំនាញ»', |
| 1276 | + 'ct-intermediate-header' => 'ចំនួនការចុចរបស់ «អ្នកមធ្យម»', |
| 1277 | + 'ct-beginner-header' => 'ចំនួនការចុចរបស់ «អ្នកដំបូង»', |
1266 | 1278 | 'ct-total-header' => 'ចំនួនចុចសរុប', |
1267 | 1279 | 'ct-start-date' => 'កាលបរិច្ឆេទចាប់ផ្ដើម (YYYYMMDD)', |
1268 | 1280 | 'ct-end-date' => 'កាលបរិច្ឆេទបញ្ចប់ (YYYYMMDD)', |
| 1281 | + 'ct-increment-by' => 'ចំនួនថ្ងៃដែលចំនុចទិន្នន័យនីមួយៗតំណាងអោយ', |
| 1282 | + 'ct-change-graph' => 'ផ្លាស់ប្ដូរក្រាហ្វ', |
| 1283 | + 'ct-beginner' => 'អ្នកដំបូង', |
| 1284 | + 'ct-intermediate' => 'អ្នកមធ្យម', |
| 1285 | + 'ct-expert' => 'អ្នកជំនាញ', |
| 1286 | + 'ct-date-range' => 'ដែនកំណត់កាលបរិច្ឆេទ', |
| 1287 | + 'ct-editing' => 'បច្ចុប្បន្នកំពុងកែប្រែ៖', |
| 1288 | + 'ct-anon-users' => 'អ្នកប្រើប្រាស់អនាមិក', |
| 1289 | + 'ct-user-contribs' => 'ការរួមចំណែកសរុបរបស់អ្នកប្រើប្រាស់', |
| 1290 | + 'ct-user-span' => 'ការរួមចំណែករបស់អ្នកប្រើប្រាស់ក្នុងរយៈកាលមួយ', |
1269 | 1291 | 'ct-and' => 'និង', |
| 1292 | + 'ct-update-table' => 'អាប់ដេតតារាង', |
1270 | 1293 | ); |
1271 | 1294 | |
1272 | 1295 | /** Kannada (ಕನ್ನಡ) |
— | — | @@ -1360,6 +1383,13 @@ |
1361 | 1384 | 'ct-update-table' => 'De Tabäll op der neuste Schtand bränge', |
1362 | 1385 | ); |
1363 | 1386 | |
| 1387 | +/** Kurdish (Latin) (Kurdî (Latin)) |
| 1388 | + * @author George Animal |
| 1389 | + */ |
| 1390 | +$messages['ku-latn'] = array( |
| 1391 | + 'ct-and' => 'û', |
| 1392 | +); |
| 1393 | + |
1364 | 1394 | /** Luxembourgish (Lëtzebuergesch) |
1365 | 1395 | * @author Robby |
1366 | 1396 | */ |
— | — | @@ -1462,14 +1492,14 @@ |
1463 | 1493 | * @author Bjankuloski06 |
1464 | 1494 | */ |
1465 | 1495 | $messages['mk'] = array( |
1466 | | - 'clicktracking' => 'Следење на кликнувања на Иницијативата за употребливост', |
1467 | | - 'clicktracking-desc' => 'Следење на кликнувања, наменето за следење на постапки кои не предизвикуваат превчитување на страницата', |
| 1496 | + 'clicktracking' => 'Следење на стискања на Иницијативата за употребливост', |
| 1497 | + 'clicktracking-desc' => 'Следење на стискања, наменето за следење на постапки кои не предизвикуваат превчитување на страницата', |
1468 | 1498 | 'ct-title' => 'Насобрани кориснички кликови', |
1469 | 1499 | 'ct-event-name' => 'Име на настанот', |
1470 | | - 'ct-expert-header' => '„Експертски“ кликови', |
1471 | | - 'ct-intermediate-header' => '„Средно-учеснички“ кликови', |
1472 | | - 'ct-beginner-header' => '„Почетнички“ кликови', |
1473 | | - 'ct-total-header' => 'Вкупно кликови', |
| 1500 | + 'ct-expert-header' => 'Стискања на „експерти“', |
| 1501 | + 'ct-intermediate-header' => 'Стискања на „средни корисници“', |
| 1502 | + 'ct-beginner-header' => 'Стискања на „почетници“', |
| 1503 | + 'ct-total-header' => 'Вкупно стискања', |
1474 | 1504 | 'ct-start-date' => 'Почетен датум (ГГГГММДД)', |
1475 | 1505 | 'ct-end-date' => 'Завршен датум (ГГГГММДД)', |
1476 | 1506 | 'ct-increment-by' => 'Број на денови што ги претставува секоја податочна точка', |
— | — | @@ -1483,7 +1513,7 @@ |
1484 | 1514 | 'ct-user-contribs' => 'Вкупно кориснички придонеси', |
1485 | 1515 | 'ct-user-span' => 'Ккориснички придонеси за период', |
1486 | 1516 | 'ct-and' => 'и', |
1487 | | - 'ct-update-table' => 'Ажурирај ја таблицата', |
| 1517 | + 'ct-update-table' => 'Поднови ја табелата', |
1488 | 1518 | ); |
1489 | 1519 | |
1490 | 1520 | /** Malayalam (മലയാളം) |
— | — | @@ -1602,9 +1632,10 @@ |
1603 | 1633 | |
1604 | 1634 | /** Nahuatl (Nāhuatl) |
1605 | 1635 | * @author Ricardo gs |
| 1636 | + * @author Teòtlalili |
1606 | 1637 | */ |
1607 | 1638 | $messages['nah'] = array( |
1608 | | - 'ct-and' => 'īhuān', |
| 1639 | + 'ct-and' => 'wàn', |
1609 | 1640 | ); |
1610 | 1641 | |
1611 | 1642 | /** Nedersaksisch (Nedersaksisch) |
— | — | @@ -1615,6 +1646,14 @@ |
1616 | 1647 | 'ct-expert-header' => '"Expert"-kliks', |
1617 | 1648 | ); |
1618 | 1649 | |
| 1650 | +/** Nepali (नेपाली) |
| 1651 | + * @author Bhawani Gautam Rhk |
| 1652 | + */ |
| 1653 | +$messages['ne'] = array( |
| 1654 | + 'ct-and' => 'अनि', |
| 1655 | + 'ct-update-table' => 'तालिका अद्यतन गर्ने', |
| 1656 | +); |
| 1657 | + |
1619 | 1658 | /** Dutch (Nederlands) |
1620 | 1659 | * @author Siebrand |
1621 | 1660 | */ |
— | — | @@ -1733,6 +1772,7 @@ |
1734 | 1773 | * @author Xqt |
1735 | 1774 | */ |
1736 | 1775 | $messages['pdc'] = array( |
| 1776 | + 'ct-beginner' => 'Aafaenger', |
1737 | 1777 | 'ct-and' => 'unn', |
1738 | 1778 | ); |
1739 | 1779 | |
— | — | @@ -2146,7 +2186,7 @@ |
2147 | 2187 | 'ct-update-table' => 'Posodobi tabelo', |
2148 | 2188 | ); |
2149 | 2189 | |
2150 | | -/** Serbian Cyrillic ekavian (Српски (ћирилица)) |
| 2190 | +/** Serbian Cyrillic ekavian (Српски (ћирилица)) |
2151 | 2191 | * @author Rancher |
2152 | 2192 | * @author Михајло Анђелковић |
2153 | 2193 | */ |
— | — | @@ -2161,16 +2201,16 @@ |
2162 | 2202 | 'ct-change-graph' => 'Промени графикон', |
2163 | 2203 | 'ct-beginner' => 'Почетник', |
2164 | 2204 | 'ct-intermediate' => 'Напредни', |
2165 | | - 'ct-expert' => 'Експерт', |
| 2205 | + 'ct-expert' => 'Стручњак', |
2166 | 2206 | 'ct-date-range' => 'Опсег датума', |
2167 | 2207 | 'ct-editing' => 'Тренутно мења:', |
2168 | 2208 | 'ct-anon-users' => 'Анонимни корисници', |
2169 | | - 'ct-user-contribs' => 'Укупно корисничких доприноса', |
| 2209 | + 'ct-user-contribs' => 'Укупно прилога', |
2170 | 2210 | 'ct-and' => 'и', |
2171 | 2211 | 'ct-update-table' => 'Ажурирај табелу', |
2172 | 2212 | ); |
2173 | 2213 | |
2174 | | -/** Serbian Latin ekavian (Srpski (latinica)) */ |
| 2214 | +/** Serbian Latin ekavian (Srpski (latinica)) */ |
2175 | 2215 | $messages['sr-el'] = array( |
2176 | 2216 | 'ct-expert-header' => 'Klikovi "eksperata"', |
2177 | 2217 | 'ct-intermediate-header' => 'Klikovi "naprednih"', |
— | — | @@ -2559,6 +2599,7 @@ |
2560 | 2600 | /** Cantonese (粵語) |
2561 | 2601 | * @author Horacewai2 |
2562 | 2602 | * @author Shinjiman |
| 2603 | + * @author Waihorace |
2563 | 2604 | */ |
2564 | 2605 | $messages['yue'] = array( |
2565 | 2606 | 'clicktracking' => '可用性倡議撳追蹤', |
— | — | @@ -2641,7 +2682,7 @@ |
2642 | 2683 | 'ct-anon-users' => '匿名用戶', |
2643 | 2684 | 'ct-user-contribs' => '用戶貢獻合計', |
2644 | 2685 | 'ct-user-span' => '時間範圍內的用戶貢獻', |
2645 | | - 'ct-and' => '和', |
| 2686 | + 'ct-and' => ' 和 ', |
2646 | 2687 | 'ct-update-table' => '更新表格', |
2647 | 2688 | ); |
2648 | 2689 | |
Index: branches/wmf/1.17wmf1/extensions/ClickTracking/ClickTracking.php |
— | — | @@ -87,4 +87,11 @@ |
88 | 88 | 'styles' => 'ext.clickTracking.special.css', |
89 | 89 | 'dependencies' => array( 'jquery.ui.datepicker', 'jquery.ui.dialog' ), |
90 | 90 | ) + $ctResourceTemplate; |
| 91 | +$wgResourceModules['ext.UserBuckets'] = array( |
| 92 | + 'scripts' => 'ext.UserBuckets.js', |
| 93 | + 'dependencies' => array('jquery.clickTracking', 'jquery.cookie'), |
| 94 | +) + $ctResourceTemplate; |
91 | 95 | |
| 96 | +//uncomment for sample campaign |
| 97 | +//ClickTrackingHooks::addCampaign($dir. 'modules', 'ClickTracking/modules', 'sampleCampaign' ); |
| 98 | + |