Fixed spacing in actions/cache/filebackend/filerepo/job folder
[mediawiki.git] / resources / mediawiki / mediawiki.user.js
blobe036dc9b22229fc62936111cd0f914ecbcf6345a
1 /*
2  * Implementation for mediaWiki.user
3  */
5 ( function ( mw, $ ) {
7         /**
8          * User object
9          */
10         function User( options, tokens ) {
11                 var user, callbacks;
13                 /* Private Members */
15                 user = this;
16                 callbacks = {};
18                 /**
19                  * Gets the current user's groups or rights.
20                  * @param {String} info: One of 'groups' or 'rights'.
21                  * @param {Function} callback
22                  */
23                 function getUserInfo( info, callback ) {
24                         var api;
25                         if ( callbacks[info] ) {
26                                 callbacks[info].add( callback );
27                                 return;
28                         }
29                         callbacks.rights = $.Callbacks('once memory');
30                         callbacks.groups = $.Callbacks('once memory');
31                         callbacks[info].add( callback );
32                         api = new mw.Api();
33                         api.get( {
34                                 action: 'query',
35                                 meta: 'userinfo',
36                                 uiprop: 'rights|groups'
37                         } ).always( function ( data ) {
38                                 var rights, groups;
39                                 if ( data.query && data.query.userinfo ) {
40                                         rights = data.query.userinfo.rights;
41                                         groups = data.query.userinfo.groups;
42                                 }
43                                 callbacks.rights.fire( rights || [] );
44                                 callbacks.groups.fire( groups || [] );
45                         } );
46                 }
48                 /* Public Members */
50                 this.options = options || new mw.Map();
52                 this.tokens = tokens || new mw.Map();
54                 /* Public Methods */
56                 /**
57                  * Generates a random user session ID (32 alpha-numeric characters).
58                  *
59                  * This information would potentially be stored in a cookie to identify a user during a
60                  * session or series of sessions. Its uniqueness should not be depended on.
61                  *
62                  * @return String: Random set of 32 alpha-numeric characters
63                  */
64                 this.generateRandomSessionId = function () {
65                         var i, r,
66                                 id = '',
67                                 seed = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
68                         for ( i = 0; i < 32; i++ ) {
69                                 r = Math.floor( Math.random() * seed.length );
70                                 id += seed.substring( r, r + 1 );
71                         }
72                         return id;
73                 };
75                 /**
76                  * Gets the current user's name.
77                  *
78                  * @return Mixed: User name string or null if users is anonymous
79                  */
80                 this.getName = function () {
81                         return mw.config.get( 'wgUserName' );
82                 };
84                 /**
85                  * @deprecated since 1.20 use mw.user.getName() instead
86                  */
87                 this.name = function () {
88                         return this.getName();
89                 };
91                 /**
92                  * Get date user registered, if available.
93                  *
94                  * @return {Date|false|null} date user registered, or false for anonymous users, or
95                  *  null when data is not available
96                  */
97                 this.getRegistration = function () {
98                         var registration = mw.config.get( 'wgUserRegistration' );
99                         if ( this.isAnon() ) {
100                                 return false;
101                         } else if ( registration === null ) {
102                                 // Information may not be available if they signed up before
103                                 // MW began storing this.
104                                 return null;
105                         } else {
106                                 return new Date( registration );
107                         }
108                 };
110                 /**
111                  * Checks if the current user is anonymous.
112                  *
113                  * @return Boolean
114                  */
115                 this.isAnon = function () {
116                         return user.getName() === null;
117                 };
119                 /**
120                  * @deprecated since 1.20 use mw.user.isAnon() instead
121                  */
122                 this.anonymous = function () {
123                         return user.isAnon();
124                 };
126                 /**
127                  * Gets a random session ID automatically generated and kept in a cookie.
128                  *
129                  * This ID is ephemeral for everyone, staying in their browser only until they close
130                  * their browser.
131                  *
132                  * @return String: User name or random session ID
133                  */
134                 this.sessionId = function () {
135                         var sessionId = $.cookie( 'mediaWiki.user.sessionId' );
136                         if ( typeof sessionId === 'undefined' || sessionId === null ) {
137                                 sessionId = user.generateRandomSessionId();
138                                 $.cookie( 'mediaWiki.user.sessionId', sessionId, { 'expires': null, 'path': '/' } );
139                         }
140                         return sessionId;
141                 };
143                 /**
144                  * Gets the current user's name or a random ID automatically generated and kept in a cookie.
145                  *
146                  * This ID is persistent for anonymous users, staying in their browser up to 1 year. The
147                  * expiration time is reset each time the ID is queried, so in most cases this ID will
148                  * persist until the browser's cookies are cleared or the user doesn't visit for 1 year.
149                  *
150                  * @return {string} User name or random session ID
151                  */
152                 this.id = function () {
153                         var id,
154                                 name = user.getName();
155                         if ( name ) {
156                                 return name;
157                         }
158                         id = $.cookie( 'mediaWiki.user.id' );
159                         if ( typeof id === 'undefined' || id === null ) {
160                                 id = user.generateRandomSessionId();
161                         }
162                         // Set cookie if not set, or renew it if already set
163                         $.cookie( 'mediaWiki.user.id', id, {
164                                 expires: 365,
165                                 path: '/'
166                         } );
167                         return id;
168                 };
170                 /**
171                  * Gets the user's bucket, placing them in one at random based on set odds if needed.
172                  *
173                  * @param key String: Name of bucket
174                  * @param options Object: Bucket configuration options
175                  * @param options.buckets Object: List of bucket-name/relative-probability pairs (required,
176                  * must have at least one pair)
177                  * @param options.version Number: Version of bucket test, changing this forces rebucketing
178                  * (optional, default: 0)
179                  * @param options.expires Number: Length of time (in days) until the user gets rebucketed
180                  * (optional, default: 30)
181                  * @return String: Bucket name - the randomly chosen key of the options.buckets object
182                  *
183                  * @example
184                  *     mw.user.bucket( 'test', {
185                  *         'buckets': { 'ignored': 50, 'control': 25, 'test': 25 },
186                  *         'version': 1,
187                  *         'expires': 7
188                  *     } );
189                  */
190                 this.bucket = function ( key, options ) {
191                         var cookie, parts, version, bucket,
192                                 range, k, rand, total;
194                         options = $.extend( {
195                                 buckets: {},
196                                 version: 0,
197                                 expires: 30
198                         }, options || {} );
200                         cookie = $.cookie( 'mediaWiki.user.bucket:' + key );
202                         // Bucket information is stored as 2 integers, together as version:bucket like: "1:2"
203                         if ( typeof cookie === 'string' && cookie.length > 2 && cookie.indexOf( ':' ) > 0 ) {
204                                 parts = cookie.split( ':' );
205                                 if ( parts.length > 1 && Number( parts[0] ) === options.version ) {
206                                         version = Number( parts[0] );
207                                         bucket = String( parts[1] );
208                                 }
209                         }
210                         if ( bucket === undefined ) {
211                                 if ( !$.isPlainObject( options.buckets ) ) {
212                                         throw 'Invalid buckets error. Object expected for options.buckets.';
213                                 }
214                                 version = Number( options.version );
215                                 // Find range
216                                 range = 0;
217                                 for ( k in options.buckets ) {
218                                         range += options.buckets[k];
219                                 }
220                                 // Select random value within range
221                                 rand = Math.random() * range;
222                                 // Determine which bucket the value landed in
223                                 total = 0;
224                                 for ( k in options.buckets ) {
225                                         bucket = k;
226                                         total += options.buckets[k];
227                                         if ( total >= rand ) {
228                                                 break;
229                                         }
230                                 }
231                                 $.cookie(
232                                         'mediaWiki.user.bucket:' + key,
233                                         version + ':' + bucket,
234                                         { 'path': '/', 'expires': Number( options.expires ) }
235                                 );
236                         }
237                         return bucket;
238                 };
240                 /**
241                  * Gets the current user's groups.
242                  */
243                 this.getGroups = function ( callback ) {
244                         getUserInfo( 'groups', callback );
245                 };
247                 /**
248                  * Gets the current user's rights.
249                  */
250                 this.getRights = function ( callback ) {
251                         getUserInfo( 'rights', callback );
252                 };
253         }
255         // Extend the skeleton mw.user from mediawiki.js
256         // This is kind of ugly but we're stuck with this for b/c reasons
257         mw.user = new User( mw.user.options, mw.user.tokens );
259 }( mediaWiki, jQuery ) );