r43507 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r43506‎ | r43507 | r43508 >
Date:22:48, 14 November 2008
Author:skizzerz
Status:deferred
Tags:
Comment:
* update for EditUser extension, now has complete backwards-compatibility
Modified paths:
  • /trunk/extensions/EditUser/1.11 (added) (history)
  • /trunk/extensions/EditUser/1.11/EditUser_body.php (added) (history)
  • /trunk/extensions/EditUser/1.12 (added) (history)
  • /trunk/extensions/EditUser/1.12/EditUser_body.php (added) (history)
  • /trunk/extensions/EditUser/1.13 (added) (history)
  • /trunk/extensions/EditUser/1.13/EditUser_body.php (added) (history)
  • /trunk/extensions/EditUser/1.14 (added) (history)
  • /trunk/extensions/EditUser/1.14/EditUser_body.php (added) (history)
  • /trunk/extensions/EditUser/EditUser.php (modified) (history)
  • /trunk/extensions/EditUser/EditUser_body.php (deleted) (history)

Diff [purge]

Index: trunk/extensions/EditUser/EditUser_body.php
@@ -1,1132 +0,0 @@
2 -<?php
3 -/* Shamelessly copied and modified from /includes/specials/SpecialPreferences.php */
4 -class EditUser extends SpecialPage {
5 - var $mQuickbar, $mOldpass, $mNewpass, $mRetypePass, $mStubs;
6 - var $mRows, $mCols, $mSkin, $mMath, $mDate, $mUserEmail, $mEmailFlag, $mNick;
7 - var $mUserLanguage, $mUserVariant;
8 - var $mSearch, $mRecent, $mRecentDays, $mHourDiff, $mSearchLines, $mSearchChars, $mAction;
9 - var $mReset, $mPosted, $mToggles, $mSearchNs, $mRealName, $mImageSize;
10 - var $mUnderline, $mWatchlistEdits;
11 - var $user, $target, $mLogout;
12 -
13 - function __construct() {
14 - SpecialPage::SpecialPage('EditUser', 'edituser');
15 - }
16 - /**
17 - * Constructor
18 - * Load some values
19 - */
20 - function loadGlobals( $par ) {
21 - global $wgContLang, $wgAllowRealName, $wgRequest;
22 - $request = $wgRequest;
23 - $this->user = User::newFromName($par);
24 - $this->user->load();
25 - $this->mQuickbar = $request->getVal( 'wpQuickbar' );
26 - $this->mNewpass = $request->getVal( 'wpNewpass' );
27 - $this->mRetypePass =$request->getVal( 'wpRetypePass' );
28 - $this->mStubs = $request->getVal( 'wpStubs' );
29 - $this->mRows = $request->getVal( 'wpRows' );
30 - $this->mCols = $request->getVal( 'wpCols' );
31 - $this->mSkin = $request->getVal( 'wpSkin' );
32 - $this->mMath = $request->getVal( 'wpMath' );
33 - $this->mDate = $request->getVal( 'wpDate' );
34 - $this->mUserEmail = $request->getVal( 'wpUserEmail' );
35 - $this->mRealName = $wgAllowRealName ? $request->getVal( 'wpRealName' ) : '';
36 - $this->mEmailFlag = $request->getCheck( 'wpEmailFlag' ) ? 0 : 1;
37 - $this->mNick = $request->getVal( 'wpNick' );
38 - $this->mUserLanguage = $request->getVal( 'wpUserLanguage' );
39 - $this->mUserVariant = $request->getVal( 'wpUserVariant' );
40 - $this->mSearch = $request->getVal( 'wpSearch' );
41 - $this->mRecent = $request->getVal( 'wpRecent' );
42 - $this->mRecentDays = $request->getVal( 'wpRecentDays' );
43 - $this->mHourDiff = $request->getVal( 'wpHourDiff' );
44 - $this->mSearchLines = $request->getVal( 'wpSearchLines' );
45 - $this->mSearchChars = $request->getVal( 'wpSearchChars' );
46 - $this->mImageSize = $request->getVal( 'wpImageSize' );
47 - $this->mThumbSize = $request->getInt( 'wpThumbSize' );
48 - $this->mUnderline = $request->getInt( 'wpOpunderline' );
49 - $this->mAction = $request->getVal( 'action' );
50 - $this->mReset = $request->getCheck( 'wpReset' );
51 - $this->mPosted = $request->wasPosted();
52 - $this->mSuccess = $request->getCheck( 'success' );
53 - $this->mWatchlistDays = $request->getVal( 'wpWatchlistDays' );
54 - $this->mWatchlistEdits = $request->getVal( 'wpWatchlistEdits' );
55 - $this->mDisableMWSuggest = $request->getCheck( 'wpDisableMWSuggest' );
56 - $this->mLogout = $request->getCheck( 'wpLogout' ) && $this->mPosted;
57 - $this->mSaveprefs = $request->getCheck( 'wpSaveprefs' ) &&
58 - $this->mPosted &&
59 - $this->user->matchEditToken( $request->getVal( 'wpEditToken' ) );
60 -
61 - # User toggles (the big ugly unsorted list of checkboxes)
62 - $this->mToggles = array();
63 - if ( $this->mPosted ) {
64 - $togs = User::getToggles();
65 - foreach ( $togs as $tname ) {
66 - $this->mToggles[$tname] = $request->getCheck( "wpOp$tname" ) ? 1 : 0;
67 - }
68 - }
69 -
70 - $this->mUsedToggles = array();
71 -
72 - # Search namespace options
73 - # Note: namespaces don't necessarily have consecutive keys
74 - $this->mSearchNs = array();
75 - if ( $this->mPosted ) {
76 - $namespaces = $wgContLang->getNamespaces();
77 - foreach ( $namespaces as $i => $namespace ) {
78 - if ( $i >= 0 ) {
79 - $this->mSearchNs[$i] = $request->getCheck( "wpNs$i" ) ? 1 : 0;
80 - }
81 - }
82 - }
83 -
84 - # Validate language
85 - if ( !preg_match( '/^[a-z\-]*$/', $this->mUserLanguage ) ) {
86 - $this->mUserLanguage = 'nolanguage';
87 - }
88 -
89 - wfRunHooks( 'InitPreferencesForm', array( $this, $request ) );
90 - }
91 -
92 - public function execute( $par ) {
93 - global $wgOut, $wgUser, $wgRequest;
94 - if( !$wgUser->isAllowed( 'edituser' ) ) {
95 - $wgOut->permissionRequired( 'edituser' );
96 - return false;
97 - }
98 -
99 - wfLoadExtensionMessages( 'EditUser' );
100 -
101 - $this->setHeaders();
102 - $this->target = (isset($par)) ? $par : $wgRequest->getText('username', '');
103 - if($this->target === '') {
104 - $wgOut->addHTML($this->makeSearchForm());
105 - return;
106 - }
107 - $targetuser = User::NewFromName( $this->target );
108 - if( $targetuser->getID() == 0 ) {
109 - $wgOut->addWikiText( wfMsg( 'edituser-nouser' ) );
110 - return;
111 - }
112 - if( $targetuser->isAllowed('edituser-exempt') ) {
113 - $wgOut->addWikiText( wfMsg( 'edituser-exempt' ) );
114 - return;
115 - }
116 - $this->loadGlobals($this->target);
117 - $wgOut->addHTML($this->makeSearchForm());
118 - $wgOut->addHTML('<br />');
119 - if ( wfReadOnly() ) {
120 - $wgOut->readOnlyPage();
121 - return;
122 - }
123 - if ( $this->mReset ) {
124 - $this->resetPrefs();
125 - $this->mainPrefsForm( 'reset', wfMsg( 'prefsreset' ) );
126 - } else if ($this->mLogout) {
127 - $this->user->doLogout();
128 - } else if ( $this->mSaveprefs ) {
129 - $this->savePreferences();
130 - } else {
131 - $this->resetPrefs();
132 - $this->mainPrefsForm( '' );
133 - }
134 - }
135 - /**
136 - * @access private
137 - */
138 - function validateInt( &$val, $min=0, $max=0x7fffffff ) {
139 - $val = intval($val);
140 - $val = min($val, $max);
141 - $val = max($val, $min);
142 - return $val;
143 - }
144 -
145 - /**
146 - * @access private
147 - */
148 - function validateFloat( &$val, $min, $max=0x7fffffff ) {
149 - $val = floatval( $val );
150 - $val = min( $val, $max );
151 - $val = max( $val, $min );
152 - return( $val );
153 - }
154 -
155 - /**
156 - * @access private
157 - */
158 - function validateIntOrNull( &$val, $min=0, $max=0x7fffffff ) {
159 - $val = trim($val);
160 - if($val === '') {
161 - return null;
162 - } else {
163 - return $this->validateInt( $val, $min, $max );
164 - }
165 - }
166 -
167 - /**
168 - * @access private
169 - */
170 - function validateDate( $val ) {
171 - global $wgLang, $wgContLang;
172 - if ( $val !== false && (
173 - in_array( $val, (array)$wgLang->getDatePreferences() ) ||
174 - in_array( $val, (array)$wgContLang->getDatePreferences() ) ) )
175 - {
176 - return $val;
177 - } else {
178 - return $wgLang->getDefaultDateFormat();
179 - }
180 - }
181 -
182 - /**
183 - * Used to validate the user inputed timezone before saving it as
184 - * 'timecorrection', will return '00:00' if fed bogus data.
185 - * Note: It's not a 100% correct implementation timezone-wise, it will
186 - * accept stuff like '14:30',
187 - * @access private
188 - * @param string $s the user input
189 - * @return string
190 - */
191 - function validateTimeZone( $s ) {
192 - if ( $s !== '' ) {
193 - if ( strpos( $s, ':' ) ) {
194 - # HH:MM
195 - $array = explode( ':' , $s );
196 - $hour = intval( $array[0] );
197 - $minute = intval( $array[1] );
198 - } else {
199 - $minute = intval( $s * 60 );
200 - $hour = intval( $minute / 60 );
201 - $minute = abs( $minute ) % 60;
202 - }
203 - # Max is +14:00 and min is -12:00, see:
204 - # http://en.wikipedia.org/wiki/Timezone
205 - $hour = min( $hour, 14 );
206 - $hour = max( $hour, -12 );
207 - $minute = min( $minute, 59 );
208 - $minute = max( $minute, 0 );
209 - $s = sprintf( "%02d:%02d", $hour, $minute );
210 - }
211 - return $s;
212 - }
213 -
214 - /**
215 - * @access private
216 - */
217 - function savePreferences() {
218 - global $wgUser, $wgOut, $wgParser;
219 - global $wgEnableUserEmail, $wgEnableEmail;
220 - global $wgEmailAuthentication, $wgRCMaxAge;
221 - global $wgAuth, $wgEmailConfirmToEdit;
222 -
223 -
224 - if ( $this->mNewpass !== '' && $wgAuth->allowPasswordChange() ) {
225 - if ( $this->mNewpass != $this->mRetypePass ) {
226 - wfRunHooks( 'PrefsPasswordAudit', array( $this->user, $this->mNewpass, 'badretype' ) );
227 - $this->mainPrefsForm( 'error', wfMsg( 'badretype' ) );
228 - return;
229 - }
230 -
231 - try {
232 - $this->user->setPassword( $this->mNewpass );
233 - wfRunHooks( 'PrefsPasswordAudit', array( $this->user, $this->mNewpass, 'success' ) );
234 - $this->mNewpass = $this->mOldpass = $this->mRetypePass = '';
235 - } catch( PasswordError $e ) {
236 - wfRunHooks( 'PrefsPasswordAudit', array( $this->user, $this->mNewpass, 'error' ) );
237 - $this->mainPrefsForm( 'error', $e->getMessage() );
238 - return;
239 - }
240 - }
241 - $this->user->setRealName( $this->mRealName );
242 - $oldOptions = $this->user->mOptions;
243 -
244 - if( $this->user->getOption( 'language' ) !== $this->mUserLanguage ) {
245 - $needRedirect = true;
246 - } else {
247 - $needRedirect = false;
248 - }
249 -
250 - # Validate the signature and clean it up as needed
251 - global $wgMaxSigChars;
252 - if( mb_strlen( $this->mNick ) > $wgMaxSigChars ) {
253 - global $wgLang;
254 - $this->mainPrefsForm( 'error',
255 - wfMsgExt( 'badsiglength', 'parsemag', $wgLang->formatNum( $wgMaxSigChars ) ) );
256 - return;
257 - } elseif( $this->mToggles['fancysig'] ) {
258 - if( $wgParser->validateSig( $this->mNick ) !== false ) {
259 - $this->mNick = $wgParser->cleanSig( $this->mNick );
260 - } else {
261 - $this->mainPrefsForm( 'error', wfMsg( 'badsig' ) );
262 - return;
263 - }
264 - } else {
265 - // When no fancy sig used, make sure ~{3,5} get removed.
266 - $this->mNick = $wgParser->cleanSigInSig( $this->mNick );
267 - }
268 -
269 - $this->user->setOption( 'language', $this->mUserLanguage );
270 - $this->user->setOption( 'variant', $this->mUserVariant );
271 - $this->user->setOption( 'nickname', $this->mNick );
272 - $this->user->setOption( 'quickbar', $this->mQuickbar );
273 - $this->user->setOption( 'skin', $this->mSkin );
274 - global $wgUseTeX;
275 - if( $wgUseTeX ) {
276 - $this->user->setOption( 'math', $this->mMath );
277 - }
278 - $this->user->setOption( 'date', $this->validateDate( $this->mDate ) );
279 - $this->user->setOption( 'searchlimit', $this->validateIntOrNull( $this->mSearch ) );
280 - $this->user->setOption( 'contextlines', $this->validateIntOrNull( $this->mSearchLines ) );
281 - $this->user->setOption( 'contextchars', $this->validateIntOrNull( $this->mSearchChars ) );
282 - $this->user->setOption( 'rclimit', $this->validateIntOrNull( $this->mRecent ) );
283 - $this->user->setOption( 'rcdays', $this->validateInt($this->mRecentDays, 1, ceil($wgRCMaxAge / (3600*24))));
284 - $this->user->setOption( 'wllimit', $this->validateIntOrNull( $this->mWatchlistEdits, 0, 1000 ) );
285 - $this->user->setOption( 'rows', $this->validateInt( $this->mRows, 4, 1000 ) );
286 - $this->user->setOption( 'cols', $this->validateInt( $this->mCols, 4, 1000 ) );
287 - $this->user->setOption( 'stubthreshold', $this->validateIntOrNull( $this->mStubs ) );
288 - $this->user->setOption( 'timecorrection', $this->validateTimeZone( $this->mHourDiff, -12, 14 ) );
289 - $this->user->setOption( 'imagesize', $this->mImageSize );
290 - $this->user->setOption( 'thumbsize', $this->mThumbSize );
291 - $this->user->setOption( 'underline', $this->validateInt($this->mUnderline, 0, 2) );
292 - $this->user->setOption( 'watchlistdays', $this->validateFloat( $this->mWatchlistDays, 0, 7 ) );
293 - $this->user->setOption( 'disablesuggest', $this->mDisableMWSuggest );
294 -
295 - # Set search namespace options
296 - foreach( $this->mSearchNs as $i => $value ) {
297 - $this->user->setOption( "searchNs{$i}", $value );
298 - }
299 -
300 - if( $wgEnableEmail && $wgEnableUserEmail ) {
301 - $this->user->setOption( 'disablemail', $this->mEmailFlag );
302 - }
303 -
304 - # Set user toggles
305 - foreach ( $this->mToggles as $tname => $tvalue ) {
306 - $this->user->setOption( $tname, $tvalue );
307 - }
308 -
309 - $error = false;
310 - if( $wgEnableEmail ) {
311 - $newadr = $this->mUserEmail;
312 - $oldadr = $this->user->getEmail();
313 - if( ($newadr != '') && ($newadr != $oldadr) ) {
314 - # the user has supplied a new email address on the login page
315 - if( $this->user->isValidEmailAddr( $newadr ) ) {
316 - # new behaviour: set this new emailaddr from login-page into user database record
317 - $this->user->setEmail( $newadr );
318 - # auto-authenticate it
319 - $this->user->confirmEmail();
320 - } else {
321 - $error = wfMsg( 'invalidemailaddress' );
322 - }
323 - } else {
324 - if( $wgEmailConfirmToEdit && empty( $newadr ) ) {
325 - $this->mainPrefsForm( 'error', wfMsg( 'noemailtitle' ) );
326 - return;
327 - }
328 - $this->user->setEmail( $this->mUserEmail );
329 - }
330 - if( $oldadr != $newadr ) {
331 - wfRunHooks( 'PrefsEmailAudit', array( $this->user, $oldadr, $newadr ) );
332 - }
333 - }
334 -
335 - if( !$wgAuth->updateExternalDB( $this->user ) ){
336 - $this->mainPrefsForm( 'error', wfMsg( 'externaldberror' ) );
337 - return;
338 - }
339 -
340 - $msg = '';
341 - if ( !wfRunHooks( 'SavePreferences', array( $this, $this->user, &$msg, $oldOptions ) ) ) {
342 - $this->mainPrefsForm( 'error', $msg );
343 - return;
344 - }
345 -
346 - $this->user->saveSettings();
347 -
348 - if( $needRedirect && $error === false ) {
349 - $title = SpecialPage::getTitleFor( 'Preferences' );
350 - $wgOut->redirect( $title->getFullURL( 'success' ) );
351 - return;
352 - }
353 -
354 - $wgOut->parserOptions( ParserOptions::newFromUser( $this->user ) );
355 - $this->mainPrefsForm( $error === false ? 'success' : 'error', $error);
356 - }
357 -
358 - /**
359 - * @access private
360 - */
361 - function resetPrefs() {
362 - global $wgUser, $wgLang, $wgContLang, $wgContLanguageCode, $wgAllowRealName;
363 -
364 - $this->mNewpass = $this->mRetypePass = '';
365 - $this->mUserEmail = $this->user->getEmail();
366 - $this->mUserEmailAuthenticationtimestamp = $this->user->getEmailAuthenticationtimestamp();
367 - $this->mRealName = ($wgAllowRealName) ? $this->user->getRealName() : '';
368 -
369 - # language value might be blank, default to content language
370 - $this->mUserLanguage = $this->user->getOption( 'language', $wgContLanguageCode );
371 -
372 - $this->mUserVariant = $this->user->getOption( 'variant');
373 - $this->mEmailFlag = $this->user->getOption( 'disablemail' ) == 1 ? 1 : 0;
374 - $this->mNick = $this->user->getOption( 'nickname' );
375 -
376 - $this->mQuickbar = $this->user->getOption( 'quickbar' );
377 - $this->mSkin = Skin::normalizeKey( $this->user->getOption( 'skin' ) );
378 - $this->mMath = $this->user->getOption( 'math' );
379 - $this->mDate = $this->user->getDatePreference();
380 - $this->mRows = $this->user->getOption( 'rows' );
381 - $this->mCols = $this->user->getOption( 'cols' );
382 - $this->mStubs = $this->user->getOption( 'stubthreshold' );
383 - $this->mHourDiff = $this->user->getOption( 'timecorrection' );
384 - $this->mSearch = $this->user->getOption( 'searchlimit' );
385 - $this->mSearchLines = $this->user->getOption( 'contextlines' );
386 - $this->mSearchChars = $this->user->getOption( 'contextchars' );
387 - $this->mImageSize = $this->user->getOption( 'imagesize' );
388 - $this->mThumbSize = $this->user->getOption( 'thumbsize' );
389 - $this->mRecent = $this->user->getOption( 'rclimit' );
390 - $this->mRecentDays = $this->user->getOption( 'rcdays' );
391 - $this->mWatchlistEdits = $this->user->getOption( 'wllimit' );
392 - $this->mUnderline = $this->user->getOption( 'underline' );
393 - $this->mWatchlistDays = $this->user->getOption( 'watchlistdays' );
394 - $this->mDisableMWSuggest = $this->user->getBoolOption( 'disablesuggest' );
395 -
396 - $togs = User::getToggles();
397 - foreach ( $togs as $tname ) {
398 - $this->mToggles[$tname] = $this->user->getOption( $tname );
399 - }
400 -
401 - $namespaces = $wgContLang->getNamespaces();
402 - foreach ( $namespaces as $i => $namespace ) {
403 - if ( $i >= NS_MAIN ) {
404 - $this->mSearchNs[$i] = $this->user->getOption( 'searchNs'.$i );
405 - }
406 - }
407 -
408 - wfRunHooks( 'ResetPreferences', array( $this, $this->user ) );
409 - }
410 -
411 - /**
412 - * @access private
413 - */
414 - function namespacesCheckboxes() {
415 - global $wgContLang;
416 -
417 - # Determine namespace checkboxes
418 - $namespaces = $wgContLang->getNamespaces();
419 - $r1 = null;
420 -
421 - foreach ( $namespaces as $i => $name ) {
422 - if ($i < 0)
423 - continue;
424 - $checked = $this->mSearchNs[$i] ? "checked='checked'" : '';
425 - $name = str_replace( '_', ' ', $namespaces[$i] );
426 -
427 - if ( empty($name) )
428 - $name = wfMsg( 'blanknamespace' );
429 -
430 - $r1 .= "<input type='checkbox' value='1' name='wpNs$i' id='wpNs$i' {$checked}/> <label for='wpNs$i'>{$name}</label><br />\n";
431 - }
432 - return $r1;
433 - }
434 -
435 -
436 - function getToggle( $tname, $trailer = false, $disabled = false ) {
437 - global $wgUser, $wgLang;
438 -
439 - $this->mUsedToggles[$tname] = true;
440 - $ttext = $wgLang->getUserToggle( $tname );
441 -
442 - $checked = $this->user->getOption( $tname ) == 1 ? ' checked="checked"' : '';
443 - $disabled = $disabled ? ' disabled="disabled"' : '';
444 - $trailer = $trailer ? $trailer : '';
445 - return "<div class='toggle'><input type='checkbox' value='1' id=\"$tname\" name=\"wpOp$tname\"$checked$disabled />" .
446 - " <span class='toggletext'><label for=\"$tname\">$ttext</label>$trailer</span></div>\n";
447 - }
448 -
449 - function getToggles( $items ) {
450 - $out = "";
451 - foreach( $items as $item ) {
452 - if( $item === false )
453 - continue;
454 - if( is_array( $item ) ) {
455 - list( $key, $trailer ) = $item;
456 - } else {
457 - $key = $item;
458 - $trailer = false;
459 - }
460 - $out .= $this->getToggle( $key, $trailer );
461 - }
462 - return $out;
463 - }
464 -
465 - function addRow($td1, $td2) {
466 - return "<tr><td class='mw-label'>$td1</td><td class='mw-input'>$td2</td></tr>";
467 - }
468 -
469 - /**
470 - * Helper function for user information panel
471 - * @param $td1 label for an item
472 - * @param $td2 item or null
473 - * @param $td3 optional help or null
474 - * @return xhtml block
475 - */
476 - function tableRow( $td1, $td2 = null, $td3 = null ) {
477 -
478 - if ( is_null( $td3 ) ) {
479 - $td3 = '';
480 - } else {
481 - $td3 = Xml::tags( 'tr', null,
482 - Xml::tags( 'td', array( 'class' => 'pref-label', 'colspan' => '2' ), $td3 )
483 - );
484 - }
485 -
486 - if ( is_null( $td2 ) ) {
487 - $td1 = Xml::tags( 'td', array( 'class' => 'pref-label', 'colspan' => '2' ), $td1 );
488 - $td2 = '';
489 - } else {
490 - $td1 = Xml::tags( 'td', array( 'class' => 'pref-label' ), $td1 );
491 - $td2 = Xml::tags( 'td', array( 'class' => 'pref-input' ), $td2 );
492 - }
493 -
494 - return Xml::tags( 'tr', null, $td1 . $td2 ). $td3 . "\n";
495 -
496 - }
497 -
498 - /**
499 - * @access private
500 - */
501 - function mainPrefsForm( $status , $message = '' ) {
502 - global $wgUser, $wgOut, $wgLang, $wgContLang, $wgAuth;
503 - global $wgAllowRealName, $wgImageLimits, $wgThumbLimits;
504 - global $wgDisableLangConversion, $wgDisableTitleConversion;
505 - global $wgEnotifWatchlist, $wgEnotifUserTalk,$wgEnotifMinorEdits;
506 - global $wgRCShowWatchingUsers, $wgEnotifRevealEditorAddress;
507 - global $wgEnableEmail, $wgEnableUserEmail, $wgEmailAuthentication;
508 - global $wgContLanguageCode, $wgDefaultSkin, $wgCookieExpiration;
509 - global $wgEmailConfirmToEdit, $wgEnableMWSuggest;
510 -
511 - $wgOut->addScriptFile( 'prefs.js' );
512 -
513 - $wgOut->disallowUserJs(); # Prevent hijacked user scripts from sniffing passwords etc.
514 -
515 - if ( $this->mSuccess || 'success' == $status ) {
516 - $wgOut->wrapWikiMsg( '<div class="successbox"><strong>$1</strong></div>', 'savedprefs' );
517 - } else if ( 'error' == $status ) {
518 - $wgOut->addWikiText( '<div class="errorbox"><strong>' . $message . '</strong></div>' );
519 - } else if ( '' != $status ) {
520 - $wgOut->addWikiText( $message . "\n----" );
521 - }
522 -
523 - $qbs = $wgLang->getQuickbarSettings();
524 - $skinNames = $wgLang->getSkinNames();
525 - $mathopts = $wgLang->getMathNames();
526 - $dateopts = $wgLang->getDatePreferences();
527 - $togs = User::getToggles();
528 -
529 - $titleObj = SpecialPage::getTitleFor( 'EditUser' );
530 -
531 - # Pre-expire some toggles so they won't show if disabled
532 - $this->mUsedToggles[ 'shownumberswatching' ] = true;
533 - $this->mUsedToggles[ 'showupdated' ] = true;
534 - $this->mUsedToggles[ 'enotifwatchlistpages' ] = true;
535 - $this->mUsedToggles[ 'enotifusertalkpages' ] = true;
536 - $this->mUsedToggles[ 'enotifminoredits' ] = true;
537 - $this->mUsedToggles[ 'enotifrevealaddr' ] = true;
538 - $this->mUsedToggles[ 'ccmeonemails' ] = true;
539 - $this->mUsedToggles[ 'uselivepreview' ] = true;
540 - $this->mUsedToggles[ 'noconvertlink' ] = true;
541 -
542 -
543 - if ( !$this->mEmailFlag ) { $emfc = 'checked="checked"'; }
544 - else { $emfc = ''; }
545 -
546 -
547 - if ($wgEmailAuthentication && ($this->mUserEmail != '') ) {
548 - if( $this->user->getEmailAuthenticationTimestamp() ) {
549 - // date and time are separate parameters to facilitate localisation.
550 - // $time is kept for backward compat reasons.
551 - // 'emailauthenticated' is also used in SpecialConfirmemail.php
552 - $time = $wgLang->timeAndDate( $this->user->getEmailAuthenticationTimestamp(), true );
553 - $d = $wgLang->date( $this->user->getEmailAuthenticationTimestamp(), true );
554 - $t = $wgLang->time( $this->user->getEmailAuthenticationTimestamp(), true );
555 - $emailauthenticated = wfMsg('emailauthenticated', $time, $d, $t ).'<br />';
556 - $disableEmailPrefs = false;
557 - } else {
558 - $disableEmailPrefs = true;
559 - $skin = $this->user->getSkin();
560 - $emailauthenticated = wfMsg('emailnotauthenticated').'<br />' .
561 - $skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Confirmemail' ),
562 - wfMsg( 'emailconfirmlink' ) ) . '<br />';
563 - }
564 - } else {
565 - $emailauthenticated = '';
566 - $disableEmailPrefs = false;
567 - }
568 -
569 - if ($this->mUserEmail == '') {
570 - $emailauthenticated = wfMsg( 'noemailprefs' ) . '<br />';
571 - }
572 -
573 - $ps = $this->namespacesCheckboxes();
574 -
575 - $enotifwatchlistpages = ($wgEnotifWatchlist) ? $this->getToggle( 'enotifwatchlistpages', false, $disableEmailPrefs ) : '';
576 - $enotifusertalkpages = ($wgEnotifUserTalk) ? $this->getToggle( 'enotifusertalkpages', false, $disableEmailPrefs ) : '';
577 - $enotifminoredits = ($wgEnotifWatchlist && $wgEnotifMinorEdits) ? $this->getToggle( 'enotifminoredits', false, $disableEmailPrefs ) : '';
578 - $enotifrevealaddr = (($wgEnotifWatchlist || $wgEnotifUserTalk) && $wgEnotifRevealEditorAddress) ? $this->getToggle( 'enotifrevealaddr', false, $disableEmailPrefs ) : '';
579 -
580 - # </FIXME>
581 -
582 - $wgOut->addHTML(
583 - Xml::openElement( 'form', array(
584 - 'action' => $titleObj->getLocalUrl(),
585 - 'method' => 'post',
586 - 'id' => 'mw-preferences-form',
587 - ) ) .
588 - Xml::openElement( 'div', array( 'id' => 'preferences' ) )
589 - );
590 -
591 - # User data
592 -
593 - $wgOut->addHTML(
594 - Xml::fieldset( wfMsg('prefs-personal') ) .
595 - Xml::openElement( 'table' ) .
596 - $this->tableRow( Xml::element( 'h2', null, wfMsg( 'prefs-personal' ) ) )
597 - );
598 -
599 - # Get groups to which the user belongs
600 - $userEffectiveGroups = $this->user->getEffectiveGroups();
601 - $userEffectiveGroupsArray = array();
602 - foreach( $userEffectiveGroups as $ueg ) {
603 - if( $ueg == '*' ) {
604 - // Skip the default * group, seems useless here
605 - continue;
606 - }
607 - $userEffectiveGroupsArray[] = User::makeGroupLinkHTML( $ueg );
608 - }
609 - asort( $userEffectiveGroupsArray );
610 -
611 - $sk = $this->user->getSkin();
612 - $toolLinks = array();
613 - $toolLinks[] = $sk->makeKnownLinkObj( SpecialPage::getTitleFor( 'ListGroupRights' ), wfMsg( 'listgrouprights' ) );
614 - # At the moment one tool link only but be prepared for the future...
615 - # FIXME: Add a link to Special:Userrights for users who are allowed to use it.
616 - # $wgUser->isAllowed( 'userrights' ) seems to strict in some cases
617 -
618 - $userInformationHtml =
619 - $this->tableRow( wfMsgHtml( 'username' ), htmlspecialchars( $this->user->getName() ) ) .
620 - $this->tableRow( wfMsgHtml( 'uid' ), $wgLang->formatNum( htmlspecialchars( $this->user->getId() ) ) ).
621 -
622 - $this->tableRow(
623 - wfMsgExt( 'prefs-memberingroups', array( 'parseinline' ), count( $userEffectiveGroupsArray ) ),
624 - $wgLang->commaList( $userEffectiveGroupsArray ) .
625 - '<br />(' . implode( ' | ', $toolLinks ) . ')'
626 - ) .
627 -
628 - $this->tableRow(
629 - wfMsgHtml( 'prefs-edits' ),
630 - $wgLang->formatNum( $this->user->getEditCount() )
631 - );
632 -
633 - if( wfRunHooks( 'PreferencesUserInformationPanel', array( $this, &$userInformationHtml ) ) ) {
634 - $wgOut->addHTML( $userInformationHtml );
635 - }
636 -
637 - if ( $wgAllowRealName ) {
638 - $wgOut->addHTML(
639 - $this->tableRow(
640 - Xml::label( wfMsg('yourrealname'), 'wpRealName' ),
641 - Xml::input( 'wpRealName', 25, $this->mRealName, array( 'id' => 'wpRealName' ) ),
642 - Xml::tags('div', array( 'class' => 'prefsectiontip' ),
643 - wfMsgExt( 'prefs-help-realname', 'parseinline' )
644 - )
645 - )
646 - );
647 - }
648 - if ( $wgEnableEmail ) {
649 - $wgOut->addHTML(
650 - $this->tableRow(
651 - Xml::label( wfMsg('youremail'), 'wpUserEmail' ),
652 - Xml::input( 'wpUserEmail', 25, $this->mUserEmail, array( 'id' => 'wpUserEmail' ) ),
653 - Xml::tags('div', array( 'class' => 'prefsectiontip' ),
654 - wfMsgExt( $wgEmailConfirmToEdit ? 'prefs-help-email-required' : 'prefs-help-email', 'parseinline' )
655 - )
656 - )
657 - );
658 - }
659 -
660 - global $wgParser, $wgMaxSigChars;
661 - if( mb_strlen( $this->mNick ) > $wgMaxSigChars ) {
662 - $invalidSig = $this->tableRow(
663 - '&nbsp;',
664 - Xml::element( 'span', array( 'class' => 'error' ),
665 - wfMsgExt( 'badsiglength', 'parsemag', $wgLang->formatNum( $wgMaxSigChars ) ) )
666 - );
667 - } elseif( !empty( $this->mToggles['fancysig'] ) &&
668 - false === $wgParser->validateSig( $this->mNick ) ) {
669 - $invalidSig = $this->tableRow(
670 - '&nbsp;',
671 - Xml::element( 'span', array( 'class' => 'error' ), wfMsg( 'badsig' ) )
672 - );
673 - } else {
674 - $invalidSig = '';
675 - }
676 -
677 - $wgOut->addHTML(
678 - $this->tableRow(
679 - Xml::label( wfMsg( 'yournick' ), 'wpNick' ),
680 - Xml::input( 'wpNick', 25, $this->mNick,
681 - array(
682 - 'id' => 'wpNick',
683 - // Note: $wgMaxSigChars is enforced in Unicode characters,
684 - // both on the backend and now in the browser.
685 - // Badly-behaved requests may still try to submit
686 - // an overlong string, however.
687 - 'maxlength' => $wgMaxSigChars ) )
688 - ) .
689 - $invalidSig .
690 - $this->tableRow( '&nbsp;', $this->getToggle( 'fancysig' ) )
691 - );
692 -
693 - list( $lsLabel, $lsSelect) = Xml::languageSelector( $this->mUserLanguage );
694 - $wgOut->addHTML(
695 - $this->tableRow( $lsLabel, $lsSelect )
696 - );
697 -
698 - /* see if there are multiple language variants to choose from*/
699 - if(!$wgDisableLangConversion) {
700 - $variants = $wgContLang->getVariants();
701 - $variantArray = array();
702 -
703 - $languages = Language::getLanguageNames( true );
704 - foreach($variants as $v) {
705 - $v = str_replace( '_', '-', strtolower($v));
706 - if( array_key_exists( $v, $languages ) ) {
707 - // If it doesn't have a name, we'll pretend it doesn't exist
708 - $variantArray[$v] = $languages[$v];
709 - }
710 - }
711 -
712 - $options = "\n";
713 - foreach( $variantArray as $code => $name ) {
714 - $selected = ($code == $this->mUserVariant);
715 - $options .= Xml::option( "$code - $name", $code, $selected ) . "\n";
716 - }
717 -
718 - if(count($variantArray) > 1) {
719 - $wgOut->addHTML(
720 - $this->tableRow(
721 - Xml::label( wfMsg( 'yourvariant' ), 'wpUserVariant' ),
722 - Xml::tags( 'select',
723 - array( 'name' => 'wpUserVariant', 'id' => 'wpUserVariant' ),
724 - $options
725 - )
726 - )
727 - );
728 - }
729 -
730 - if(count($variantArray) > 1 && !$wgDisableLangConversion && !$wgDisableTitleConversion) {
731 - $wgOut->addHTML(
732 - Xml::tags( 'tr', null,
733 - Xml::tags( 'td', array( 'colspan' => '2' ),
734 - $this->getToggle( "noconvertlink" )
735 - )
736 - )
737 - );
738 - }
739 - }
740 -
741 - # Password
742 - if( $wgAuth->allowPasswordChange() ) {
743 - $wgOut->addHTML(
744 - $this->tableRow( Xml::element( 'h2', null, wfMsg( 'changepassword' ) ) ) .
745 - $this->tableRow(
746 - Xml::label( wfMsg( 'newpassword' ), 'wpNewpass' ),
747 - Xml::password( 'wpNewpass', 25, $this->mNewpass, array( 'id' => 'wpNewpass' ) )
748 - ) .
749 - $this->tableRow(
750 - Xml::label( wfMsg( 'retypenew' ), 'wpRetypePass' ),
751 - Xml::password( 'wpRetypePass', 25, $this->mRetypePass, array( 'id' => 'wpRetypePass' ) )
752 - )
753 - );
754 - if( $wgCookieExpiration > 0 ){
755 - $wgOut->addHTML(
756 - Xml::tags( 'tr', null,
757 - Xml::tags( 'td', array( 'colspan' => '2' ),
758 - $this->getToggle( "rememberpassword" )
759 - )
760 - )
761 - );
762 - } else {
763 - $this->mUsedToggles['rememberpassword'] = true;
764 - }
765 - }
766 -
767 - # <FIXME>
768 - # Enotif
769 - if ( $wgEnableEmail ) {
770 -
771 - $moreEmail = '';
772 - if ($wgEnableUserEmail) {
773 - // fixme -- the "allowemail" pseudotoggle is a hacked-together
774 - // inversion for the "disableemail" preference.
775 - $emf = wfMsg( 'allowemail' );
776 - $disabled = $disableEmailPrefs ? ' disabled="disabled"' : '';
777 - $moreEmail =
778 - "<input type='checkbox' $emfc $disabled value='1' name='wpEmailFlag' id='wpEmailFlag' /> <label for='wpEmailFlag'>$emf</label>" .
779 - $this->getToggle( 'ccmeonemails', '', $disableEmailPrefs );
780 - }
781 -
782 -
783 - $wgOut->addHTML(
784 - $this->tableRow( Xml::element( 'h2', null, wfMsg( 'email' ) ) ) .
785 - $this->tableRow(
786 - $emailauthenticated.
787 - $enotifrevealaddr.
788 - $enotifwatchlistpages.
789 - $enotifusertalkpages.
790 - $enotifminoredits.
791 - $moreEmail
792 - )
793 - );
794 - }
795 - # </FIXME>
796 -
797 - $wgOut->addHTML(
798 - Xml::closeElement( 'table' ) .
799 - Xml::closeElement( 'fieldset' )
800 - );
801 -
802 -
803 - # Quickbar
804 - #
805 - if ($this->mSkin == 'cologneblue' || $this->mSkin == 'standard') {
806 - $wgOut->addHTML( "<fieldset>\n<legend>" . wfMsg( 'qbsettings' ) . "</legend>\n" );
807 - for ( $i = 0; $i < count( $qbs ); ++$i ) {
808 - if ( $i == $this->mQuickbar ) { $checked = ' checked="checked"'; }
809 - else { $checked = ""; }
810 - $wgOut->addHTML( "<div><label><input type='radio' name='wpQuickbar' value=\"$i\"$checked />{$qbs[$i]}</label></div>\n" );
811 - }
812 - $wgOut->addHTML( "</fieldset>\n\n" );
813 - } else {
814 - # Need to output a hidden option even if the relevant skin is not in use,
815 - # otherwise the preference will get reset to 0 on submit
816 - $wgOut->addHTML( wfHidden( 'wpQuickbar', $this->mQuickbar ) );
817 - }
818 -
819 - # Skin
820 - #
821 - $wgOut->addHTML( "<fieldset>\n<legend>\n" . wfMsg('skin') . "</legend>\n" );
822 - $mptitle = Title::newMainPage();
823 - $previewtext = wfMsg('skin-preview');
824 - # Only show members of Skin::getSkinNames() rather than
825 - # $skinNames (skins is all skin names from Language.php)
826 - $validSkinNames = Skin::getUsableSkins();
827 - # Sort by UI skin name. First though need to update validSkinNames as sometimes
828 - # the skinkey & UI skinname differ (e.g. "standard" skinkey is "Classic" in the UI).
829 - foreach ($validSkinNames as $skinkey => & $skinname ) {
830 - if ( isset( $skinNames[$skinkey] ) ) {
831 - $skinname = $skinNames[$skinkey];
832 - }
833 - }
834 - asort($validSkinNames);
835 - foreach ($validSkinNames as $skinkey => $sn ) {
836 - $checked = $skinkey == $this->mSkin ? ' checked="checked"' : '';
837 -
838 - $mplink = htmlspecialchars($mptitle->getLocalURL("useskin=$skinkey"));
839 - $previewlink = "(<a target='_blank' href=\"$mplink\">$previewtext</a>)";
840 - if( $skinkey == $wgDefaultSkin )
841 - $sn .= ' (' . wfMsg( 'default' ) . ')';
842 - $wgOut->addHTML( "<input type='radio' name='wpSkin' id=\"wpSkin$skinkey\" value=\"$skinkey\"$checked /> <label for=\"wpSkin$skinkey\">{$sn}</label> $previewlink<br />\n" );
843 - }
844 - $wgOut->addHTML( "</fieldset>\n\n" );
845 -
846 - # Math
847 - #
848 - global $wgUseTeX;
849 - if( $wgUseTeX ) {
850 - $wgOut->addHTML( "<fieldset>\n<legend>" . wfMsg('math') . '</legend>' );
851 - foreach ( $mathopts as $k => $v ) {
852 - $checked = ($k == $this->mMath);
853 - $wgOut->addHTML(
854 - Xml::openElement( 'div' ) .
855 - Xml::radioLabel( wfMsg( $v ), 'wpMath', $k, "mw-sp-math-$k", $checked ) .
856 - Xml::closeElement( 'div' ) . "\n"
857 - );
858 - }
859 - $wgOut->addHTML( "</fieldset>\n\n" );
860 - }
861 -
862 - # Files
863 - #
864 - $wgOut->addHTML(
865 - "<fieldset>\n" . Xml::element( 'legend', null, wfMsg( 'files' ) ) . "\n"
866 - );
867 -
868 - $imageLimitOptions = null;
869 - foreach ( $wgImageLimits as $index => $limits ) {
870 - $selected = ($index == $this->mImageSize);
871 - $imageLimitOptions .= Xml::option( "{$limits[0]}×{$limits[1]}" .
872 - wfMsg('unit-pixel'), $index, $selected );
873 - }
874 -
875 - $imageSizeId = 'wpImageSize';
876 - $wgOut->addHTML(
877 - "<div>" . Xml::label( wfMsg('imagemaxsize'), $imageSizeId ) . " " .
878 - Xml::openElement( 'select', array( 'name' => $imageSizeId, 'id' => $imageSizeId ) ) .
879 - $imageLimitOptions .
880 - Xml::closeElement( 'select' ) . "</div>\n"
881 - );
882 -
883 - $imageThumbOptions = null;
884 - foreach ( $wgThumbLimits as $index => $size ) {
885 - $selected = ($index == $this->mThumbSize);
886 - $imageThumbOptions .= Xml::option($size . wfMsg('unit-pixel'), $index,
887 - $selected);
888 - }
889 -
890 - $thumbSizeId = 'wpThumbSize';
891 - $wgOut->addHTML(
892 - "<div>" . Xml::label( wfMsg('thumbsize'), $thumbSizeId ) . " " .
893 - Xml::openElement( 'select', array( 'name' => $thumbSizeId, 'id' => $thumbSizeId ) ) .
894 - $imageThumbOptions .
895 - Xml::closeElement( 'select' ) . "</div>\n"
896 - );
897 -
898 - $wgOut->addHTML( "</fieldset>\n\n" );
899 -
900 - # Date format
901 - #
902 - # Date/Time
903 - #
904 -
905 - $wgOut->addHTML(
906 - Xml::openElement( 'fieldset' ) .
907 - Xml::element( 'legend', null, wfMsg( 'datetime' ) ) . "\n"
908 - );
909 -
910 - if ($dateopts) {
911 - $wgOut->addHTML(
912 - Xml::openElement( 'fieldset' ) .
913 - Xml::element( 'legend', null, wfMsg( 'dateformat' ) ) . "\n"
914 - );
915 - $idCnt = 0;
916 - $epoch = '20010115161234'; # Wikipedia day
917 - foreach( $dateopts as $key ) {
918 - if( $key == 'default' ) {
919 - $formatted = wfMsg( 'datedefault' );
920 - } else {
921 - $formatted = $wgLang->timeanddate( $epoch, false, $key );
922 - }
923 - $wgOut->addHTML(
924 - Xml::tags( 'div', null,
925 - Xml::radioLabel( $formatted, 'wpDate', $key, "wpDate$idCnt", $key == $this->mDate )
926 - ) . "\n"
927 - );
928 - $idCnt++;
929 - }
930 - $wgOut->addHTML( Xml::closeElement( 'fieldset' ) . "\n" );
931 - }
932 -
933 - $nowlocal = $wgLang->time( $now = wfTimestampNow(), true );
934 - $nowserver = $wgLang->time( $now, false );
935 -
936 - $wgOut->addHTML(
937 - Xml::openElement( 'fieldset' ) .
938 - Xml::element( 'legend', null, wfMsg( 'timezonelegend' ) ) .
939 - Xml::openElement( 'table' ) .
940 - $this->addRow( wfMsg( 'servertime' ), $nowserver ) .
941 - $this->addRow( wfMsg( 'localtime' ), $nowlocal ) .
942 - $this->addRow(
943 - Xml::label( wfMsg( 'timezoneoffset' ), 'wpHourDiff' ),
944 - Xml::input( 'wpHourDiff', 6, $this->mHourDiff, array( 'id' => 'wpHourDiff' ) ) ) .
945 - "<tr>
946 - <td></td>
947 - <td class='mw-submit'>" .
948 - Xml::element( 'input',
949 - array( 'type' => 'button',
950 - 'value' => wfMsg( 'guesstimezone' ),
951 - 'onclick' => 'javascript:guessTimezone()',
952 - 'id' => 'guesstimezonebutton',
953 - 'style' => 'display:none;' ) ) .
954 - "</td>
955 - </tr>" .
956 - Xml::closeElement( 'table' ) .
957 - Xml::tags( 'div', array( 'class' => 'prefsectiontip' ), wfMsgExt( 'timezonetext', 'parseinline' ) ).
958 - Xml::closeElement( 'fieldset' ) .
959 - Xml::closeElement( 'fieldset' ) . "\n\n"
960 - );
961 -
962 - # Editing
963 - #
964 - global $wgLivePreview;
965 - $wgOut->addHTML( '<fieldset><legend>' . wfMsg( 'textboxsize' ) . '</legend>
966 - <div>' .
967 - wfInputLabel( wfMsg( 'rows' ), 'wpRows', 'wpRows', 3, $this->mRows ) .
968 - ' ' .
969 - wfInputLabel( wfMsg( 'columns' ), 'wpCols', 'wpCols', 3, $this->mCols ) .
970 - "</div>" .
971 - $this->getToggles( array(
972 - 'editsection',
973 - 'editsectiononrightclick',
974 - 'editondblclick',
975 - 'editwidth',
976 - 'showtoolbar',
977 - 'previewonfirst',
978 - 'previewontop',
979 - 'minordefault',
980 - 'externaleditor',
981 - 'externaldiff',
982 - $wgLivePreview ? 'uselivepreview' : false,
983 - 'forceeditsummary',
984 - ) ) . '</fieldset>'
985 - );
986 -
987 - # Recent changes
988 - $wgOut->addHTML( '<fieldset><legend>' . wfMsgHtml( 'prefs-rc' ) . '</legend>' );
989 -
990 - $rc = '<table><tr>';
991 - $rc .= '<td>' . Xml::label( wfMsg( 'recentchangesdays' ), 'wpRecentDays' ) . '</td>';
992 - $rc .= '<td>' . Xml::input( 'wpRecentDays', 3, $this->mRecentDays, array( 'id' => 'wpRecentDays' ) ) . '</td>';
993 - $rc .= '</tr><tr>';
994 - $rc .= '<td>' . Xml::label( wfMsg( 'recentchangescount' ), 'wpRecent' ) . '</td>';
995 - $rc .= '<td>' . Xml::input( 'wpRecent', 3, $this->mRecent, array( 'id' => 'wpRecent' ) ) . '</td>';
996 - $rc .= '</tr></table>';
997 - $wgOut->addHTML( $rc );
998 -
999 - $wgOut->addHTML( '<br />' );
1000 -
1001 - $toggles[] = 'hideminor';
1002 - if( $wgRCShowWatchingUsers )
1003 - $toggles[] = 'shownumberswatching';
1004 - $toggles[] = 'usenewrc';
1005 - $wgOut->addHTML( $this->getToggles( $toggles ) );
1006 -
1007 - $wgOut->addHTML( '</fieldset>' );
1008 -
1009 - # Watchlist
1010 - $wgOut->addHTML( '<fieldset><legend>' . wfMsgHtml( 'prefs-watchlist' ) . '</legend>' );
1011 -
1012 - $wgOut->addHTML( wfInputLabel( wfMsg( 'prefs-watchlist-days' ), 'wpWatchlistDays', 'wpWatchlistDays', 3, $this->mWatchlistDays ) );
1013 - $wgOut->addHTML( '<br /><br />' );
1014 -
1015 - $wgOut->addHTML( $this->getToggle( 'extendwatchlist' ) );
1016 - $wgOut->addHTML( wfInputLabel( wfMsg( 'prefs-watchlist-edits' ), 'wpWatchlistEdits', 'wpWatchlistEdits', 3, $this->mWatchlistEdits ) );
1017 - $wgOut->addHTML( '<br /><br />' );
1018 -
1019 - $wgOut->addHTML( $this->getToggles( array( 'watchlisthideminor', 'watchlisthidebots', 'watchlisthideown', 'watchlisthideanons', 'watchlisthideliu' ) ) );
1020 -
1021 - if( $this->user->isAllowed( 'createpage' ) || $this->user->isAllowed( 'createtalk' ) )
1022 - $wgOut->addHTML( $this->getToggle( 'watchcreations' ) );
1023 - foreach( array( 'edit' => 'watchdefault', 'move' => 'watchmoves', 'delete' => 'watchdeletion' ) as $action => $toggle ) {
1024 - if( $this->user->isAllowed( $action ) )
1025 - $wgOut->addHTML( $this->getToggle( $toggle ) );
1026 - }
1027 - $this->mUsedToggles['watchcreations'] = true;
1028 - $this->mUsedToggles['watchdefault'] = true;
1029 - $this->mUsedToggles['watchmoves'] = true;
1030 - $this->mUsedToggles['watchdeletion'] = true;
1031 -
1032 - $wgOut->addHTML( '</fieldset>' );
1033 -
1034 - # Search
1035 - $mwsuggest = $wgEnableMWSuggest ?
1036 - $this->addRow(
1037 - Xml::label( wfMsg( 'mwsuggest-disable' ), 'wpDisableMWSuggest' ),
1038 - Xml::check( 'wpDisableMWSuggest', $this->mDisableMWSuggest, array( 'id' => 'wpDisableMWSuggest' ) )
1039 - ) : '';
1040 - $wgOut->addHTML(
1041 - // Elements for the search tab itself
1042 - Xml::openElement( 'fieldset' ) .
1043 - Xml::element( 'legend', null, wfMsg( 'searchresultshead' ) ) .
1044 - // Elements for the search options in the search tab
1045 - Xml::openElement( 'fieldset' ) .
1046 - Xml::element( 'legend', null, wfMsg( 'prefs-searchoptions' ) ) .
1047 - Xml::openElement( 'table' ) .
1048 - $this->addRow(
1049 - Xml::label( wfMsg( 'resultsperpage' ), 'wpSearch' ),
1050 - Xml::input( 'wpSearch', 4, $this->mSearch, array( 'id' => 'wpSearch' ) )
1051 - ) .
1052 - $this->addRow(
1053 - Xml::label( wfMsg( 'contextlines' ), 'wpSearchLines' ),
1054 - Xml::input( 'wpSearchLines', 4, $this->mSearchLines, array( 'id' => 'wpSearchLines' ) )
1055 - ) .
1056 - $this->addRow(
1057 - Xml::label( wfMsg( 'contextchars' ), 'wpSearchChars' ),
1058 - Xml::input( 'wpSearchChars', 4, $this->mSearchChars, array( 'id' => 'wpSearchChars' ) )
1059 - ) .
1060 - $mwsuggest .
1061 - Xml::closeElement( 'table' ) .
1062 - Xml::closeElement( 'fieldset' ) .
1063 - // Elements for the namespace options in the search tab
1064 - Xml::openElement( 'fieldset' ) .
1065 - Xml::element( 'legend', null, wfMsg( 'prefs-namespaces' ) ) .
1066 - wfMsgExt( 'defaultns', array( 'parse' ) ) .
1067 - $ps .
1068 - Xml::closeElement( 'fieldset' ) .
1069 - // End of the search tab
1070 - Xml::closeElement( 'fieldset' )
1071 - );
1072 -
1073 - # Misc
1074 - #
1075 - $wgOut->addHTML('<fieldset><legend>' . wfMsg('prefs-misc') . '</legend>');
1076 - $wgOut->addHTML( '<label for="wpStubs">' . wfMsg( 'stub-threshold' ) . '</label>&nbsp;' );
1077 - $wgOut->addHTML( Xml::input( 'wpStubs', 6, $this->mStubs, array( 'id' => 'wpStubs' ) ) );
1078 - $msgUnderline = htmlspecialchars( wfMsg ( 'tog-underline' ) );
1079 - $msgUnderlinenever = htmlspecialchars( wfMsg ( 'underline-never' ) );
1080 - $msgUnderlinealways = htmlspecialchars( wfMsg ( 'underline-always' ) );
1081 - $msgUnderlinedefault = htmlspecialchars( wfMsg ( 'underline-default' ) );
1082 - $uopt = $this->user->getOption("underline");
1083 - $s0 = $uopt == 0 ? ' selected="selected"' : '';
1084 - $s1 = $uopt == 1 ? ' selected="selected"' : '';
1085 - $s2 = $uopt == 2 ? ' selected="selected"' : '';
1086 - $wgOut->addHTML("
1087 -<div class='toggle'><p><label for='wpOpunderline'>$msgUnderline</label>
1088 -<select name='wpOpunderline' id='wpOpunderline'>
1089 -<option value=\"0\"$s0>$msgUnderlinenever</option>
1090 -<option value=\"1\"$s1>$msgUnderlinealways</option>
1091 -<option value=\"2\"$s2>$msgUnderlinedefault</option>
1092 -</select></p></div>");
1093 -
1094 - foreach ( $togs as $tname ) {
1095 - if( !array_key_exists( $tname, $this->mUsedToggles ) ) {
1096 - $wgOut->addHTML( $this->getToggle( $tname ) );
1097 - }
1098 - }
1099 - $wgOut->addHTML( '</fieldset>' );
1100 -
1101 - wfRunHooks( 'RenderPreferencesForm', array( $this, $wgOut ) );
1102 -
1103 - $token = htmlspecialchars( $this->user->editToken() );
1104 - $skin = $this->user->getSkin();
1105 - $wgOut->addHTML( "
1106 - <div id='prefsubmit'>
1107 - <div>
1108 - <input type='submit' name='wpSaveprefs' class='btnSavePrefs' value=\"" . wfMsgHtml( 'saveprefs' ) . '"'.$skin->tooltipAndAccesskey('save')." />
1109 - <input type='submit' name='wpReset' value=\"" . wfMsgHtml( 'resetprefs' ) . "\" />
1110 - </div>
1111 -
1112 - </div>
1113 -
1114 - <input type='hidden' name='wpEditToken' value=\"{$token}\" />
1115 - <input type='hidden' name='username' value=\"{$this->target}\" />
1116 - </div></form>\n" );
1117 -
1118 - $wgOut->addHTML( Xml::tags( 'div', array( 'class' => "prefcache" ),
1119 - wfMsgExt( 'clearyourcache', 'parseinline' ) )
1120 - );
1121 - }
1122 -
1123 - function makeSearchForm() {
1124 - $thisTitle = Title::makeTitle( NS_SPECIAL, $this->getName() );
1125 - $form = wfOpenElement( 'form', array( 'method' => 'post', 'action' => $thisTitle->getLocalUrl() ) );
1126 - $form .= wfElement( 'label', array( 'for' => 'username' ), wfMsg( 'edituser-username' ) ) . ' ';
1127 - $form .= wfElement( 'input', array( 'type' => 'text', 'name' => 'username', 'id' => 'username', 'value' => $this->target ) ) . ' ';
1128 - $form .= wfElement( 'input', array( 'type' => 'submit', 'name' => 'dosearch', 'value' => wfMsg( 'edituser-dosearch' ) ) );
1129 - $form .= wfElement( 'input', array( 'type' => 'hidden', 'name' => 'issearch', 'value' => '1' ) );
1130 - $form .= wfCloseElement( 'form' );
1131 - return $form;
1132 - }
1133 -}
Index: trunk/extensions/EditUser/1.11/EditUser_body.php
@@ -0,0 +1,1023 @@
 2+<?php
 3+/* Shamelessly copied and modified from /includes/specials/SpecialPreferences.php v1.11 */
 4+class EditUser extends SpecialPage {
 5+ var $mQuickbar, $mOldpass, $mNewpass, $mRetypePass, $mStubs;
 6+ var $mRows, $mCols, $mSkin, $mMath, $mDate, $mUserEmail, $mEmailFlag, $mNick;
 7+ var $mUserLanguage, $mUserVariant;
 8+ var $mSearch, $mRecent, $mRecentDays, $mHourDiff, $mSearchLines, $mSearchChars, $mAction;
 9+ var $mReset, $mPosted, $mToggles, $mSearchNs, $mRealName, $mImageSize;
 10+ var $mUnderline, $mWatchlistEdits;
 11+ var $user, $target;
 12+
 13+ function __construct() {
 14+ SpecialPage::SpecialPage('EditUser', 'edituser');
 15+ }
 16+ /**
 17+ * Constructor
 18+ * Load some values
 19+ */
 20+ function loadGlobals( $par ) {
 21+ global $wgContLang, $wgAllowRealName, $wgRequest;
 22+ $request = $wgRequest;
 23+ $this->mQuickbar = $request->getVal( 'wpQuickbar' );
 24+ $this->mNewpass = $request->getVal( 'wpNewpass' );
 25+ $this->mRetypePass =$request->getVal( 'wpRetypePass' );
 26+ $this->mStubs = $request->getVal( 'wpStubs' );
 27+ $this->mRows = $request->getVal( 'wpRows' );
 28+ $this->mCols = $request->getVal( 'wpCols' );
 29+ $this->mSkin = $request->getVal( 'wpSkin' );
 30+ $this->mMath = $request->getVal( 'wpMath' );
 31+ $this->mDate = $request->getVal( 'wpDate' );
 32+ $this->mUserEmail = $request->getVal( 'wpUserEmail' );
 33+ $this->mRealName = $wgAllowRealName ? $request->getVal( 'wpRealName' ) : '';
 34+ $this->mEmailFlag = $request->getCheck( 'wpEmailFlag' ) ? 0 : 1;
 35+ $this->mNick = $request->getVal( 'wpNick' );
 36+ $this->mUserLanguage = $request->getVal( 'wpUserLanguage' );
 37+ $this->mUserVariant = $request->getVal( 'wpUserVariant' );
 38+ $this->mSearch = $request->getVal( 'wpSearch' );
 39+ $this->mRecent = $request->getVal( 'wpRecent' );
 40+ $this->mRecentDays = $request->getVal( 'wpRecentDays' );
 41+ $this->mHourDiff = $request->getVal( 'wpHourDiff' );
 42+ $this->mSearchLines = $request->getVal( 'wpSearchLines' );
 43+ $this->mSearchChars = $request->getVal( 'wpSearchChars' );
 44+ $this->mImageSize = $request->getVal( 'wpImageSize' );
 45+ $this->mThumbSize = $request->getInt( 'wpThumbSize' );
 46+ $this->mUnderline = $request->getInt( 'wpOpunderline' );
 47+ $this->mAction = $request->getVal( 'action' );
 48+ $this->mReset = $request->getCheck( 'wpReset' );
 49+ $this->mPosted = $request->wasPosted();
 50+ $this->mSuccess = $request->getCheck( 'success' );
 51+ $this->mWatchlistDays = $request->getVal( 'wpWatchlistDays' );
 52+ $this->mWatchlistEdits = $request->getVal( 'wpWatchlistEdits' );
 53+ $this->mSaveprefs = $request->getCheck( 'wpSaveprefs' ) &&
 54+ $this->mPosted &&
 55+ $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) );
 56+
 57+ # User toggles (the big ugly unsorted list of checkboxes)
 58+ $this->mToggles = array();
 59+ if ( $this->mPosted ) {
 60+ $togs = User::getToggles();
 61+ foreach ( $togs as $tname ) {
 62+ $this->mToggles[$tname] = $request->getCheck( "wpOp$tname" ) ? 1 : 0;
 63+ }
 64+ }
 65+
 66+ $this->mUsedToggles = array();
 67+
 68+ # Search namespace options
 69+ # Note: namespaces don't necessarily have consecutive keys
 70+ $this->mSearchNs = array();
 71+ if ( $this->mPosted ) {
 72+ $namespaces = $wgContLang->getNamespaces();
 73+ foreach ( $namespaces as $i => $namespace ) {
 74+ if ( $i >= 0 ) {
 75+ $this->mSearchNs[$i] = $request->getCheck( "wpNs$i" ) ? 1 : 0;
 76+ }
 77+ }
 78+ }
 79+
 80+ # Validate language
 81+ if ( !preg_match( '/^[a-z\-]*$/', $this->mUserLanguage ) ) {
 82+ $this->mUserLanguage = 'nolanguage';
 83+ }
 84+
 85+ wfRunHooks( "InitPreferencesForm", array( $this, $request ) );
 86+ }
 87+
 88+ function execute( $par ) {
 89+ global $wgOut, $wgUser, $wgRequest;
 90+ if( !$wgUser->isAllowed( 'edituser' ) ) {
 91+ $wgOut->permissionRequired( 'edituser' );
 92+ return false;
 93+ }
 94+
 95+ wfLoadExtensionMessages( 'EditUser' );
 96+
 97+ $this->setHeaders();
 98+ $this->target = (isset($par)) ? $par : $wgRequest->getText('username', '');
 99+ if($this->target === '') {
 100+ $wgOut->addHtml($this->makeSearchForm());
 101+ return;
 102+ }
 103+ $targetuser = User::NewFromName( $this->target );
 104+ if( $targetuser->getID() == 0 ) {
 105+ $wgOut->addWikiText( wfMsg( 'edituser-nouser' ) );
 106+ return;
 107+ }
 108+ if( $targetuser->isAllowed('edituser-exempt') ) {
 109+ $wgOut->addWikiText( wfMsg( 'edituser-exempt' ) );
 110+ return;
 111+ }
 112+ $this->loadGlobals($this->target);
 113+ $wgOut->addHtml($this->makeSearchForm());
 114+ $wgOut->addHtml('<br />');
 115+ if ( wfReadOnly() ) {
 116+ $wgOut->readOnlyPage();
 117+ return;
 118+ }
 119+ if ( $this->mReset ) {
 120+ $this->resetPrefs();
 121+ $this->mainPrefsForm( 'reset', wfMsg( 'prefsreset' ) );
 122+ } else if ( $this->mSaveprefs ) {
 123+ $this->savePreferences();
 124+ } else {
 125+ $this->resetPrefs();
 126+ $this->mainPrefsForm( '' );
 127+ }
 128+ }
 129+ /**
 130+ * @access private
 131+ */
 132+ function validateInt( &$val, $min=0, $max=0x7fffffff ) {
 133+ $val = intval($val);
 134+ $val = min($val, $max);
 135+ $val = max($val, $min);
 136+ return $val;
 137+ }
 138+
 139+ /**
 140+ * @access private
 141+ */
 142+ function validateFloat( &$val, $min, $max=0x7fffffff ) {
 143+ $val = floatval( $val );
 144+ $val = min( $val, $max );
 145+ $val = max( $val, $min );
 146+ return( $val );
 147+ }
 148+
 149+ /**
 150+ * @access private
 151+ */
 152+ function validateIntOrNull( &$val, $min=0, $max=0x7fffffff ) {
 153+ $val = trim($val);
 154+ if($val === '') {
 155+ return $val;
 156+ } else {
 157+ return $this->validateInt( $val, $min, $max );
 158+ }
 159+ }
 160+
 161+ /**
 162+ * @access private
 163+ */
 164+ function validateDate( $val ) {
 165+ global $wgLang, $wgContLang;
 166+ if ( $val !== false && (
 167+ in_array( $val, (array)$wgLang->getDatePreferences() ) ||
 168+ in_array( $val, (array)$wgContLang->getDatePreferences() ) ) )
 169+ {
 170+ return $val;
 171+ } else {
 172+ return $wgLang->getDefaultDateFormat();
 173+ }
 174+ }
 175+
 176+ /**
 177+ * Used to validate the user inputed timezone before saving it as
 178+ * 'timecorrection', will return '00:00' if fed bogus data.
 179+ * Note: It's not a 100% correct implementation timezone-wise, it will
 180+ * accept stuff like '14:30',
 181+ * @access private
 182+ * @param string $s the user input
 183+ * @return string
 184+ */
 185+ function validateTimeZone( $s ) {
 186+ if ( $s !== '' ) {
 187+ if ( strpos( $s, ':' ) ) {
 188+ # HH:MM
 189+ $array = explode( ':' , $s );
 190+ $hour = intval( $array[0] );
 191+ $minute = intval( $array[1] );
 192+ } else {
 193+ $minute = intval( $s * 60 );
 194+ $hour = intval( $minute / 60 );
 195+ $minute = abs( $minute ) % 60;
 196+ }
 197+ # Max is +14:00 and min is -12:00, see:
 198+ # http://en.wikipedia.org/wiki/Timezone
 199+ $hour = min( $hour, 14 );
 200+ $hour = max( $hour, -12 );
 201+ $minute = min( $minute, 59 );
 202+ $minute = max( $minute, 0 );
 203+ $s = sprintf( "%02d:%02d", $hour, $minute );
 204+ }
 205+ return $s;
 206+ }
 207+
 208+ /**
 209+ * @access private
 210+ */
 211+ function savePreferences() {
 212+ global $wgUser, $wgOut, $wgParser;
 213+ global $wgEnableUserEmail, $wgEnableEmail;
 214+ global $wgEmailAuthentication;
 215+ global $wgAuth;
 216+
 217+
 218+ if ( '' != $this->mNewpass && $wgAuth->allowPasswordChange() ) {
 219+ if ( $this->mNewpass != $this->mRetypePass ) {
 220+ wfRunHooks( "PrefsPasswordAudit", array( $this->user, $this->mNewpass, 'badretype' ) );
 221+ $this->mainPrefsForm( 'error', wfMsg( 'badretype' ) );
 222+ return;
 223+ }
 224+
 225+ try {
 226+ $this->user->setPassword( $this->mNewpass );
 227+ wfRunHooks( "PrefsPasswordAudit", array( $this->user, $this->mNewpass, 'success' ) );
 228+ $this->mNewpass = $this->mOldpass = $this->mRetypePass = '';
 229+ } catch( PasswordError $e ) {
 230+ wfRunHooks( "PrefsPasswordAudit", array( $this->user, $this->mNewpass, 'error' ) );
 231+ $this->mainPrefsForm( 'error', $e->getMessage() );
 232+ return;
 233+ }
 234+ }
 235+ $this->user->setRealName( $this->mRealName );
 236+
 237+ if( $this->user->getOption( 'language' ) !== $this->mUserLanguage ) {
 238+ $needRedirect = true;
 239+ } else {
 240+ $needRedirect = false;
 241+ }
 242+
 243+ # Validate the signature and clean it up as needed
 244+ global $wgMaxSigChars;
 245+ if( mb_strlen( $this->mNick ) > $wgMaxSigChars ) {
 246+ global $wgLang;
 247+ $this->mainPrefsForm( 'error',
 248+ wfMsg( 'badsiglength', $wgLang->formatNum( $wgMaxSigChars ) ) );
 249+ return;
 250+ } elseif( $this->mToggles['fancysig'] ) {
 251+ if( Parser::validateSig( $this->mNick ) !== false ) {
 252+ $this->mNick = $wgParser->cleanSig( $this->mNick );
 253+ } else {
 254+ $this->mainPrefsForm( 'error', wfMsg( 'badsig' ) );
 255+ return;
 256+ }
 257+ } else {
 258+ // When no fancy sig used, make sure ~{3,5} get removed.
 259+ $this->mNick = $wgParser->cleanSigInSig( $this->mNick );
 260+ }
 261+
 262+ $this->user->setOption( 'language', $this->mUserLanguage );
 263+ $this->user->setOption( 'variant', $this->mUserVariant );
 264+ $this->user->setOption( 'nickname', $this->mNick );
 265+ $this->user->setOption( 'quickbar', $this->mQuickbar );
 266+ $this->user->setOption( 'skin', $this->mSkin );
 267+ global $wgUseTeX;
 268+ if( $wgUseTeX ) {
 269+ $this->user->setOption( 'math', $this->mMath );
 270+ }
 271+ $this->user->setOption( 'date', $this->validateDate( $this->mDate ) );
 272+ $this->user->setOption( 'searchlimit', $this->validateIntOrNull( $this->mSearch ) );
 273+ $this->user->setOption( 'contextlines', $this->validateIntOrNull( $this->mSearchLines ) );
 274+ $this->user->setOption( 'contextchars', $this->validateIntOrNull( $this->mSearchChars ) );
 275+ $this->user->setOption( 'rclimit', $this->validateIntOrNull( $this->mRecent ) );
 276+ $this->user->setOption( 'rcdays', $this->validateInt( $this->mRecentDays, 1, 7 ) );
 277+ $this->user->setOption( 'wllimit', $this->validateIntOrNull( $this->mWatchlistEdits, 0, 1000 ) );
 278+ $this->user->setOption( 'rows', $this->validateInt( $this->mRows, 4, 1000 ) );
 279+ $this->user->setOption( 'cols', $this->validateInt( $this->mCols, 4, 1000 ) );
 280+ $this->user->setOption( 'stubthreshold', $this->validateIntOrNull( $this->mStubs ) );
 281+ $this->user->setOption( 'timecorrection', $this->validateTimeZone( $this->mHourDiff, -12, 14 ) );
 282+ $this->user->setOption( 'imagesize', $this->mImageSize );
 283+ $this->user->setOption( 'thumbsize', $this->mThumbSize );
 284+ $this->user->setOption( 'underline', $this->validateInt($this->mUnderline, 0, 2) );
 285+ $this->user->setOption( 'watchlistdays', $this->validateFloat( $this->mWatchlistDays, 0, 7 ) );
 286+
 287+ # Set search namespace options
 288+ foreach( $this->mSearchNs as $i => $value ) {
 289+ $this->user->setOption( "searchNs{$i}", $value );
 290+ }
 291+
 292+ if( $wgEnableEmail && $wgEnableUserEmail ) {
 293+ $this->user->setOption( 'disablemail', $this->mEmailFlag );
 294+ }
 295+
 296+ # Set user toggles
 297+ foreach ( $this->mToggles as $tname => $tvalue ) {
 298+ $this->user->setOption( $tname, $tvalue );
 299+ }
 300+ if (!$wgAuth->updateExternalDB($this->user)) {
 301+ $this->mainPrefsForm( 'error', wfMsg( 'externaldberror' ) );
 302+ return;
 303+ }
 304+
 305+ $msg = '';
 306+ if ( !wfRunHooks( "SavePreferences", array( $this, $this->user, &$msg ) ) ) {
 307+ print "(($msg))";
 308+ $this->mainPrefsForm( 'error', $msg );
 309+ return;
 310+ }
 311+
 312+ $this->user->saveSettings();
 313+
 314+ $error = false;
 315+ if( $wgEnableEmail ) {
 316+ $newadr = $this->mUserEmail;
 317+ $oldadr = $this->user->getEmail();
 318+ if( ($newadr != '') && ($newadr != $oldadr) ) {
 319+ # the user has supplied a new email address on the login page
 320+ if( $this->user->isValidEmailAddr( $newadr ) ) {
 321+ $this->user->mEmail = $newadr; # new behaviour: set this new emailaddr from login-page into user database record
 322+ $this->user->confirmEmail(); #auto-authenticate it
 323+ } else {
 324+ $error = wfMsg( 'invalidemailaddress' );
 325+ }
 326+ } else {
 327+ $this->user->setEmail( $this->mUserEmail );
 328+ $this->user->setCookies();
 329+ $this->user->saveSettings();
 330+ }
 331+ if( $oldadr != $newadr ) {
 332+ wfRunHooks( "PrefsEmailAudit", array( $this->user, $oldadr, $newadr ) );
 333+ }
 334+ }
 335+
 336+ if( $needRedirect && $error === false ) {
 337+ $title =& SpecialPage::getTitleFor( "EditUser" );
 338+ $wgOut->redirect($title->getFullURL('success'));
 339+ return;
 340+ }
 341+
 342+ $wgOut->setParserOptions( ParserOptions::newFromUser( $this->user ) );
 343+ $this->mainPrefsForm( $error === false ? 'success' : 'error', $error);
 344+ }
 345+
 346+ /**
 347+ * @access private
 348+ */
 349+ function resetPrefs() {
 350+ global $wgUser, $wgLang, $wgContLang, $wgContLanguageCode, $wgAllowRealName;
 351+
 352+ $this->mNewpass = $this->mRetypePass = '';
 353+ $this->mUserEmail = $this->user->getEmail();
 354+ $this->mUserEmailAuthenticationtimestamp = $this->user->getEmailAuthenticationtimestamp();
 355+ $this->mRealName = ($wgAllowRealName) ? $this->user->getRealName() : '';
 356+
 357+ # language value might be blank, default to content language
 358+ $this->mUserLanguage = $this->user->getOption( 'language', $wgContLanguageCode );
 359+
 360+ $this->mUserVariant = $this->user->getOption( 'variant');
 361+ $this->mEmailFlag = $this->user->getOption( 'disablemail' ) == 1 ? 1 : 0;
 362+ $this->mNick = $this->user->getOption( 'nickname' );
 363+
 364+ $this->mQuickbar = $this->user->getOption( 'quickbar' );
 365+ $this->mSkin = Skin::normalizeKey( $this->user->getOption( 'skin' ) );
 366+ $this->mMath = $this->user->getOption( 'math' );
 367+ $this->mDate = $this->user->getDatePreference();
 368+ $this->mRows = $this->user->getOption( 'rows' );
 369+ $this->mCols = $this->user->getOption( 'cols' );
 370+ $this->mStubs = $this->user->getOption( 'stubthreshold' );
 371+ $this->mHourDiff = $this->user->getOption( 'timecorrection' );
 372+ $this->mSearch = $this->user->getOption( 'searchlimit' );
 373+ $this->mSearchLines = $this->user->getOption( 'contextlines' );
 374+ $this->mSearchChars = $this->user->getOption( 'contextchars' );
 375+ $this->mImageSize = $this->user->getOption( 'imagesize' );
 376+ $this->mThumbSize = $this->user->getOption( 'thumbsize' );
 377+ $this->mRecent = $this->user->getOption( 'rclimit' );
 378+ $this->mRecentDays = $this->user->getOption( 'rcdays' );
 379+ $this->mWatchlistEdits = $this->user->getOption( 'wllimit' );
 380+ $this->mUnderline = $this->user->getOption( 'underline' );
 381+ $this->mWatchlistDays = $this->user->getOption( 'watchlistdays' );
 382+
 383+ $togs = User::getToggles();
 384+ foreach ( $togs as $tname ) {
 385+ $this->mToggles[$tname] = $this->user->getOption( $tname );
 386+ }
 387+
 388+ $namespaces = $wgContLang->getNamespaces();
 389+ foreach ( $namespaces as $i => $namespace ) {
 390+ if ( $i >= NS_MAIN ) {
 391+ $this->mSearchNs[$i] = $this->user->getOption( 'searchNs'.$i );
 392+ }
 393+ }
 394+
 395+ wfRunHooks( "ResetPreferences", array( $this, $this->user ) );
 396+ }
 397+
 398+ /**
 399+ * @access private
 400+ */
 401+ function namespacesCheckboxes() {
 402+ global $wgContLang;
 403+
 404+ # Determine namespace checkboxes
 405+ $namespaces = $wgContLang->getNamespaces();
 406+ $r1 = null;
 407+
 408+ foreach ( $namespaces as $i => $name ) {
 409+ if ($i < 0)
 410+ continue;
 411+ $checked = $this->mSearchNs[$i] ? "checked='checked'" : '';
 412+ $name = str_replace( '_', ' ', $namespaces[$i] );
 413+
 414+ if ( empty($name) )
 415+ $name = wfMsg( 'blanknamespace' );
 416+
 417+ $r1 .= "<input type='checkbox' value='1' name='wpNs$i' id='wpNs$i' {$checked}/> <label for='wpNs$i'>{$name}</label><br />\n";
 418+ }
 419+ return $r1;
 420+ }
 421+
 422+
 423+ function getToggle( $tname, $trailer = false, $disabled = false ) {
 424+ global $wgUser, $wgLang;
 425+
 426+ $this->mUsedToggles[$tname] = true;
 427+ $ttext = $wgLang->getUserToggle( $tname );
 428+
 429+ $checked = $this->user->getOption( $tname ) == 1 ? ' checked="checked"' : '';
 430+ $disabled = $disabled ? ' disabled="disabled"' : '';
 431+ $trailer = $trailer ? $trailer : '';
 432+ return "<div class='toggle'><input type='checkbox' value='1' id=\"$tname\" name=\"wpOp$tname\"$checked$disabled />" .
 433+ " <span class='toggletext'><label for=\"$tname\">$ttext</label>$trailer</span></div>\n";
 434+ }
 435+
 436+ function getToggles( $items ) {
 437+ $out = "";
 438+ foreach( $items as $item ) {
 439+ if( $item === false )
 440+ continue;
 441+ if( is_array( $item ) ) {
 442+ list( $key, $trailer ) = $item;
 443+ } else {
 444+ $key = $item;
 445+ $trailer = false;
 446+ }
 447+ $out .= $this->getToggle( $key, $trailer );
 448+ }
 449+ return $out;
 450+ }
 451+
 452+ function addRow($td1, $td2) {
 453+ return "<tr><td align='right'>$td1</td><td align='left'>$td2</td></tr>";
 454+ }
 455+
 456+ /**
 457+ * Helper function for user information panel
 458+ * @param $td1 label for an item
 459+ * @param $td2 item or null
 460+ * @param $td3 optional help or null
 461+ * @return xhtml block
 462+ */
 463+ function tableRow( $td1, $td2 = null, $td3 = null ) {
 464+ global $wgContLang;
 465+
 466+ $align['align'] = $wgContLang->isRtl() ? 'right' : 'left';
 467+
 468+ if ( is_null( $td3 ) ) {
 469+ $td3 = '';
 470+ } else {
 471+ $td3 = Xml::tags( 'tr', null,
 472+ Xml::tags( 'td', array( 'colspan' => '2' ), $td3 )
 473+ );
 474+ }
 475+
 476+ if ( is_null( $td2 ) ) {
 477+ $td1 = Xml::tags( 'td', $align + array( 'colspan' => '2' ), $td1 );
 478+ $td2 = '';
 479+ } else {
 480+ $td1 = Xml::tags( 'td', $align, $td1 );
 481+ $td2 = Xml::tags( 'td', $align, $td2 );
 482+ }
 483+
 484+ return Xml::tags( 'tr', null, $td1 . $td2 ). $td3 . "\n";
 485+
 486+ }
 487+
 488+ /**
 489+ * @access private
 490+ */
 491+ function mainPrefsForm( $status , $message = '' ) {
 492+ global $wgUser, $wgOut, $wgLang, $wgContLang;
 493+ global $wgAllowRealName, $wgImageLimits, $wgThumbLimits;
 494+ global $wgDisableLangConversion;
 495+ global $wgEnotifWatchlist, $wgEnotifUserTalk,$wgEnotifMinorEdits;
 496+ global $wgRCShowWatchingUsers, $wgEnotifRevealEditorAddress;
 497+ global $wgEnableEmail, $wgEnableUserEmail, $wgEmailAuthentication;
 498+ global $wgContLanguageCode, $wgDefaultSkin, $wgSkipSkins, $wgAuth;
 499+
 500+ $wgOut->disallowUserJs(); # Prevent hijacked user scripts from sniffing passwords etc.
 501+
 502+ if ( $this->mSuccess || 'success' == $status ) {
 503+ $wgOut->addWikitext( '<div class="successbox"><strong>'. wfMsg( 'savedprefs' ) . '</strong></div>' );
 504+ } else if ( 'error' == $status ) {
 505+ $wgOut->addWikitext( '<div class="errorbox"><strong>' . $message . '</strong></div>' );
 506+ } else if ( '' != $status ) {
 507+ $wgOut->addWikitext( $message . "\n----" );
 508+ }
 509+
 510+ $qbs = $wgLang->getQuickbarSettings();
 511+ $skinNames = $wgLang->getSkinNames();
 512+ $mathopts = $wgLang->getMathNames();
 513+ $dateopts = $wgLang->getDatePreferences();
 514+ $togs = User::getToggles();
 515+
 516+ $titleObj = SpecialPage::getTitleFor( 'EditUser' );
 517+ $action = $titleObj->escapeLocalURL();
 518+
 519+ # Pre-expire some toggles so they won't show if disabled
 520+ $this->mUsedToggles[ 'shownumberswatching' ] = true;
 521+ $this->mUsedToggles[ 'showupdated' ] = true;
 522+ $this->mUsedToggles[ 'enotifwatchlistpages' ] = true;
 523+ $this->mUsedToggles[ 'enotifusertalkpages' ] = true;
 524+ $this->mUsedToggles[ 'enotifminoredits' ] = true;
 525+ $this->mUsedToggles[ 'enotifrevealaddr' ] = true;
 526+ $this->mUsedToggles[ 'ccmeonemails' ] = true;
 527+ $this->mUsedToggles[ 'uselivepreview' ] = true;
 528+
 529+
 530+ if ( !$this->mEmailFlag ) { $emfc = 'checked="checked"'; }
 531+ else { $emfc = ''; }
 532+
 533+
 534+ if ($wgEmailAuthentication && ($this->mUserEmail != '') ) {
 535+ if( $this->user->getEmailAuthenticationTimestamp() ) {
 536+ $emailauthenticated = wfMsg('emailauthenticated',$wgLang->timeanddate($this->user->getEmailAuthenticationTimestamp(), true ) ).'<br />';
 537+ $disableEmailPrefs = false;
 538+ } else {
 539+ $disableEmailPrefs = true;
 540+ $skin = $this->user->getSkin();
 541+ $emailauthenticated = wfMsg('emailnotauthenticated').'<br />' .
 542+ $skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Confirmemail' ),
 543+ wfMsg( 'emailconfirmlink' ) ) . '<br />';
 544+ }
 545+ } else {
 546+ $emailauthenticated = '';
 547+ $disableEmailPrefs = false;
 548+ }
 549+
 550+ if ($this->mUserEmail == '') {
 551+ $emailauthenticated = wfMsg( 'noemailprefs' ) . '<br />';
 552+ }
 553+
 554+ $ps = $this->namespacesCheckboxes();
 555+
 556+ $enotifwatchlistpages = ($wgEnotifWatchlist) ? $this->getToggle( 'enotifwatchlistpages', false, $disableEmailPrefs ) : '';
 557+ $enotifusertalkpages = ($wgEnotifUserTalk) ? $this->getToggle( 'enotifusertalkpages', false, $disableEmailPrefs ) : '';
 558+ $enotifminoredits = ($wgEnotifWatchlist && $wgEnotifMinorEdits) ? $this->getToggle( 'enotifminoredits', false, $disableEmailPrefs ) : '';
 559+ $enotifrevealaddr = (($wgEnotifWatchlist || $wgEnotifUserTalk) && $wgEnotifRevealEditorAddress) ? $this->getToggle( 'enotifrevealaddr', false, $disableEmailPrefs ) : '';
 560+
 561+ # </FIXME>
 562+
 563+ $wgOut->addHTML( "<form action=\"$action\" method='post'>" );
 564+ $wgOut->addHTML( "<div id='preferences'>" );
 565+
 566+ # User data
 567+
 568+ $wgOut->addHTML(
 569+ Xml::openElement( 'fieldset ' ) .
 570+ Xml::element( 'legend', null, wfMsg('prefs-personal') ) .
 571+ Xml::openElement( 'table' ) .
 572+ $this->tableRow( Xml::element( 'h2', null, wfMsg( 'prefs-personal' ) ) )
 573+ );
 574+
 575+ $userInformationHtml =
 576+ $this->tableRow( wfMsgHtml( 'username' ), htmlspecialchars( $this->user->getName() ) ) .
 577+ $this->tableRow( wfMsgHtml( 'uid' ), htmlspecialchars( $this->user->getID() ) ) .
 578+ $this->tableRow(
 579+ wfMsgHtml( 'prefs-edits' ),
 580+ $wgLang->formatNum( User::edits( $this->user->getId() ) )
 581+ );
 582+
 583+ if( wfRunHooks( 'PreferencesUserInformationPanel', array( $this, &$userInformationHtml ) ) ) {
 584+ $wgOut->addHtml( $userInformationHtml );
 585+ }
 586+
 587+ if ( $wgAllowRealName ) {
 588+ $wgOut->addHTML(
 589+ $this->tableRow(
 590+ Xml::label( wfMsg('yourrealname'), 'wpRealName' ),
 591+ Xml::input( 'wpRealName', 25, $this->mRealName, array( 'id' => 'wpRealName' ) ),
 592+ Xml::tags('div', array( 'class' => 'prefsectiontip' ),
 593+ wfMsgExt( 'prefs-help-realname', 'parseinline' )
 594+ )
 595+ )
 596+ );
 597+ }
 598+ if ( $wgEnableEmail ) {
 599+ $wgOut->addHTML(
 600+ $this->tableRow(
 601+ Xml::label( wfMsg('youremail'), 'wpUserEmail' ),
 602+ Xml::input( 'wpUserEmail', 25, $this->mUserEmail, array( 'id' => 'wpUserEmail' ) ),
 603+ Xml::tags('div', array( 'class' => 'prefsectiontip' ),
 604+ wfMsgExt( 'prefs-help-email', 'parseinline' )
 605+ )
 606+ )
 607+ );
 608+ }
 609+
 610+ global $wgParser, $wgMaxSigChars;
 611+ if( mb_strlen( $this->mNick ) > $wgMaxSigChars ) {
 612+ $invalidSig = $this->tableRow(
 613+ '&nbsp;',
 614+ Xml::element( 'span', array( 'class' => 'error' ),
 615+ wfMsg( 'badsiglength', $wgLang->formatNum( $wgMaxSigChars ) ) )
 616+ );
 617+ } elseif( !empty( $this->mToggles['fancysig'] ) &&
 618+ false === $wgParser->validateSig( $this->mNick ) ) {
 619+ $invalidSig = $this->tableRow(
 620+ '&nbsp;',
 621+ Xml::element( 'span', array( 'class' => 'error' ), wfMsg( 'badsig' ) )
 622+ );
 623+ } else {
 624+ $invalidSig = '';
 625+ }
 626+
 627+ $wgOut->addHTML(
 628+ $this->tableRow(
 629+ Xml::label( wfMsg( 'yournick' ), 'wpNick' ),
 630+ Xml::input( 'wpNick', 25, $this->mNick,
 631+ array(
 632+ 'id' => 'wpNick',
 633+ // Note: $wgMaxSigChars is enforced in Unicode characters,
 634+ // both on the backend and now in the browser.
 635+ // Badly-behaved requests may still try to submit
 636+ // an overlong string, however.
 637+ 'maxlength' => $wgMaxSigChars ) )
 638+ ) .
 639+ $invalidSig .
 640+ $this->tableRow( '&nbsp;', $this->getToggle( 'fancysig' ) )
 641+ );
 642+
 643+ list( $lsLabel, $lsSelect) = Xml::languageSelector( $this->mUserLanguage );
 644+ $wgOut->addHTML(
 645+ $this->tableRow( $lsLabel, $lsSelect )
 646+ );
 647+
 648+ /* see if there are multiple language variants to choose from*/
 649+ if(!$wgDisableLangConversion) {
 650+ $variants = $wgContLang->getVariants();
 651+ $variantArray = array();
 652+
 653+ $languages = Language::getLanguageNames( true );
 654+ foreach($variants as $v) {
 655+ $v = str_replace( '_', '-', strtolower($v));
 656+ if( array_key_exists( $v, $languages ) ) {
 657+ // If it doesn't have a name, we'll pretend it doesn't exist
 658+ $variantArray[$v] = $languages[$v];
 659+ }
 660+ }
 661+
 662+ $options = "\n";
 663+ foreach( $variantArray as $code => $name ) {
 664+ $selected = ($code == $this->mUserVariant);
 665+ $options .= Xml::option( "$code - $name", $code, $selected ) . "\n";
 666+ }
 667+
 668+ if(count($variantArray) > 1) {
 669+ $wgOut->addHtml(
 670+ $this->tableRow(
 671+ Xml::label( wfMsg( 'yourvariant' ), 'wpUserVariant' ),
 672+ Xml::tags( 'select',
 673+ array( 'name' => 'wpUserVariant', 'id' => 'wpUserVariant' ),
 674+ $options
 675+ )
 676+ )
 677+ );
 678+ }
 679+ }
 680+
 681+ # Password
 682+ if( $wgAuth->allowPasswordChange() ) {
 683+ $wgOut->addHTML(
 684+ $this->tableRow( Xml::element( 'h2', null, wfMsg( 'changepassword' ) ) ) .
 685+ $this->tableRow(
 686+ Xml::label( wfMsg( 'newpassword' ), 'wpNewpass' ),
 687+ Xml::password( 'wpNewpass', 25, $this->mNewpass, array( 'id' => 'wpNewpass' ) )
 688+ ) .
 689+ $this->tableRow(
 690+ Xml::label( wfMsg( 'retypenew' ), 'wpRetypePass' ),
 691+ Xml::password( 'wpRetypePass', 25, $this->mRetypePass, array( 'id' => 'wpRetypePass' ) )
 692+ ) .
 693+ Xml::tags( 'tr', null,
 694+ Xml::tags( 'td', array( 'colspan' => '2' ),
 695+ $this->getToggle( "rememberpassword" )
 696+ )
 697+ )
 698+ );
 699+ }
 700+
 701+ # <FIXME>
 702+ # Enotif
 703+ if ( $wgEnableEmail ) {
 704+
 705+ $moreEmail = '';
 706+ if ($wgEnableUserEmail) {
 707+ $emf = wfMsg( 'allowemail' );
 708+ $disabled = $disableEmailPrefs ? ' disabled="disabled"' : '';
 709+ $moreEmail =
 710+ "<input type='checkbox' $emfc $disabled value='1' name='wpEmailFlag' id='wpEmailFlag' /> <label for='wpEmailFlag'>$emf</label>";
 711+ }
 712+
 713+
 714+ $wgOut->addHTML(
 715+ $this->tableRow( Xml::element( 'h2', null, wfMsg( 'email' ) ) ) .
 716+ $this->tableRow(
 717+ $emailauthenticated.
 718+ $enotifrevealaddr.
 719+ $enotifwatchlistpages.
 720+ $enotifusertalkpages.
 721+ $enotifminoredits.
 722+ $moreEmail.
 723+ $this->getToggle( 'ccmeonemails' )
 724+ )
 725+ );
 726+ }
 727+ # </FIXME>
 728+
 729+ $wgOut->addHTML(
 730+ Xml::closeElement( 'table' ) .
 731+ Xml::closeElement( 'fieldset' )
 732+ );
 733+
 734+
 735+ # Quickbar
 736+ #
 737+ if ($this->mSkin == 'cologneblue' || $this->mSkin == 'standard') {
 738+ $wgOut->addHtml( "<fieldset>\n<legend>" . wfMsg( 'qbsettings' ) . "</legend>\n" );
 739+ for ( $i = 0; $i < count( $qbs ); ++$i ) {
 740+ if ( $i == $this->mQuickbar ) { $checked = ' checked="checked"'; }
 741+ else { $checked = ""; }
 742+ $wgOut->addHTML( "<div><label><input type='radio' name='wpQuickbar' value=\"$i\"$checked />{$qbs[$i]}</label></div>\n" );
 743+ }
 744+ $wgOut->addHtml( "</fieldset>\n\n" );
 745+ } else {
 746+ # Need to output a hidden option even if the relevant skin is not in use,
 747+ # otherwise the preference will get reset to 0 on submit
 748+ $wgOut->addHtml( wfHidden( 'wpQuickbar', $this->mQuickbar ) );
 749+ }
 750+
 751+ # Skin
 752+ #
 753+ $wgOut->addHTML( "<fieldset>\n<legend>\n" . wfMsg('skin') . "</legend>\n" );
 754+ $mptitle = Title::newMainPage();
 755+ $previewtext = wfMsg('skinpreview');
 756+ # Only show members of Skin::getSkinNames() rather than
 757+ # $skinNames (skins is all skin names from Language.php)
 758+ $validSkinNames = Skin::getSkinNames();
 759+ # Sort by UI skin name. First though need to update validSkinNames as sometimes
 760+ # the skinkey & UI skinname differ (e.g. "standard" skinkey is "Classic" in the UI).
 761+ foreach ($validSkinNames as $skinkey => & $skinname ) {
 762+ if ( isset( $skinNames[$skinkey] ) ) {
 763+ $skinname = $skinNames[$skinkey];
 764+ }
 765+ }
 766+ asort($validSkinNames);
 767+ foreach ($validSkinNames as $skinkey => $sn ) {
 768+ if ( in_array( $skinkey, $wgSkipSkins ) ) {
 769+ continue;
 770+ }
 771+ $checked = $skinkey == $this->mSkin ? ' checked="checked"' : '';
 772+
 773+ $mplink = htmlspecialchars($mptitle->getLocalURL("useskin=$skinkey"));
 774+ $previewlink = "<a target='_blank' href=\"$mplink\">$previewtext</a>";
 775+ if( $skinkey == $wgDefaultSkin )
 776+ $sn .= ' (' . wfMsg( 'default' ) . ')';
 777+ $wgOut->addHTML( "<input type='radio' name='wpSkin' id=\"wpSkin$skinkey\" value=\"$skinkey\"$checked /> <label for=\"wpSkin$skinkey\">{$sn}</label> $previewlink<br />\n" );
 778+ }
 779+ $wgOut->addHTML( "</fieldset>\n\n" );
 780+
 781+ # Math
 782+ #
 783+ global $wgUseTeX;
 784+ if( $wgUseTeX ) {
 785+ $wgOut->addHTML( "<fieldset>\n<legend>" . wfMsg('math') . '</legend>' );
 786+ foreach ( $mathopts as $k => $v ) {
 787+ $checked = ($k == $this->mMath);
 788+ $wgOut->addHTML(
 789+ Xml::openElement( 'div' ) .
 790+ Xml::radioLabel( wfMsg( $v ), 'wpMath', $k, "mw-sp-math-$k", $checked ) .
 791+ Xml::closeElement( 'div' ) . "\n"
 792+ );
 793+ }
 794+ $wgOut->addHTML( "</fieldset>\n\n" );
 795+ }
 796+
 797+ # Files
 798+ #
 799+ $wgOut->addHTML(
 800+ "<fieldset>\n" . Xml::element( 'legend', null, wfMsg( 'files' ) ) . "\n"
 801+ );
 802+
 803+ $imageLimitOptions = null;
 804+ foreach ( $wgImageLimits as $index => $limits ) {
 805+ $selected = ($index == $this->mImageSize);
 806+ $imageLimitOptions .= Xml::option( "{$limits[0]}×{$limits[1]}" .
 807+ wfMsg('unit-pixel'), $index, $selected );
 808+ }
 809+
 810+ $imageSizeId = 'wpImageSize';
 811+ $wgOut->addHTML(
 812+ "<div>" . Xml::label( wfMsg('imagemaxsize'), $imageSizeId ) . " " .
 813+ Xml::openElement( 'select', array( 'name' => $imageSizeId, 'id' => $imageSizeId ) ) .
 814+ $imageLimitOptions .
 815+ Xml::closeElement( 'select' ) . "</div>\n"
 816+ );
 817+
 818+ $imageThumbOptions = null;
 819+ foreach ( $wgThumbLimits as $index => $size ) {
 820+ $selected = ($index == $this->mThumbSize);
 821+ $imageThumbOptions .= Xml::option($size . wfMsg('unit-pixel'), $index,
 822+ $selected);
 823+ }
 824+
 825+ $thumbSizeId = 'wpThumbSize';
 826+ $wgOut->addHTML(
 827+ "<div>" . Xml::label( wfMsg('thumbsize'), $thumbSizeId ) . " " .
 828+ Xml::openElement( 'select', array( 'name' => $thumbSizeId, 'id' => $thumbSizeId ) ) .
 829+ $imageThumbOptions .
 830+ Xml::closeElement( 'select' ) . "</div>\n"
 831+ );
 832+
 833+ $wgOut->addHTML( "</fieldset>\n\n" );
 834+
 835+ # Date format
 836+ #
 837+ # Date/Time
 838+ #
 839+
 840+ $wgOut->addHTML( "<fieldset>\n<legend>" . wfMsg( 'datetime' ) . "</legend>\n" );
 841+
 842+ if ($dateopts) {
 843+ $wgOut->addHTML( "<fieldset>\n<legend>" . wfMsg( 'dateformat' ) . "</legend>\n" );
 844+ $idCnt = 0;
 845+ $epoch = '20010115161234'; # Wikipedia day
 846+ foreach( $dateopts as $key ) {
 847+ if( $key == 'default' ) {
 848+ $formatted = wfMsgHtml( 'datedefault' );
 849+ } else {
 850+ $formatted = htmlspecialchars( $wgLang->timeanddate( $epoch, false, $key ) );
 851+ }
 852+ ($key == $this->mDate) ? $checked = ' checked="checked"' : $checked = '';
 853+ $wgOut->addHTML( "<div><input type='radio' name=\"wpDate\" id=\"wpDate$idCnt\" ".
 854+ "value=\"$key\"$checked /> <label for=\"wpDate$idCnt\">$formatted</label></div>\n" );
 855+ $idCnt++;
 856+ }
 857+ $wgOut->addHTML( "</fieldset>\n" );
 858+ }
 859+
 860+ $nowlocal = $wgLang->time( $now = wfTimestampNow(), true );
 861+ $nowserver = $wgLang->time( $now, false );
 862+
 863+ $wgOut->addHTML( '<fieldset><legend>' . wfMsg( 'timezonelegend' ). '</legend><table>' .
 864+ $this->addRow( wfMsg( 'servertime' ), $nowserver ) .
 865+ $this->addRow( wfMsg( 'localtime' ), $nowlocal ) .
 866+ $this->addRow(
 867+ '<label for="wpHourDiff">' . wfMsg( 'timezoneoffset' ) . '</label>',
 868+ "<input type='text' name='wpHourDiff' id='wpHourDiff' value=\"" . htmlspecialchars( $this->mHourDiff ) . "\" size='6' />"
 869+ ) . "<tr><td colspan='2'>
 870+ <input type='button' value=\"" . wfMsg( 'guesstimezone' ) ."\"
 871+ onclick='javascript:guessTimezone()' id='guesstimezonebutton' style='display:none;' />
 872+ </td></tr></table><div class='prefsectiontip'>¹" . wfMsg( 'timezonetext' ) . "</div></fieldset>
 873+ </fieldset>\n\n" );
 874+
 875+ # Editing
 876+ #
 877+ global $wgLivePreview;
 878+ $wgOut->addHTML( '<fieldset><legend>' . wfMsg( 'textboxsize' ) . '</legend>
 879+ <div>' .
 880+ wfInputLabel( wfMsg( 'rows' ), 'wpRows', 'wpRows', 3, $this->mRows ) .
 881+ ' ' .
 882+ wfInputLabel( wfMsg( 'columns' ), 'wpCols', 'wpCols', 3, $this->mCols ) .
 883+ "</div>" .
 884+ $this->getToggles( array(
 885+ 'editsection',
 886+ 'editsectiononrightclick',
 887+ 'editondblclick',
 888+ 'editwidth',
 889+ 'showtoolbar',
 890+ 'previewonfirst',
 891+ 'previewontop',
 892+ 'minordefault',
 893+ 'externaleditor',
 894+ 'externaldiff',
 895+ $wgLivePreview ? 'uselivepreview' : false,
 896+ 'forceeditsummary',
 897+ ) ) . '</fieldset>'
 898+ );
 899+
 900+ # Recent changes
 901+ $wgOut->addHtml( '<fieldset><legend>' . wfMsgHtml( 'prefs-rc' ) . '</legend>' );
 902+
 903+ $rc = '<table><tr>';
 904+ $rc .= '<td>' . Xml::label( wfMsg( 'recentchangesdays' ), 'wpRecentDays' ) . '</td>';
 905+ $rc .= '<td>' . Xml::input( 'wpRecentDays', 3, $this->mRecentDays, array( 'id' => 'wpRecentDays' ) ) . '</td>';
 906+ $rc .= '</tr><tr>';
 907+ $rc .= '<td>' . Xml::label( wfMsg( 'recentchangescount' ), 'wpRecent' ) . '</td>';
 908+ $rc .= '<td>' . Xml::input( 'wpRecent', 3, $this->mRecent, array( 'id' => 'wpRecent' ) ) . '</td>';
 909+ $rc .= '</tr></table>';
 910+ $wgOut->addHtml( $rc );
 911+
 912+ $wgOut->addHtml( '<br />' );
 913+
 914+ $toggles[] = 'hideminor';
 915+ if( $wgRCShowWatchingUsers )
 916+ $toggles[] = 'shownumberswatching';
 917+ $toggles[] = 'usenewrc';
 918+ $wgOut->addHtml( $this->getToggles( $toggles ) );
 919+
 920+ $wgOut->addHtml( '</fieldset>' );
 921+
 922+ # Watchlist
 923+ $wgOut->addHtml( '<fieldset><legend>' . wfMsgHtml( 'prefs-watchlist' ) . '</legend>' );
 924+
 925+ $wgOut->addHtml( wfInputLabel( wfMsg( 'prefs-watchlist-days' ), 'wpWatchlistDays', 'wpWatchlistDays', 3, $this->mWatchlistDays ) );
 926+ $wgOut->addHtml( '<br /><br />' );
 927+
 928+ $wgOut->addHtml( $this->getToggle( 'extendwatchlist' ) );
 929+ $wgOut->addHtml( wfInputLabel( wfMsg( 'prefs-watchlist-edits' ), 'wpWatchlistEdits', 'wpWatchlistEdits', 3, $this->mWatchlistEdits ) );
 930+ $wgOut->addHtml( '<br /><br />' );
 931+
 932+ $wgOut->addHtml( $this->getToggles( array( 'watchlisthideown', 'watchlisthidebots', 'watchlisthideminor' ) ) );
 933+
 934+ if( $this->user->isAllowed( 'createpage' ) || $this->user->isAllowed( 'createtalk' ) )
 935+ $wgOut->addHtml( $this->getToggle( 'watchcreations' ) );
 936+ foreach( array( 'edit' => 'watchdefault', 'move' => 'watchmoves', 'delete' => 'watchdeletion' ) as $action => $toggle ) {
 937+ if( $this->user->isAllowed( $action ) )
 938+ $wgOut->addHtml( $this->getToggle( $toggle ) );
 939+ }
 940+ $this->mUsedToggles['watchcreations'] = true;
 941+ $this->mUsedToggles['watchdefault'] = true;
 942+ $this->mUsedToggles['watchmoves'] = true;
 943+ $this->mUsedToggles['watchdeletion'] = true;
 944+
 945+ $wgOut->addHtml( '</fieldset>' );
 946+
 947+ # Search
 948+ $wgOut->addHTML( '<fieldset><legend>' . wfMsg( 'searchresultshead' ) . '</legend><table>' .
 949+ $this->addRow(
 950+ wfLabel( wfMsg( 'resultsperpage' ), 'wpSearch' ),
 951+ wfInput( 'wpSearch', 4, $this->mSearch, array( 'id' => 'wpSearch' ) )
 952+ ) .
 953+ $this->addRow(
 954+ wfLabel( wfMsg( 'contextlines' ), 'wpSearchLines' ),
 955+ wfInput( 'wpSearchLines', 4, $this->mSearchLines, array( 'id' => 'wpSearchLines' ) )
 956+ ) .
 957+ $this->addRow(
 958+ wfLabel( wfMsg( 'contextchars' ), 'wpSearchChars' ),
 959+ wfInput( 'wpSearchChars', 4, $this->mSearchChars, array( 'id' => 'wpSearchChars' ) )
 960+ ) .
 961+ "</table><fieldset><legend>" . wfMsg( 'defaultns' ) . "</legend>$ps</fieldset></fieldset>" );
 962+
 963+ # Misc
 964+ #
 965+ $wgOut->addHTML('<fieldset><legend>' . wfMsg('prefs-misc') . '</legend>');
 966+ $wgOut->addHtml( '<label for="wpStubs">' . wfMsg( 'stub-threshold' ) . '</label>&nbsp;' );
 967+ $wgOut->addHtml( Xml::input( 'wpStubs', 6, $this->mStubs, array( 'id' => 'wpStubs' ) ) );
 968+ $msgUnderline = htmlspecialchars( wfMsg ( 'tog-underline' ) );
 969+ $msgUnderlinenever = htmlspecialchars( wfMsg ( 'underline-never' ) );
 970+ $msgUnderlinealways = htmlspecialchars( wfMsg ( 'underline-always' ) );
 971+ $msgUnderlinedefault = htmlspecialchars( wfMsg ( 'underline-default' ) );
 972+ $uopt = $this->user->getOption("underline");
 973+ $s0 = $uopt == 0 ? ' selected="selected"' : '';
 974+ $s1 = $uopt == 1 ? ' selected="selected"' : '';
 975+ $s2 = $uopt == 2 ? ' selected="selected"' : '';
 976+ $wgOut->addHTML("
 977+<div class='toggle'><p><label for='wpOpunderline'>$msgUnderline</label>
 978+<select name='wpOpunderline' id='wpOpunderline'>
 979+<option value=\"0\"$s0>$msgUnderlinenever</option>
 980+<option value=\"1\"$s1>$msgUnderlinealways</option>
 981+<option value=\"2\"$s2>$msgUnderlinedefault</option>
 982+</select></p></div>");
 983+
 984+ foreach ( $togs as $tname ) {
 985+ if( !array_key_exists( $tname, $this->mUsedToggles ) ) {
 986+ $wgOut->addHTML( $this->getToggle( $tname ) );
 987+ }
 988+ }
 989+ $wgOut->addHTML( '</fieldset>' );
 990+
 991+ wfRunHooks( "RenderPreferencesForm", array( $this, $wgOut ) );
 992+
 993+ $token = htmlspecialchars( $this->user->editToken() );
 994+ $skin = $this->user->getSkin();
 995+ $wgOut->addHTML( "
 996+ <div id='prefsubmit'>
 997+ <div>
 998+ <input type='submit' name='wpSaveprefs' class='btnSavePrefs' value=\"" . wfMsgHtml( 'saveprefs' ) . '"'.$skin->tooltipAndAccesskey('save')." />
 999+ <input type='submit' name='wpReset' value=\"" . wfMsgHtml( 'resetprefs' ) . "\" />
 1000+ </div>
 1001+
 1002+ </div>
 1003+
 1004+ <input type='hidden' name='wpEditToken' value=\"{$token}\" />
 1005+ </div></form>\n" );
 1006+
 1007+ $wgOut->addHtml( Xml::tags( 'div', array( 'class' => "prefcache" ),
 1008+ wfMsgExt( 'clearyourcache', 'parseinline' ) )
 1009+ );
 1010+
 1011+ }
 1012+
 1013+ function makeSearchForm() {
 1014+ $thisTitle = Title::makeTitle( NS_SPECIAL, $this->getName() );
 1015+ $form = wfOpenElement( 'form', array( 'method' => 'post', 'action' => $thisTitle->getLocalUrl() ) );
 1016+ $form .= wfElement( 'label', array( 'for' => 'username' ), wfMsg( 'edituser-username' ) ) . ' ';
 1017+ $form .= wfElement( 'input', array( 'type' => 'text', 'name' => 'username', 'id' => 'username', 'value' => $this->target ) ) . ' ';
 1018+ $form .= wfElement( 'input', array( 'type' => 'submit', 'name' => 'dosearch', 'value' => wfMsg( 'edituser-dosearch' ) ) );
 1019+ $form .= wfElement( 'input', array( 'type' => 'hidden', 'name' => 'issearch', 'value' => '1' ) );
 1020+ $form .= wfCloseElement( 'form' );
 1021+ return $form;
 1022+ }
 1023+}
 1024+
Property changes on: trunk/extensions/EditUser/1.11/EditUser_body.php
___________________________________________________________________
Added: svn:eol-style
11025 + native
Index: trunk/extensions/EditUser/1.12/EditUser_body.php
@@ -0,0 +1,1037 @@
 2+<?php
 3+/* Shamelessly copied and modified from /includes/specials/SpecialPreferences.php v1.12 */
 4+class EditUser extends SpecialPage {
 5+ var $mQuickbar, $mNewpass, $mRetypePass, $mStubs;
 6+ var $mRows, $mCols, $mSkin, $mMath, $mDate, $mUserEmail, $mEmailFlag, $mNick;
 7+ var $mUserLanguage, $mUserVariant;
 8+ var $mSearch, $mRecent, $mRecentDays, $mHourDiff, $mSearchLines, $mSearchChars, $mAction;
 9+ var $mReset, $mPosted, $mToggles, $mUseAjaxSearch, $mSearchNs, $mRealName, $mImageSize;
 10+ var $mUnderline, $mWatchlistEdits;
 11+ var $user, $target;
 12+
 13+ function __construct() {
 14+ SpecialPage::SpecialPage('EditUser', 'edituser');
 15+ }
 16+ /**
 17+ * Constructor
 18+ * Load some values
 19+ */
 20+ function loadGlobals( $par ) {
 21+ global $wgContLang, $wgUser, $wgAllowRealName, $wgRequest;
 22+ $request = $wgRequest;
 23+ $this->user = User::newFromName($par);
 24+ $this->user->load();
 25+ $this->mQuickbar = $request->getVal( 'wpQuickbar' );
 26+ $this->mNewpass = $request->getVal( 'wpNewpass' );
 27+ $this->mRetypePass =$request->getVal( 'wpRetypePass' );
 28+ $this->mStubs = $request->getVal( 'wpStubs' );
 29+ $this->mRows = $request->getVal( 'wpRows' );
 30+ $this->mCols = $request->getVal( 'wpCols' );
 31+ $this->mSkin = $request->getVal( 'wpSkin' );
 32+ $this->mMath = $request->getVal( 'wpMath' );
 33+ $this->mDate = $request->getVal( 'wpDate' );
 34+ $this->mUserEmail = $request->getVal( 'wpUserEmail' );
 35+ $this->mRealName = $wgAllowRealName ? $request->getVal( 'wpRealName' ) : '';
 36+ $this->mEmailFlag = $request->getCheck( 'wpEmailFlag' ) ? 0 : 1;
 37+ $this->mNick = $request->getVal( 'wpNick' );
 38+ $this->mUserLanguage = $request->getVal( 'wpUserLanguage' );
 39+ $this->mUserVariant = $request->getVal( 'wpUserVariant' );
 40+ $this->mSearch = $request->getVal( 'wpSearch' );
 41+ $this->mRecent = $request->getVal( 'wpRecent' );
 42+ $this->mRecentDays = $request->getVal( 'wpRecentDays' );
 43+ $this->mHourDiff = $request->getVal( 'wpHourDiff' );
 44+ $this->mSearchLines = $request->getVal( 'wpSearchLines' );
 45+ $this->mSearchChars = $request->getVal( 'wpSearchChars' );
 46+ $this->mImageSize = $request->getVal( 'wpImageSize' );
 47+ $this->mThumbSize = $request->getInt( 'wpThumbSize' );
 48+ $this->mUnderline = $request->getInt( 'wpOpunderline' );
 49+ $this->mAction = $request->getVal( 'action' );
 50+ $this->mReset = $request->getCheck( 'wpReset' );
 51+ $this->mPosted = $request->wasPosted();
 52+ $this->mSuccess = $request->getCheck( 'success' );
 53+ $this->mWatchlistDays = $request->getVal( 'wpWatchlistDays' );
 54+ $this->mWatchlistEdits = $request->getVal( 'wpWatchlistEdits' );
 55+ $this->mUseAjaxSearch = $request->getCheck( 'wpUseAjaxSearch' );
 56+ $this->mSaveprefs = $request->getCheck( 'wpSaveprefs' ) &&
 57+ $this->mPosted &&
 58+ $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) );
 59+
 60+ # User toggles (the big ugly unsorted list of checkboxes)
 61+ $this->mToggles = array();
 62+ if ( $this->mPosted ) {
 63+ $togs = User::getToggles();
 64+ foreach ( $togs as $tname ) {
 65+ $this->mToggles[$tname] = $request->getCheck( "wpOp$tname" ) ? 1 : 0;
 66+ }
 67+ }
 68+
 69+ $this->mUsedToggles = array();
 70+
 71+ # Search namespace options
 72+ # Note: namespaces don't necessarily have consecutive keys
 73+ $this->mSearchNs = array();
 74+ if ( $this->mPosted ) {
 75+ $namespaces = $wgContLang->getNamespaces();
 76+ foreach ( $namespaces as $i => $namespace ) {
 77+ if ( $i >= 0 ) {
 78+ $this->mSearchNs[$i] = $request->getCheck( "wpNs$i" ) ? 1 : 0;
 79+ }
 80+ }
 81+ }
 82+
 83+ # Validate language
 84+ if ( !preg_match( '/^[a-z\-]*$/', $this->mUserLanguage ) ) {
 85+ $this->mUserLanguage = 'nolanguage';
 86+ }
 87+
 88+ wfRunHooks( 'InitPreferencesForm', array( $this, $request ) );
 89+ }
 90+
 91+ function execute( $par ) {
 92+ global $wgOut, $wgUser, $wgRequest;
 93+ if( !$wgUser->isAllowed( 'edituser' ) ) {
 94+ $wgOut->permissionRequired( 'edituser' );
 95+ return false;
 96+ }
 97+
 98+ wfLoadExtensionMessages( 'EditUser' );
 99+
 100+ $this->setHeaders();
 101+ $this->target = (isset($par)) ? $par : $wgRequest->getText('username', '');
 102+ if($this->target === '') {
 103+ $wgOut->addHtml($this->makeSearchForm());
 104+ return;
 105+ }
 106+ $targetuser = User::NewFromName( $this->target );
 107+ if( $targetuser->getID() == 0 ) {
 108+ $wgOut->addWikiText( wfMsg( 'edituser-nouser' ) );
 109+ return;
 110+ }
 111+ if( $targetuser->isAllowed('edituser-exempt') ) {
 112+ $wgOut->addWikiText( wfMsg( 'edituser-exempt' ) );
 113+ return;
 114+ }
 115+ $this->loadGlobals($this->target);
 116+ $wgOut->addHtml($this->makeSearchForm());
 117+ $wgOut->addHtml('<br />');
 118+ if ( wfReadOnly() ) {
 119+ $wgOut->readOnlyPage();
 120+ return;
 121+ }
 122+ if ( $this->mReset ) {
 123+ $this->resetPrefs();
 124+ $this->mainPrefsForm( 'reset', wfMsg( 'prefsreset' ) );
 125+ } else if ( $this->mSaveprefs ) {
 126+ $this->savePreferences();
 127+ } else {
 128+ $this->resetPrefs();
 129+ $this->mainPrefsForm( '' );
 130+ }
 131+ }
 132+ /**
 133+ * @access private
 134+ */
 135+ function validateInt( &$val, $min=0, $max=0x7fffffff ) {
 136+ $val = intval($val);
 137+ $val = min($val, $max);
 138+ $val = max($val, $min);
 139+ return $val;
 140+ }
 141+
 142+ /**
 143+ * @access private
 144+ */
 145+ function validateFloat( &$val, $min, $max=0x7fffffff ) {
 146+ $val = floatval( $val );
 147+ $val = min( $val, $max );
 148+ $val = max( $val, $min );
 149+ return( $val );
 150+ }
 151+
 152+ /**
 153+ * @access private
 154+ */
 155+ function validateIntOrNull( &$val, $min=0, $max=0x7fffffff ) {
 156+ $val = trim($val);
 157+ if($val === '') {
 158+ return $val;
 159+ } else {
 160+ return $this->validateInt( $val, $min, $max );
 161+ }
 162+ }
 163+
 164+ /**
 165+ * @access private
 166+ */
 167+ function validateDate( $val ) {
 168+ global $wgLang, $wgContLang;
 169+ if ( $val !== false && (
 170+ in_array( $val, (array)$wgLang->getDatePreferences() ) ||
 171+ in_array( $val, (array)$wgContLang->getDatePreferences() ) ) )
 172+ {
 173+ return $val;
 174+ } else {
 175+ return $wgLang->getDefaultDateFormat();
 176+ }
 177+ }
 178+
 179+ /**
 180+ * Used to validate the user inputed timezone before saving it as
 181+ * 'timecorrection', will return '00:00' if fed bogus data.
 182+ * Note: It's not a 100% correct implementation timezone-wise, it will
 183+ * accept stuff like '14:30',
 184+ * @access private
 185+ * @param string $s the user input
 186+ * @return string
 187+ */
 188+ function validateTimeZone( $s ) {
 189+ if ( $s !== '' ) {
 190+ if ( strpos( $s, ':' ) ) {
 191+ # HH:MM
 192+ $array = explode( ':' , $s );
 193+ $hour = intval( $array[0] );
 194+ $minute = intval( $array[1] );
 195+ } else {
 196+ $minute = intval( $s * 60 );
 197+ $hour = intval( $minute / 60 );
 198+ $minute = abs( $minute ) % 60;
 199+ }
 200+ # Max is +14:00 and min is -12:00, see:
 201+ # http://en.wikipedia.org/wiki/Timezone
 202+ $hour = min( $hour, 14 );
 203+ $hour = max( $hour, -12 );
 204+ $minute = min( $minute, 59 );
 205+ $minute = max( $minute, 0 );
 206+ $s = sprintf( "%02d:%02d", $hour, $minute );
 207+ }
 208+ return $s;
 209+ }
 210+
 211+ /**
 212+ * @access private
 213+ */
 214+ function savePreferences() {
 215+ global $wgUser, $wgOut, $wgParser;
 216+ global $wgEnableUserEmail, $wgEnableEmail;
 217+ global $wgEmailAuthentication, $wgRCMaxAge;
 218+ global $wgAuth, $wgEmailConfirmToEdit;
 219+
 220+
 221+ if ( '' != $this->mNewpass && $wgAuth->allowPasswordChange() ) {
 222+ if ( $this->mNewpass != $this->mRetypePass ) {
 223+ wfRunHooks( 'PrefsPasswordAudit', array( $this->user, $this->mNewpass, 'badretype' ) );
 224+ $this->mainPrefsForm( 'error', wfMsg( 'badretype' ) );
 225+ return;
 226+ }
 227+
 228+ try {
 229+ $this->user->setPassword( $this->mNewpass );
 230+ wfRunHooks( 'PrefsPasswordAudit', array( $this->user, $this->mNewpass, 'success' ) );
 231+ $this->mNewpass = $this->mOldpass = $this->mRetypePass = '';
 232+ } catch( PasswordError $e ) {
 233+ wfRunHooks( 'PrefsPasswordAudit', array( $this->user, $this->mNewpass, 'error' ) );
 234+ $this->mainPrefsForm( 'error', $e->getMessage() );
 235+ return;
 236+ }
 237+ }
 238+ $this->user->setRealName( $this->mRealName );
 239+
 240+ if( $this->user->getOption( 'language' ) !== $this->mUserLanguage ) {
 241+ $needRedirect = true;
 242+ } else {
 243+ $needRedirect = false;
 244+ }
 245+
 246+ # Validate the signature and clean it up as needed
 247+ global $wgMaxSigChars;
 248+ if( mb_strlen( $this->mNick ) > $wgMaxSigChars ) {
 249+ global $wgLang;
 250+ $this->mainPrefsForm( 'error',
 251+ wfMsg( 'badsiglength', $wgLang->formatNum( $wgMaxSigChars ) ) );
 252+ return;
 253+ } elseif( $this->mToggles['fancysig'] ) {
 254+ if( $wgParser->validateSig( $this->mNick ) !== false ) {
 255+ $this->mNick = $wgParser->cleanSig( $this->mNick );
 256+ } else {
 257+ $this->mainPrefsForm( 'error', wfMsg( 'badsig' ) );
 258+ return;
 259+ }
 260+ } else {
 261+ // When no fancy sig used, make sure ~{3,5} get removed.
 262+ $this->mNick = $wgParser->cleanSigInSig( $this->mNick );
 263+ }
 264+
 265+ $this->user->setOption( 'language', $this->mUserLanguage );
 266+ $this->user->setOption( 'variant', $this->mUserVariant );
 267+ $this->user->setOption( 'nickname', $this->mNick );
 268+ $this->user->setOption( 'quickbar', $this->mQuickbar );
 269+ $this->user->setOption( 'skin', $this->mSkin );
 270+ global $wgUseTeX;
 271+ if( $wgUseTeX ) {
 272+ $this->user->setOption( 'math', $this->mMath );
 273+ }
 274+ $this->user->setOption( 'date', $this->validateDate( $this->mDate ) );
 275+ $this->user->setOption( 'searchlimit', $this->validateIntOrNull( $this->mSearch ) );
 276+ $this->user->setOption( 'contextlines', $this->validateIntOrNull( $this->mSearchLines ) );
 277+ $this->user->setOption( 'contextchars', $this->validateIntOrNull( $this->mSearchChars ) );
 278+ $this->user->setOption( 'rclimit', $this->validateIntOrNull( $this->mRecent ) );
 279+ $this->user->setOption( 'rcdays', $this->validateInt($this->mRecentDays, 1, ceil($wgRCMaxAge / (3600*24))));
 280+ $this->user->setOption( 'wllimit', $this->validateIntOrNull( $this->mWatchlistEdits, 0, 1000 ) );
 281+ $this->user->setOption( 'rows', $this->validateInt( $this->mRows, 4, 1000 ) );
 282+ $this->user->setOption( 'cols', $this->validateInt( $this->mCols, 4, 1000 ) );
 283+ $this->user->setOption( 'stubthreshold', $this->validateIntOrNull( $this->mStubs ) );
 284+ $this->user->setOption( 'timecorrection', $this->validateTimeZone( $this->mHourDiff, -12, 14 ) );
 285+ $this->user->setOption( 'imagesize', $this->mImageSize );
 286+ $this->user->setOption( 'thumbsize', $this->mThumbSize );
 287+ $this->user->setOption( 'underline', $this->validateInt($this->mUnderline, 0, 2) );
 288+ $this->user->setOption( 'watchlistdays', $this->validateFloat( $this->mWatchlistDays, 0, 7 ) );
 289+ $this->user->setOption( 'ajaxsearch', $this->mUseAjaxSearch );
 290+
 291+ # Set search namespace options
 292+ foreach( $this->mSearchNs as $i => $value ) {
 293+ $this->user->setOption( "searchNs{$i}", $value );
 294+ }
 295+
 296+ if( $wgEnableEmail && $wgEnableUserEmail ) {
 297+ $this->user->setOption( 'disablemail', $this->mEmailFlag );
 298+ }
 299+
 300+ # Set user toggles
 301+ foreach ( $this->mToggles as $tname => $tvalue ) {
 302+ $this->user->setOption( $tname, $tvalue );
 303+ }
 304+
 305+ $error = false;
 306+ if( $wgEnableEmail ) {
 307+ $newadr = $this->mUserEmail;
 308+ $oldadr = $this->user->getEmail();
 309+ if( ($newadr != '') && ($newadr != $oldadr) ) {
 310+ # the user has supplied a new email address on the login page
 311+ if( $this->user->isValidEmailAddr( $newadr ) ) {
 312+ $this->user->mEmail = $newadr; # new behaviour: set this new emailaddr from login-page into user database record
 313+ $this->user->confirmEmail(); #auto-authenticate it
 314+ } else {
 315+ $error = wfMsg( 'invalidemailaddress' );
 316+ }
 317+ } else {
 318+ if( $wgEmailConfirmToEdit && empty( $newadr ) ) {
 319+ $this->mainPrefsForm( 'error', wfMsg( 'noemailtitle' ) );
 320+ return;
 321+ }
 322+ $this->user->setEmail( $this->mUserEmail );
 323+ }
 324+ if( $oldadr != $newadr ) {
 325+ wfRunHooks( 'PrefsEmailAudit', array( $this->user, $oldadr, $newadr ) );
 326+ }
 327+ }
 328+
 329+ if (!$wgAuth->updateExternalDB($this->user)) {
 330+ $this->mainPrefsForm( 'error', wfMsg( 'externaldberror' ) );
 331+ return;
 332+ }
 333+
 334+ $msg = '';
 335+ if ( !wfRunHooks( 'SavePreferences', array( $this, $this->user, &$msg ) ) ) {
 336+ print "(($msg))";
 337+ $this->mainPrefsForm( 'error', $msg );
 338+ return;
 339+ }
 340+
 341+ $this->user->saveSettings();
 342+
 343+ if( $needRedirect && $error === false ) {
 344+ $title = SpecialPage::getTitleFor( 'EditUser' );
 345+ $wgOut->redirect($title->getFullURL('success'));
 346+ return;
 347+ }
 348+
 349+ $wgOut->setParserOptions( ParserOptions::newFromUser( $this->user ) );
 350+ $this->mainPrefsForm( $error === false ? 'success' : 'error', $error);
 351+ }
 352+
 353+ /**
 354+ * @access private
 355+ */
 356+ function resetPrefs() {
 357+ global $wgUser, $wgLang, $wgContLang, $wgContLanguageCode, $wgAllowRealName;
 358+
 359+ $this->mUserEmail = $this->user->getEmail();
 360+ $this->mUserEmailAuthenticationtimestamp = $this->user->getEmailAuthenticationtimestamp();
 361+ $this->mRealName = ($wgAllowRealName) ? $this->user->getRealName() : '';
 362+
 363+ # language value might be blank, default to content language
 364+ $this->mUserLanguage = $this->user->getOption( 'language', $wgContLanguageCode );
 365+
 366+ $this->mUserVariant = $this->user->getOption( 'variant');
 367+ $this->mEmailFlag = $this->user->getOption( 'disablemail' ) == 1 ? 1 : 0;
 368+ $this->mNick = $this->user->getOption( 'nickname' );
 369+
 370+ $this->mQuickbar = $this->user->getOption( 'quickbar' );
 371+ $this->mSkin = Skin::normalizeKey( $this->user->getOption( 'skin' ) );
 372+ $this->mMath = $this->user->getOption( 'math' );
 373+ $this->mDate = $this->user->getDatePreference();
 374+ $this->mRows = $this->user->getOption( 'rows' );
 375+ $this->mCols = $this->user->getOption( 'cols' );
 376+ $this->mStubs = $this->user->getOption( 'stubthreshold' );
 377+ $this->mHourDiff = $this->user->getOption( 'timecorrection' );
 378+ $this->mSearch = $this->user->getOption( 'searchlimit' );
 379+ $this->mSearchLines = $this->user->getOption( 'contextlines' );
 380+ $this->mSearchChars = $this->user->getOption( 'contextchars' );
 381+ $this->mImageSize = $this->user->getOption( 'imagesize' );
 382+ $this->mThumbSize = $this->user->getOption( 'thumbsize' );
 383+ $this->mRecent = $this->user->getOption( 'rclimit' );
 384+ $this->mRecentDays = $this->user->getOption( 'rcdays' );
 385+ $this->mWatchlistEdits = $this->user->getOption( 'wllimit' );
 386+ $this->mUnderline = $this->user->getOption( 'underline' );
 387+ $this->mWatchlistDays = $this->user->getOption( 'watchlistdays' );
 388+ $this->mUseAjaxSearch = $this->user->getBoolOption( 'ajaxsearch' );
 389+
 390+ $togs = User::getToggles();
 391+ foreach ( $togs as $tname ) {
 392+ $this->mToggles[$tname] = $this->user->getOption( $tname );
 393+ }
 394+
 395+ $namespaces = $wgContLang->getNamespaces();
 396+ foreach ( $namespaces as $i => $namespace ) {
 397+ if ( $i >= NS_MAIN ) {
 398+ $this->mSearchNs[$i] = $this->user->getOption( 'searchNs'.$i );
 399+ }
 400+ }
 401+
 402+ wfRunHooks( 'ResetPreferences', array( $this, $this->user ) );
 403+ }
 404+
 405+ /**
 406+ * @access private
 407+ */
 408+ function namespacesCheckboxes() {
 409+ global $wgContLang;
 410+
 411+ # Determine namespace checkboxes
 412+ $namespaces = $wgContLang->getNamespaces();
 413+ $r1 = null;
 414+
 415+ foreach ( $namespaces as $i => $name ) {
 416+ if ($i < 0)
 417+ continue;
 418+ $checked = $this->mSearchNs[$i] ? "checked='checked'" : '';
 419+ $name = str_replace( '_', ' ', $namespaces[$i] );
 420+
 421+ if ( empty($name) )
 422+ $name = wfMsg( 'blanknamespace' );
 423+
 424+ $r1 .= "<input type='checkbox' value='1' name='wpNs$i' id='wpNs$i' {$checked}/> <label for='wpNs$i'>{$name}</label><br />\n";
 425+ }
 426+ return $r1;
 427+ }
 428+
 429+
 430+ function getToggle( $tname, $trailer = false, $disabled = false ) {
 431+ global $wgUser, $wgLang;
 432+
 433+ $this->mUsedToggles[$tname] = true;
 434+ $ttext = $wgLang->getUserToggle( $tname );
 435+
 436+ $checked = $this->user->getOption( $tname ) == 1 ? ' checked="checked"' : '';
 437+ $disabled = $disabled ? ' disabled="disabled"' : '';
 438+ $trailer = $trailer ? $trailer : '';
 439+ return "<div class='toggle'><input type='checkbox' value='1' id=\"$tname\" name=\"wpOp$tname\"$checked$disabled />" .
 440+ " <span class='toggletext'><label for=\"$tname\">$ttext</label>$trailer</span></div>\n";
 441+ }
 442+
 443+ function getToggles( $items ) {
 444+ $out = "";
 445+ foreach( $items as $item ) {
 446+ if( $item === false )
 447+ continue;
 448+ if( is_array( $item ) ) {
 449+ list( $key, $trailer ) = $item;
 450+ } else {
 451+ $key = $item;
 452+ $trailer = false;
 453+ }
 454+ $out .= $this->getToggle( $key, $trailer );
 455+ }
 456+ return $out;
 457+ }
 458+
 459+ function addRow($td1, $td2) {
 460+ return "<tr><td align='right'>$td1</td><td align='left'>$td2</td></tr>";
 461+ }
 462+
 463+ /**
 464+ * Helper function for user information panel
 465+ * @param $td1 label for an item
 466+ * @param $td2 item or null
 467+ * @param $td3 optional help or null
 468+ * @return xhtml block
 469+ */
 470+ function tableRow( $td1, $td2 = null, $td3 = null ) {
 471+ global $wgContLang;
 472+
 473+ $align['align'] = $wgContLang->isRtl() ? 'right' : 'left';
 474+
 475+ if ( is_null( $td3 ) ) {
 476+ $td3 = '';
 477+ } else {
 478+ $td3 = Xml::tags( 'tr', null,
 479+ Xml::tags( 'td', array( 'colspan' => '2' ), $td3 )
 480+ );
 481+ }
 482+
 483+ if ( is_null( $td2 ) ) {
 484+ $td1 = Xml::tags( 'td', $align + array( 'colspan' => '2' ), $td1 );
 485+ $td2 = '';
 486+ } else {
 487+ $td1 = Xml::tags( 'td', $align, $td1 );
 488+ $td2 = Xml::tags( 'td', $align, $td2 );
 489+ }
 490+
 491+ return Xml::tags( 'tr', null, $td1 . $td2 ). $td3 . "\n";
 492+
 493+ }
 494+
 495+ /**
 496+ * @access private
 497+ */
 498+ function mainPrefsForm( $status , $message = '' ) {
 499+ global $wgUser, $wgOut, $wgLang, $wgContLang;
 500+ global $wgAllowRealName, $wgImageLimits, $wgThumbLimits;
 501+ global $wgDisableLangConversion;
 502+ global $wgEnotifWatchlist, $wgEnotifUserTalk,$wgEnotifMinorEdits;
 503+ global $wgRCShowWatchingUsers, $wgEnotifRevealEditorAddress;
 504+ global $wgEnableEmail, $wgEnableUserEmail, $wgEmailAuthentication;
 505+ global $wgContLanguageCode, $wgDefaultSkin, $wgSkipSkins, $wgAuth;
 506+ global $wgEmailConfirmToEdit, $wgAjaxSearch;
 507+
 508+ $wgOut->disallowUserJs(); # Prevent hijacked user scripts from sniffing passwords etc.
 509+
 510+ if ( $this->mSuccess || 'success' == $status ) {
 511+ $wgOut->wrapWikiMsg( '<div class="successbox"><strong>$1</strong></div>', 'savedprefs' );
 512+ } else if ( 'error' == $status ) {
 513+ $wgOut->addWikiText( '<div class="errorbox"><strong>' . $message . '</strong></div>' );
 514+ } else if ( '' != $status ) {
 515+ $wgOut->addWikiText( $message . "\n----" );
 516+ }
 517+
 518+ $qbs = $wgLang->getQuickbarSettings();
 519+ $skinNames = $wgLang->getSkinNames();
 520+ $mathopts = $wgLang->getMathNames();
 521+ $dateopts = $wgLang->getDatePreferences();
 522+ $togs = User::getToggles();
 523+
 524+ $titleObj = SpecialPage::getTitleFor( 'EditUser' );
 525+ $action = $titleObj->escapeLocalURL();
 526+
 527+ # Pre-expire some toggles so they won't show if disabled
 528+ $this->mUsedToggles[ 'shownumberswatching' ] = true;
 529+ $this->mUsedToggles[ 'showupdated' ] = true;
 530+ $this->mUsedToggles[ 'enotifwatchlistpages' ] = true;
 531+ $this->mUsedToggles[ 'enotifusertalkpages' ] = true;
 532+ $this->mUsedToggles[ 'enotifminoredits' ] = true;
 533+ $this->mUsedToggles[ 'enotifrevealaddr' ] = true;
 534+ $this->mUsedToggles[ 'ccmeonemails' ] = true;
 535+ $this->mUsedToggles[ 'uselivepreview' ] = true;
 536+
 537+
 538+ if ( !$this->mEmailFlag ) { $emfc = 'checked="checked"'; }
 539+ else { $emfc = ''; }
 540+
 541+
 542+ if ($wgEmailAuthentication && ($this->mUserEmail != '') ) {
 543+ if( $this->user->getEmailAuthenticationTimestamp() ) {
 544+ $emailauthenticated = wfMsg('emailauthenticated',$wgLang->timeanddate($this->user->getEmailAuthenticationTimestamp(), true ) ).'<br />';
 545+ $disableEmailPrefs = false;
 546+ } else {
 547+ $disableEmailPrefs = true;
 548+ $skin = $this->user->getSkin();
 549+ $emailauthenticated = wfMsg('emailnotauthenticated').'<br />' .
 550+ $skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Confirmemail' ),
 551+ wfMsg( 'emailconfirmlink' ) ) . '<br />';
 552+ }
 553+ } else {
 554+ $emailauthenticated = '';
 555+ $disableEmailPrefs = false;
 556+ }
 557+
 558+ if ($this->mUserEmail == '') {
 559+ $emailauthenticated = wfMsg( 'noemailprefs' ) . '<br />';
 560+ }
 561+
 562+ $ps = $this->namespacesCheckboxes();
 563+
 564+ $enotifwatchlistpages = ($wgEnotifWatchlist) ? $this->getToggle( 'enotifwatchlistpages', false, $disableEmailPrefs ) : '';
 565+ $enotifusertalkpages = ($wgEnotifUserTalk) ? $this->getToggle( 'enotifusertalkpages', false, $disableEmailPrefs ) : '';
 566+ $enotifminoredits = ($wgEnotifWatchlist && $wgEnotifMinorEdits) ? $this->getToggle( 'enotifminoredits', false, $disableEmailPrefs ) : '';
 567+ $enotifrevealaddr = (($wgEnotifWatchlist || $wgEnotifUserTalk) && $wgEnotifRevealEditorAddress) ? $this->getToggle( 'enotifrevealaddr', false, $disableEmailPrefs ) : '';
 568+
 569+ # </FIXME>
 570+
 571+ $wgOut->addHTML( "<form action=\"$action\" method='post'>" );
 572+ $wgOut->addHTML( "<div id='preferences'>" );
 573+
 574+ # User data
 575+
 576+ $wgOut->addHTML(
 577+ Xml::openElement( 'fieldset ' ) .
 578+ Xml::element( 'legend', null, wfMsg('prefs-personal') ) .
 579+ Xml::openElement( 'table' ) .
 580+ $this->tableRow( Xml::element( 'h2', null, wfMsg( 'prefs-personal' ) ) )
 581+ );
 582+
 583+ $userInformationHtml =
 584+ $this->tableRow( wfMsgHtml( 'username' ), htmlspecialchars( $this->user->getName() ) ) .
 585+ $this->tableRow( wfMsgHtml( 'uid' ), htmlspecialchars( $this->user->getID() ) ) .
 586+ $this->tableRow(
 587+ wfMsgHtml( 'prefs-edits' ),
 588+ $wgLang->formatNum( User::edits( $this->user->getId() ) )
 589+ );
 590+
 591+ if( wfRunHooks( 'PreferencesUserInformationPanel', array( $this, &$userInformationHtml ) ) ) {
 592+ $wgOut->addHtml( $userInformationHtml );
 593+ }
 594+
 595+ if ( $wgAllowRealName ) {
 596+ $wgOut->addHTML(
 597+ $this->tableRow(
 598+ Xml::label( wfMsg('yourrealname'), 'wpRealName' ),
 599+ Xml::input( 'wpRealName', 25, $this->mRealName, array( 'id' => 'wpRealName' ) ),
 600+ Xml::tags('div', array( 'class' => 'prefsectiontip' ),
 601+ wfMsgExt( 'prefs-help-realname', 'parseinline' )
 602+ )
 603+ )
 604+ );
 605+ }
 606+ if ( $wgEnableEmail ) {
 607+ $wgOut->addHTML(
 608+ $this->tableRow(
 609+ Xml::label( wfMsg('youremail'), 'wpUserEmail' ),
 610+ Xml::input( 'wpUserEmail', 25, $this->mUserEmail, array( 'id' => 'wpUserEmail' ) ),
 611+ Xml::tags('div', array( 'class' => 'prefsectiontip' ),
 612+ wfMsgExt( $wgEmailConfirmToEdit ? 'prefs-help-email-required' : 'prefs-help-email', 'parseinline' )
 613+ )
 614+ )
 615+ );
 616+ }
 617+
 618+ global $wgParser, $wgMaxSigChars;
 619+ if( mb_strlen( $this->mNick ) > $wgMaxSigChars ) {
 620+ $invalidSig = $this->tableRow(
 621+ '&nbsp;',
 622+ Xml::element( 'span', array( 'class' => 'error' ),
 623+ wfMsg( 'badsiglength', $wgLang->formatNum( $wgMaxSigChars ) ) )
 624+ );
 625+ } elseif( !empty( $this->mToggles['fancysig'] ) &&
 626+ false === $wgParser->validateSig( $this->mNick ) ) {
 627+ $invalidSig = $this->tableRow(
 628+ '&nbsp;',
 629+ Xml::element( 'span', array( 'class' => 'error' ), wfMsg( 'badsig' ) )
 630+ );
 631+ } else {
 632+ $invalidSig = '';
 633+ }
 634+
 635+ $wgOut->addHTML(
 636+ $this->tableRow(
 637+ Xml::label( wfMsg( 'yournick' ), 'wpNick' ),
 638+ Xml::input( 'wpNick', 25, $this->mNick,
 639+ array(
 640+ 'id' => 'wpNick',
 641+ // Note: $wgMaxSigChars is enforced in Unicode characters,
 642+ // both on the backend and now in the browser.
 643+ // Badly-behaved requests may still try to submit
 644+ // an overlong string, however.
 645+ 'maxlength' => $wgMaxSigChars ) )
 646+ ) .
 647+ $invalidSig .
 648+ $this->tableRow( '&nbsp;', $this->getToggle( 'fancysig' ) )
 649+ );
 650+
 651+ list( $lsLabel, $lsSelect) = Xml::languageSelector( $this->mUserLanguage );
 652+ $wgOut->addHTML(
 653+ $this->tableRow( $lsLabel, $lsSelect )
 654+ );
 655+
 656+ /* see if there are multiple language variants to choose from*/
 657+ if(!$wgDisableLangConversion) {
 658+ $variants = $wgContLang->getVariants();
 659+ $variantArray = array();
 660+
 661+ $languages = Language::getLanguageNames( true );
 662+ foreach($variants as $v) {
 663+ $v = str_replace( '_', '-', strtolower($v));
 664+ if( array_key_exists( $v, $languages ) ) {
 665+ // If it doesn't have a name, we'll pretend it doesn't exist
 666+ $variantArray[$v] = $languages[$v];
 667+ }
 668+ }
 669+
 670+ $options = "\n";
 671+ foreach( $variantArray as $code => $name ) {
 672+ $selected = ($code == $this->mUserVariant);
 673+ $options .= Xml::option( "$code - $name", $code, $selected ) . "\n";
 674+ }
 675+
 676+ if(count($variantArray) > 1) {
 677+ $wgOut->addHtml(
 678+ $this->tableRow(
 679+ Xml::label( wfMsg( 'yourvariant' ), 'wpUserVariant' ),
 680+ Xml::tags( 'select',
 681+ array( 'name' => 'wpUserVariant', 'id' => 'wpUserVariant' ),
 682+ $options
 683+ )
 684+ )
 685+ );
 686+ }
 687+ }
 688+
 689+ # Password
 690+ if( $wgAuth->allowPasswordChange() ) {
 691+ $wgOut->addHTML(
 692+ $this->tableRow( Xml::element( 'h2', null, wfMsg( 'changepassword' ) ) ) .
 693+ $this->tableRow(
 694+ Xml::label( wfMsg( 'newpassword' ), 'wpNewpass' ),
 695+ Xml::password( 'wpNewpass', 25, $this->mNewpass, array( 'id' => 'wpNewpass' ) )
 696+ ) .
 697+ $this->tableRow(
 698+ Xml::label( wfMsg( 'retypenew' ), 'wpRetypePass' ),
 699+ Xml::password( 'wpRetypePass', 25, $this->mRetypePass, array( 'id' => 'wpRetypePass' ) )
 700+ ) .
 701+ Xml::tags( 'tr', null,
 702+ Xml::tags( 'td', array( 'colspan' => '2' ),
 703+ $this->getToggle( "rememberpassword" )
 704+ )
 705+ )
 706+ );
 707+ }
 708+
 709+ # <FIXME>
 710+ # Enotif
 711+ if ( $wgEnableEmail ) {
 712+
 713+ $moreEmail = '';
 714+ if ($wgEnableUserEmail) {
 715+ $emf = wfMsg( 'allowemail' );
 716+ $disabled = $disableEmailPrefs ? ' disabled="disabled"' : '';
 717+ $moreEmail =
 718+ "<input type='checkbox' $emfc $disabled value='1' name='wpEmailFlag' id='wpEmailFlag' /> <label for='wpEmailFlag'>$emf</label>";
 719+ }
 720+
 721+
 722+ $wgOut->addHTML(
 723+ $this->tableRow( Xml::element( 'h2', null, wfMsg( 'email' ) ) ) .
 724+ $this->tableRow(
 725+ $emailauthenticated.
 726+ $enotifrevealaddr.
 727+ $enotifwatchlistpages.
 728+ $enotifusertalkpages.
 729+ $enotifminoredits.
 730+ $moreEmail.
 731+ $this->getToggle( 'ccmeonemails' )
 732+ )
 733+ );
 734+ }
 735+ # </FIXME>
 736+
 737+ $wgOut->addHTML(
 738+ Xml::closeElement( 'table' ) .
 739+ Xml::closeElement( 'fieldset' )
 740+ );
 741+
 742+
 743+ # Quickbar
 744+ #
 745+ if ($this->mSkin == 'cologneblue' || $this->mSkin == 'standard') {
 746+ $wgOut->addHtml( "<fieldset>\n<legend>" . wfMsg( 'qbsettings' ) . "</legend>\n" );
 747+ for ( $i = 0; $i < count( $qbs ); ++$i ) {
 748+ if ( $i == $this->mQuickbar ) { $checked = ' checked="checked"'; }
 749+ else { $checked = ""; }
 750+ $wgOut->addHTML( "<div><label><input type='radio' name='wpQuickbar' value=\"$i\"$checked />{$qbs[$i]}</label></div>\n" );
 751+ }
 752+ $wgOut->addHtml( "</fieldset>\n\n" );
 753+ } else {
 754+ # Need to output a hidden option even if the relevant skin is not in use,
 755+ # otherwise the preference will get reset to 0 on submit
 756+ $wgOut->addHtml( wfHidden( 'wpQuickbar', $this->mQuickbar ) );
 757+ }
 758+
 759+ # Skin
 760+ #
 761+ $wgOut->addHTML( "<fieldset>\n<legend>\n" . wfMsg('skin') . "</legend>\n" );
 762+ $mptitle = Title::newMainPage();
 763+ $previewtext = wfMsg('skinpreview');
 764+ # Only show members of Skin::getSkinNames() rather than
 765+ # $skinNames (skins is all skin names from Language.php)
 766+ $validSkinNames = Skin::getSkinNames();
 767+ # Sort by UI skin name. First though need to update validSkinNames as sometimes
 768+ # the skinkey & UI skinname differ (e.g. "standard" skinkey is "Classic" in the UI).
 769+ foreach ($validSkinNames as $skinkey => & $skinname ) {
 770+ if ( isset( $skinNames[$skinkey] ) ) {
 771+ $skinname = $skinNames[$skinkey];
 772+ }
 773+ }
 774+ asort($validSkinNames);
 775+ foreach ($validSkinNames as $skinkey => $sn ) {
 776+ if ( in_array( $skinkey, $wgSkipSkins ) ) {
 777+ continue;
 778+ }
 779+ $checked = $skinkey == $this->mSkin ? ' checked="checked"' : '';
 780+
 781+ $mplink = htmlspecialchars($mptitle->getLocalURL("useskin=$skinkey"));
 782+ $previewlink = "<a target='_blank' href=\"$mplink\">$previewtext</a>";
 783+ if( $skinkey == $wgDefaultSkin )
 784+ $sn .= ' (' . wfMsg( 'default' ) . ')';
 785+ $wgOut->addHTML( "<input type='radio' name='wpSkin' id=\"wpSkin$skinkey\" value=\"$skinkey\"$checked /> <label for=\"wpSkin$skinkey\">{$sn}</label> $previewlink<br />\n" );
 786+ }
 787+ $wgOut->addHTML( "</fieldset>\n\n" );
 788+
 789+ # Math
 790+ #
 791+ global $wgUseTeX;
 792+ if( $wgUseTeX ) {
 793+ $wgOut->addHTML( "<fieldset>\n<legend>" . wfMsg('math') . '</legend>' );
 794+ foreach ( $mathopts as $k => $v ) {
 795+ $checked = ($k == $this->mMath);
 796+ $wgOut->addHTML(
 797+ Xml::openElement( 'div' ) .
 798+ Xml::radioLabel( wfMsg( $v ), 'wpMath', $k, "mw-sp-math-$k", $checked ) .
 799+ Xml::closeElement( 'div' ) . "\n"
 800+ );
 801+ }
 802+ $wgOut->addHTML( "</fieldset>\n\n" );
 803+ }
 804+
 805+ # Files
 806+ #
 807+ $wgOut->addHTML(
 808+ "<fieldset>\n" . Xml::element( 'legend', null, wfMsg( 'files' ) ) . "\n"
 809+ );
 810+
 811+ $imageLimitOptions = null;
 812+ foreach ( $wgImageLimits as $index => $limits ) {
 813+ $selected = ($index == $this->mImageSize);
 814+ $imageLimitOptions .= Xml::option( "{$limits[0]}×{$limits[1]}" .
 815+ wfMsg('unit-pixel'), $index, $selected );
 816+ }
 817+
 818+ $imageSizeId = 'wpImageSize';
 819+ $wgOut->addHTML(
 820+ "<div>" . Xml::label( wfMsg('imagemaxsize'), $imageSizeId ) . " " .
 821+ Xml::openElement( 'select', array( 'name' => $imageSizeId, 'id' => $imageSizeId ) ) .
 822+ $imageLimitOptions .
 823+ Xml::closeElement( 'select' ) . "</div>\n"
 824+ );
 825+
 826+ $imageThumbOptions = null;
 827+ foreach ( $wgThumbLimits as $index => $size ) {
 828+ $selected = ($index == $this->mThumbSize);
 829+ $imageThumbOptions .= Xml::option($size . wfMsg('unit-pixel'), $index,
 830+ $selected);
 831+ }
 832+
 833+ $thumbSizeId = 'wpThumbSize';
 834+ $wgOut->addHTML(
 835+ "<div>" . Xml::label( wfMsg('thumbsize'), $thumbSizeId ) . " " .
 836+ Xml::openElement( 'select', array( 'name' => $thumbSizeId, 'id' => $thumbSizeId ) ) .
 837+ $imageThumbOptions .
 838+ Xml::closeElement( 'select' ) . "</div>\n"
 839+ );
 840+
 841+ $wgOut->addHTML( "</fieldset>\n\n" );
 842+
 843+ # Date format
 844+ #
 845+ # Date/Time
 846+ #
 847+
 848+ $wgOut->addHTML( "<fieldset>\n<legend>" . wfMsg( 'datetime' ) . "</legend>\n" );
 849+
 850+ if ($dateopts) {
 851+ $wgOut->addHTML( "<fieldset>\n<legend>" . wfMsg( 'dateformat' ) . "</legend>\n" );
 852+ $idCnt = 0;
 853+ $epoch = '20010115161234'; # Wikipedia day
 854+ foreach( $dateopts as $key ) {
 855+ if( $key == 'default' ) {
 856+ $formatted = wfMsgHtml( 'datedefault' );
 857+ } else {
 858+ $formatted = htmlspecialchars( $wgLang->timeanddate( $epoch, false, $key ) );
 859+ }
 860+ ($key == $this->mDate) ? $checked = ' checked="checked"' : $checked = '';
 861+ $wgOut->addHTML( "<div><input type='radio' name=\"wpDate\" id=\"wpDate$idCnt\" ".
 862+ "value=\"$key\"$checked /> <label for=\"wpDate$idCnt\">$formatted</label></div>\n" );
 863+ $idCnt++;
 864+ }
 865+ $wgOut->addHTML( "</fieldset>\n" );
 866+ }
 867+
 868+ $nowlocal = $wgLang->time( $now = wfTimestampNow(), true );
 869+ $nowserver = $wgLang->time( $now, false );
 870+
 871+ $wgOut->addHTML( '<fieldset><legend>' . wfMsg( 'timezonelegend' ). '</legend><table>' .
 872+ $this->addRow( wfMsg( 'servertime' ), $nowserver ) .
 873+ $this->addRow( wfMsg( 'localtime' ), $nowlocal ) .
 874+ $this->addRow(
 875+ '<label for="wpHourDiff">' . wfMsg( 'timezoneoffset' ) . '</label>',
 876+ "<input type='text' name='wpHourDiff' id='wpHourDiff' value=\"" . htmlspecialchars( $this->mHourDiff ) . "\" size='6' />"
 877+ ) . "<tr><td colspan='2'>
 878+ <input type='button' value=\"" . wfMsg( 'guesstimezone' ) ."\"
 879+ onclick='javascript:guessTimezone()' id='guesstimezonebutton' style='display:none;' />
 880+ </td></tr></table><div class='prefsectiontip'>¹" . wfMsg( 'timezonetext' ) . "</div></fieldset>
 881+ </fieldset>\n\n" );
 882+
 883+ # Editing
 884+ #
 885+ global $wgLivePreview;
 886+ $wgOut->addHTML( '<fieldset><legend>' . wfMsg( 'textboxsize' ) . '</legend>
 887+ <div>' .
 888+ wfInputLabel( wfMsg( 'rows' ), 'wpRows', 'wpRows', 3, $this->mRows ) .
 889+ ' ' .
 890+ wfInputLabel( wfMsg( 'columns' ), 'wpCols', 'wpCols', 3, $this->mCols ) .
 891+ "</div>" .
 892+ $this->getToggles( array(
 893+ 'editsection',
 894+ 'editsectiononrightclick',
 895+ 'editondblclick',
 896+ 'editwidth',
 897+ 'showtoolbar',
 898+ 'previewonfirst',
 899+ 'previewontop',
 900+ 'minordefault',
 901+ 'externaleditor',
 902+ 'externaldiff',
 903+ $wgLivePreview ? 'uselivepreview' : false,
 904+ 'forceeditsummary',
 905+ ) ) . '</fieldset>'
 906+ );
 907+
 908+ # Recent changes
 909+ $wgOut->addHtml( '<fieldset><legend>' . wfMsgHtml( 'prefs-rc' ) . '</legend>' );
 910+
 911+ $rc = '<table><tr>';
 912+ $rc .= '<td>' . Xml::label( wfMsg( 'recentchangesdays' ), 'wpRecentDays' ) . '</td>';
 913+ $rc .= '<td>' . Xml::input( 'wpRecentDays', 3, $this->mRecentDays, array( 'id' => 'wpRecentDays' ) ) . '</td>';
 914+ $rc .= '</tr><tr>';
 915+ $rc .= '<td>' . Xml::label( wfMsg( 'recentchangescount' ), 'wpRecent' ) . '</td>';
 916+ $rc .= '<td>' . Xml::input( 'wpRecent', 3, $this->mRecent, array( 'id' => 'wpRecent' ) ) . '</td>';
 917+ $rc .= '</tr></table>';
 918+ $wgOut->addHtml( $rc );
 919+
 920+ $wgOut->addHtml( '<br />' );
 921+
 922+ $toggles[] = 'hideminor';
 923+ if( $wgRCShowWatchingUsers )
 924+ $toggles[] = 'shownumberswatching';
 925+ $toggles[] = 'usenewrc';
 926+ $wgOut->addHtml( $this->getToggles( $toggles ) );
 927+
 928+ $wgOut->addHtml( '</fieldset>' );
 929+
 930+ # Watchlist
 931+ $wgOut->addHtml( '<fieldset><legend>' . wfMsgHtml( 'prefs-watchlist' ) . '</legend>' );
 932+
 933+ $wgOut->addHtml( wfInputLabel( wfMsg( 'prefs-watchlist-days' ), 'wpWatchlistDays', 'wpWatchlistDays', 3, $this->mWatchlistDays ) );
 934+ $wgOut->addHtml( '<br /><br />' );
 935+
 936+ $wgOut->addHtml( $this->getToggle( 'extendwatchlist' ) );
 937+ $wgOut->addHtml( wfInputLabel( wfMsg( 'prefs-watchlist-edits' ), 'wpWatchlistEdits', 'wpWatchlistEdits', 3, $this->mWatchlistEdits ) );
 938+ $wgOut->addHtml( '<br /><br />' );
 939+
 940+ $wgOut->addHtml( $this->getToggles( array( 'watchlisthideown', 'watchlisthidebots', 'watchlisthideminor' ) ) );
 941+
 942+ if( $this->user->isAllowed( 'createpage' ) || $this->user->isAllowed( 'createtalk' ) )
 943+ $wgOut->addHtml( $this->getToggle( 'watchcreations' ) );
 944+ foreach( array( 'edit' => 'watchdefault', 'move' => 'watchmoves', 'delete' => 'watchdeletion' ) as $action => $toggle ) {
 945+ if( $this->user->isAllowed( $action ) )
 946+ $wgOut->addHtml( $this->getToggle( $toggle ) );
 947+ }
 948+ $this->mUsedToggles['watchcreations'] = true;
 949+ $this->mUsedToggles['watchdefault'] = true;
 950+ $this->mUsedToggles['watchmoves'] = true;
 951+ $this->mUsedToggles['watchdeletion'] = true;
 952+
 953+ $wgOut->addHtml( '</fieldset>' );
 954+
 955+ # Search
 956+ $ajaxsearch = $wgAjaxSearch ?
 957+ $this->addRow(
 958+ wfLabel( wfMsg( 'useajaxsearch' ), 'wpUseAjaxSearch' ),
 959+ wfCheck( 'wpUseAjaxSearch', $this->mUseAjaxSearch, array( 'id' => 'wpUseAjaxSearch' ) )
 960+ ) : '';
 961+ $wgOut->addHTML( '<fieldset><legend>' . wfMsg( 'searchresultshead' ) . '</legend><table>' .
 962+ $ajaxsearch .
 963+ $this->addRow(
 964+ wfLabel( wfMsg( 'resultsperpage' ), 'wpSearch' ),
 965+ wfInput( 'wpSearch', 4, $this->mSearch, array( 'id' => 'wpSearch' ) )
 966+ ) .
 967+ $this->addRow(
 968+ wfLabel( wfMsg( 'contextlines' ), 'wpSearchLines' ),
 969+ wfInput( 'wpSearchLines', 4, $this->mSearchLines, array( 'id' => 'wpSearchLines' ) )
 970+ ) .
 971+ $this->addRow(
 972+ wfLabel( wfMsg( 'contextchars' ), 'wpSearchChars' ),
 973+ wfInput( 'wpSearchChars', 4, $this->mSearchChars, array( 'id' => 'wpSearchChars' ) )
 974+ ) .
 975+ "</table><fieldset><legend>" . wfMsg( 'defaultns' ) . "</legend>$ps</fieldset></fieldset>" );
 976+
 977+ # Misc
 978+ #
 979+ $wgOut->addHTML('<fieldset><legend>' . wfMsg('prefs-misc') . '</legend>');
 980+ $wgOut->addHtml( '<label for="wpStubs">' . wfMsg( 'stub-threshold' ) . '</label>&nbsp;' );
 981+ $wgOut->addHtml( Xml::input( 'wpStubs', 6, $this->mStubs, array( 'id' => 'wpStubs' ) ) );
 982+ $msgUnderline = htmlspecialchars( wfMsg ( 'tog-underline' ) );
 983+ $msgUnderlinenever = htmlspecialchars( wfMsg ( 'underline-never' ) );
 984+ $msgUnderlinealways = htmlspecialchars( wfMsg ( 'underline-always' ) );
 985+ $msgUnderlinedefault = htmlspecialchars( wfMsg ( 'underline-default' ) );
 986+ $uopt = $this->user->getOption("underline");
 987+ $s0 = $uopt == 0 ? ' selected="selected"' : '';
 988+ $s1 = $uopt == 1 ? ' selected="selected"' : '';
 989+ $s2 = $uopt == 2 ? ' selected="selected"' : '';
 990+ $wgOut->addHTML("
 991+<div class='toggle'><p><label for='wpOpunderline'>$msgUnderline</label>
 992+<select name='wpOpunderline' id='wpOpunderline'>
 993+<option value=\"0\"$s0>$msgUnderlinenever</option>
 994+<option value=\"1\"$s1>$msgUnderlinealways</option>
 995+<option value=\"2\"$s2>$msgUnderlinedefault</option>
 996+</select></p></div>");
 997+
 998+ foreach ( $togs as $tname ) {
 999+ if( !array_key_exists( $tname, $this->mUsedToggles ) ) {
 1000+ $wgOut->addHTML( $this->getToggle( $tname ) );
 1001+ }
 1002+ }
 1003+ $wgOut->addHTML( '</fieldset>' );
 1004+
 1005+ wfRunHooks( 'RenderPreferencesForm', array( $this, $wgOut ) );
 1006+
 1007+ $token = htmlspecialchars( $this->user->editToken() );
 1008+ $skin = $this->user->getSkin();
 1009+ $wgOut->addHTML( "
 1010+ <div id='prefsubmit'>
 1011+ <div>
 1012+ <input type='submit' name='wpSaveprefs' class='btnSavePrefs' value=\"" . wfMsgHtml( 'saveprefs' ) . '"'.$skin->tooltipAndAccesskey('save')." />
 1013+ <input type='submit' name='wpReset' value=\"" . wfMsgHtml( 'resetprefs' ) . "\" />
 1014+ </div>
 1015+
 1016+ </div>
 1017+
 1018+ <input type='hidden' name='wpEditToken' value=\"{$token}\" />
 1019+ </div></form>\n" );
 1020+
 1021+ $wgOut->addHtml( Xml::tags( 'div', array( 'class' => "prefcache" ),
 1022+ wfMsgExt( 'clearyourcache', 'parseinline' ) )
 1023+ );
 1024+
 1025+ }
 1026+
 1027+ function makeSearchForm() {
 1028+ $thisTitle = Title::makeTitle( NS_SPECIAL, $this->getName() );
 1029+ $form = wfOpenElement( 'form', array( 'method' => 'post', 'action' => $thisTitle->getLocalUrl() ) );
 1030+ $form .= wfElement( 'label', array( 'for' => 'username' ), wfMsg( 'edituser-username' ) ) . ' ';
 1031+ $form .= wfElement( 'input', array( 'type' => 'text', 'name' => 'username', 'id' => 'username', 'value' => $this->target ) ) . ' ';
 1032+ $form .= wfElement( 'input', array( 'type' => 'submit', 'name' => 'dosearch', 'value' => wfMsg( 'edituser-dosearch' ) ) );
 1033+ $form .= wfElement( 'input', array( 'type' => 'hidden', 'name' => 'issearch', 'value' => '1' ) );
 1034+ $form .= wfCloseElement( 'form' );
 1035+ return $form;
 1036+ }
 1037+}
 1038+
Property changes on: trunk/extensions/EditUser/1.12/EditUser_body.php
___________________________________________________________________
Added: svn:eol-style
11039 + native
Index: trunk/extensions/EditUser/1.13/EditUser_body.php
@@ -0,0 +1,1117 @@
 2+<?php
 3+/* Shamelessly copied and modified from /includes/specials/SpecialPreferences.php v1.13 */
 4+class EditUser extends SpecialPage {
 5+ var $mQuickbar, $mOldpass, $mNewpass, $mRetypePass, $mStubs;
 6+ var $mRows, $mCols, $mSkin, $mMath, $mDate, $mUserEmail, $mEmailFlag, $mNick;
 7+ var $mUserLanguage, $mUserVariant;
 8+ var $mSearch, $mRecent, $mRecentDays, $mHourDiff, $mSearchLines, $mSearchChars, $mAction;
 9+ var $mReset, $mPosted, $mToggles, $mUseAjaxSearch, $mSearchNs, $mRealName, $mImageSize;
 10+ var $mUnderline, $mWatchlistEdits;
 11+ var $user, $target;
 12+
 13+ function __construct() {
 14+ SpecialPage::SpecialPage('EditUser', 'edituser');
 15+ }
 16+ /**
 17+ * Constructor
 18+ * Load some values
 19+ */
 20+ function loadGlobals( $par ) {
 21+ global $wgContLang, $wgAllowRealName, $wgRequest;
 22+ $request = $wgRequest;
 23+ $this->user = User::newFromName($par);
 24+ $this->user->load();
 25+ $this->mQuickbar = $request->getVal( 'wpQuickbar' );
 26+ $this->mNewpass = $request->getVal( 'wpNewpass' );
 27+ $this->mRetypePass = $request->getVal( 'wpRetypePass' );
 28+ $this->mStubs = $request->getVal( 'wpStubs' );
 29+ $this->mRows = $request->getVal( 'wpRows' );
 30+ $this->mCols = $request->getVal( 'wpCols' );
 31+ $this->mSkin = $request->getVal( 'wpSkin' );
 32+ $this->mMath = $request->getVal( 'wpMath' );
 33+ $this->mDate = $request->getVal( 'wpDate' );
 34+ $this->mUserEmail = $request->getVal( 'wpUserEmail' );
 35+ $this->mRealName = $wgAllowRealName ? $request->getVal( 'wpRealName' ) : '';
 36+ $this->mEmailFlag = $request->getCheck( 'wpEmailFlag' ) ? 0 : 1;
 37+ $this->mNick = $request->getVal( 'wpNick' );
 38+ $this->mUserLanguage = $request->getVal( 'wpUserLanguage' );
 39+ $this->mUserVariant = $request->getVal( 'wpUserVariant' );
 40+ $this->mSearch = $request->getVal( 'wpSearch' );
 41+ $this->mRecent = $request->getVal( 'wpRecent' );
 42+ $this->mRecentDays = $request->getVal( 'wpRecentDays' );
 43+ $this->mHourDiff = $request->getVal( 'wpHourDiff' );
 44+ $this->mSearchLines = $request->getVal( 'wpSearchLines' );
 45+ $this->mSearchChars = $request->getVal( 'wpSearchChars' );
 46+ $this->mImageSize = $request->getVal( 'wpImageSize' );
 47+ $this->mThumbSize = $request->getInt( 'wpThumbSize' );
 48+ $this->mUnderline = $request->getInt( 'wpOpunderline' );
 49+ $this->mAction = $request->getVal( 'action' );
 50+ $this->mReset = $request->getCheck( 'wpReset' );
 51+ $this->mPosted = $request->wasPosted();
 52+ $this->mSuccess = $request->getCheck( 'success' );
 53+ $this->mWatchlistDays = $request->getVal( 'wpWatchlistDays' );
 54+ $this->mWatchlistEdits = $request->getVal( 'wpWatchlistEdits' );
 55+ $this->mUseAjaxSearch = $request->getCheck( 'wpUseAjaxSearch' );
 56+ $this->mDisableMWSuggest = $request->getCheck( 'wpDisableMWSuggest' );
 57+ $this->mSaveprefs = $request->getCheck( 'wpSaveprefs' ) &&
 58+ $this->mPosted &&
 59+ $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) );
 60+
 61+ # User toggles (the big ugly unsorted list of checkboxes)
 62+ $this->mToggles = array();
 63+ if ( $this->mPosted ) {
 64+ $togs = User::getToggles();
 65+ foreach ( $togs as $tname ) {
 66+ $this->mToggles[$tname] = $request->getCheck( "wpOp$tname" ) ? 1 : 0;
 67+ }
 68+ }
 69+
 70+ $this->mUsedToggles = array();
 71+
 72+ # Search namespace options
 73+ # Note: namespaces don't necessarily have consecutive keys
 74+ $this->mSearchNs = array();
 75+ if ( $this->mPosted ) {
 76+ $namespaces = $wgContLang->getNamespaces();
 77+ foreach ( $namespaces as $i => $namespace ) {
 78+ if ( $i >= 0 ) {
 79+ $this->mSearchNs[$i] = $request->getCheck( "wpNs$i" ) ? 1 : 0;
 80+ }
 81+ }
 82+ }
 83+
 84+ # Validate language
 85+ if ( !preg_match( '/^[a-z\-]*$/', $this->mUserLanguage ) ) {
 86+ $this->mUserLanguage = 'nolanguage';
 87+ }
 88+
 89+ wfRunHooks( 'InitPreferencesForm', array( $this, $request ) );
 90+ }
 91+
 92+ function execute( $par ) {
 93+ global $wgOut, $wgUser, $wgRequest;
 94+ if( !$wgUser->isAllowed( 'edituser' ) ) {
 95+ $wgOut->permissionRequired( 'edituser' );
 96+ return false;
 97+ }
 98+
 99+ wfLoadExtensionMessages( 'EditUser' );
 100+
 101+ $this->setHeaders();
 102+ $this->target = (isset($par)) ? $par : $wgRequest->getText('username', '');
 103+ if($this->target === '') {
 104+ $wgOut->addHtml($this->makeSearchForm());
 105+ return;
 106+ }
 107+ $targetuser = User::NewFromName( $this->target );
 108+ if( $targetuser->getID() == 0 ) {
 109+ $wgOut->addWikiText( wfMsg( 'edituser-nouser' ) );
 110+ return;
 111+ }
 112+ if( $targetuser->isAllowed('edituser-exempt') ) {
 113+ $wgOut->addWikiText( wfMsg( 'edituser-exempt' ) );
 114+ return;
 115+ }
 116+ $this->loadGlobals($this->target);
 117+ $wgOut->addHtml($this->makeSearchForm());
 118+ $wgOut->addHtml('<br />');
 119+ if ( wfReadOnly() ) {
 120+ $wgOut->readOnlyPage();
 121+ return;
 122+ }
 123+ if ( $this->mReset ) {
 124+ $this->resetPrefs();
 125+ $this->mainPrefsForm( 'reset', wfMsg( 'prefsreset' ) );
 126+ } else if ( $this->mSaveprefs ) {
 127+ $this->savePreferences();
 128+ } else {
 129+ $this->resetPrefs();
 130+ $this->mainPrefsForm( '' );
 131+ }
 132+ }
 133+ /**
 134+ * @access private
 135+ */
 136+ function validateInt( &$val, $min=0, $max=0x7fffffff ) {
 137+ $val = intval($val);
 138+ $val = min($val, $max);
 139+ $val = max($val, $min);
 140+ return $val;
 141+ }
 142+
 143+ /**
 144+ * @access private
 145+ */
 146+ function validateFloat( &$val, $min, $max=0x7fffffff ) {
 147+ $val = floatval( $val );
 148+ $val = min( $val, $max );
 149+ $val = max( $val, $min );
 150+ return( $val );
 151+ }
 152+
 153+ /**
 154+ * @access private
 155+ */
 156+ function validateIntOrNull( &$val, $min=0, $max=0x7fffffff ) {
 157+ $val = trim($val);
 158+ if($val === '') {
 159+ return null;
 160+ } else {
 161+ return $this->validateInt( $val, $min, $max );
 162+ }
 163+ }
 164+
 165+ /**
 166+ * @access private
 167+ */
 168+ function validateDate( $val ) {
 169+ global $wgLang, $wgContLang;
 170+ if ( $val !== false && (
 171+ in_array( $val, (array)$wgLang->getDatePreferences() ) ||
 172+ in_array( $val, (array)$wgContLang->getDatePreferences() ) ) )
 173+ {
 174+ return $val;
 175+ } else {
 176+ return $wgLang->getDefaultDateFormat();
 177+ }
 178+ }
 179+
 180+ /**
 181+ * Used to validate the user inputed timezone before saving it as
 182+ * 'timecorrection', will return '00:00' if fed bogus data.
 183+ * Note: It's not a 100% correct implementation timezone-wise, it will
 184+ * accept stuff like '14:30',
 185+ * @access private
 186+ * @param string $s the user input
 187+ * @return string
 188+ */
 189+ function validateTimeZone( $s ) {
 190+ if ( $s !== '' ) {
 191+ if ( strpos( $s, ':' ) ) {
 192+ # HH:MM
 193+ $array = explode( ':' , $s );
 194+ $hour = intval( $array[0] );
 195+ $minute = intval( $array[1] );
 196+ } else {
 197+ $minute = intval( $s * 60 );
 198+ $hour = intval( $minute / 60 );
 199+ $minute = abs( $minute ) % 60;
 200+ }
 201+ # Max is +14:00 and min is -12:00, see:
 202+ # http://en.wikipedia.org/wiki/Timezone
 203+ $hour = min( $hour, 14 );
 204+ $hour = max( $hour, -12 );
 205+ $minute = min( $minute, 59 );
 206+ $minute = max( $minute, 0 );
 207+ $s = sprintf( "%02d:%02d", $hour, $minute );
 208+ }
 209+ return $s;
 210+ }
 211+
 212+ /**
 213+ * @access private
 214+ */
 215+ function savePreferences() {
 216+ global $wgUser, $wgOut, $wgParser;
 217+ global $wgEnableUserEmail, $wgEnableEmail;
 218+ global $wgEmailAuthentication, $wgRCMaxAge;
 219+ global $wgAuth, $wgEmailConfirmToEdit;
 220+
 221+
 222+ if ( '' != $this->mNewpass && $wgAuth->allowPasswordChange() ) {
 223+ if ( $this->mNewpass != $this->mRetypePass ) {
 224+ wfRunHooks( 'PrefsPasswordAudit', array( $this->user, $this->mNewpass, 'badretype' ) );
 225+ $this->mainPrefsForm( 'error', wfMsg( 'badretype' ) );
 226+ return;
 227+ }
 228+
 229+ try {
 230+ $this->user->setPassword( $this->mNewpass );
 231+ wfRunHooks( 'PrefsPasswordAudit', array( $this->user, $this->mNewpass, 'success' ) );
 232+ $this->mNewpass = $this->mOldpass = $this->mRetypePass = '';
 233+ } catch( PasswordError $e ) {
 234+ wfRunHooks( 'PrefsPasswordAudit', array( $this->user, $this->mNewpass, 'error' ) );
 235+ $this->mainPrefsForm( 'error', $e->getMessage() );
 236+ return;
 237+ }
 238+ }
 239+ $this->user->setRealName( $this->mRealName );
 240+ $oldOptions = $this->user->mOptions;
 241+
 242+ if( $this->user->getOption( 'language' ) !== $this->mUserLanguage ) {
 243+ $needRedirect = true;
 244+ } else {
 245+ $needRedirect = false;
 246+ }
 247+
 248+ # Validate the signature and clean it up as needed
 249+ global $wgMaxSigChars;
 250+ if( mb_strlen( $this->mNick ) > $wgMaxSigChars ) {
 251+ global $wgLang;
 252+ $this->mainPrefsForm( 'error',
 253+ wfMsgExt( 'badsiglength', 'parsemag', $wgLang->formatNum( $wgMaxSigChars ) ) );
 254+ return;
 255+ } elseif( $this->mToggles['fancysig'] ) {
 256+ if( $wgParser->validateSig( $this->mNick ) !== false ) {
 257+ $this->mNick = $wgParser->cleanSig( $this->mNick );
 258+ } else {
 259+ $this->mainPrefsForm( 'error', wfMsg( 'badsig' ) );
 260+ return;
 261+ }
 262+ } else {
 263+ // When no fancy sig used, make sure ~{3,5} get removed.
 264+ $this->mNick = $wgParser->cleanSigInSig( $this->mNick );
 265+ }
 266+
 267+ $this->user->setOption( 'language', $this->mUserLanguage );
 268+ $this->user->setOption( 'variant', $this->mUserVariant );
 269+ $this->user->setOption( 'nickname', $this->mNick );
 270+ $this->user->setOption( 'quickbar', $this->mQuickbar );
 271+ $this->user->setOption( 'skin', $this->mSkin );
 272+ global $wgUseTeX;
 273+ if( $wgUseTeX ) {
 274+ $this->user->setOption( 'math', $this->mMath );
 275+ }
 276+ $this->user->setOption( 'date', $this->validateDate( $this->mDate ) );
 277+ $this->user->setOption( 'searchlimit', $this->validateIntOrNull( $this->mSearch ) );
 278+ $this->user->setOption( 'contextlines', $this->validateIntOrNull( $this->mSearchLines ) );
 279+ $this->user->setOption( 'contextchars', $this->validateIntOrNull( $this->mSearchChars ) );
 280+ $this->user->setOption( 'rclimit', $this->validateIntOrNull( $this->mRecent ) );
 281+ $this->user->setOption( 'rcdays', $this->validateInt($this->mRecentDays, 1, ceil($wgRCMaxAge / (3600*24))));
 282+ $this->user->setOption( 'wllimit', $this->validateIntOrNull( $this->mWatchlistEdits, 0, 1000 ) );
 283+ $this->user->setOption( 'rows', $this->validateInt( $this->mRows, 4, 1000 ) );
 284+ $this->user->setOption( 'cols', $this->validateInt( $this->mCols, 4, 1000 ) );
 285+ $this->user->setOption( 'stubthreshold', $this->validateIntOrNull( $this->mStubs ) );
 286+ $this->user->setOption( 'timecorrection', $this->validateTimeZone( $this->mHourDiff, -12, 14 ) );
 287+ $this->user->setOption( 'imagesize', $this->mImageSize );
 288+ $this->user->setOption( 'thumbsize', $this->mThumbSize );
 289+ $this->user->setOption( 'underline', $this->validateInt($this->mUnderline, 0, 2) );
 290+ $this->user->setOption( 'watchlistdays', $this->validateFloat( $this->mWatchlistDays, 0, 7 ) );
 291+ $this->user->setOption( 'ajaxsearch', $this->mUseAjaxSearch );
 292+ $this->user->setOption( 'disablesuggest', $this->mDisableMWSuggest );
 293+
 294+ # Set search namespace options
 295+ foreach( $this->mSearchNs as $i => $value ) {
 296+ $this->user->setOption( "searchNs{$i}", $value );
 297+ }
 298+
 299+ if( $wgEnableEmail && $wgEnableUserEmail ) {
 300+ $this->user->setOption( 'disablemail', $this->mEmailFlag );
 301+ }
 302+
 303+ # Set user toggles
 304+ foreach ( $this->mToggles as $tname => $tvalue ) {
 305+ $this->user->setOption( $tname, $tvalue );
 306+ }
 307+
 308+ $error = false;
 309+ if( $wgEnableEmail ) {
 310+ $newadr = $this->mUserEmail;
 311+ $oldadr = $this->user->getEmail();
 312+ if( ($newadr != '') && ($newadr != $oldadr) ) {
 313+ # the user has supplied a new email address on the login page
 314+ if( $this->user->isValidEmailAddr( $newadr ) ) {
 315+ # new behaviour: set this new emailaddr from login-page into user database record
 316+ $this->user->setEmail( $newadr );
 317+ # auto-authenticate it
 318+ $this->user->confirmEmail();
 319+ } else {
 320+ $error = wfMsg( 'invalidemailaddress' );
 321+ }
 322+ } else {
 323+ if( $wgEmailConfirmToEdit && empty( $newadr ) ) {
 324+ $this->mainPrefsForm( 'error', wfMsg( 'noemailtitle' ) );
 325+ return;
 326+ }
 327+ $this->user->setEmail( $this->mUserEmail );
 328+ }
 329+ if( $oldadr != $newadr ) {
 330+ wfRunHooks( 'PrefsEmailAudit', array( $this->user, $oldadr, $newadr ) );
 331+ }
 332+ }
 333+
 334+ if( !$wgAuth->updateExternalDB( $this->user ) ){
 335+ $this->mainPrefsForm( 'error', wfMsg( 'externaldberror' ) );
 336+ return;
 337+ }
 338+
 339+ $msg = '';
 340+ if ( !wfRunHooks( 'SavePreferences', array( $this, $this->user, &$msg, $oldOptions ) ) ) {
 341+ $this->mainPrefsForm( 'error', $msg );
 342+ return;
 343+ }
 344+
 345+ $this->user->saveSettings();
 346+
 347+ if( $needRedirect && $error === false ) {
 348+ $title = SpecialPage::getTitleFor( 'EditUser' );
 349+ $wgOut->redirect( $title->getFullURL( 'success' ) );
 350+ return;
 351+ }
 352+
 353+ $wgOut->parserOptions( ParserOptions::newFromUser( $this->user ) );
 354+ $this->mainPrefsForm( $error === false ? 'success' : 'error', $error);
 355+ }
 356+
 357+ /**
 358+ * @access private
 359+ */
 360+ function resetPrefs() {
 361+ global $wgUser, $wgLang, $wgContLang, $wgContLanguageCode, $wgAllowRealName;
 362+
 363+ $this->mNewpass = $this->mRetypePass = '';
 364+ $this->mUserEmail = $this->user->getEmail();
 365+ $this->mUserEmailAuthenticationtimestamp = $this->user->getEmailAuthenticationtimestamp();
 366+ $this->mRealName = ($wgAllowRealName) ? $this->user->getRealName() : '';
 367+
 368+ # language value might be blank, default to content language
 369+ $this->mUserLanguage = $this->user->getOption( 'language', $wgContLanguageCode );
 370+
 371+ $this->mUserVariant = $this->user->getOption( 'variant');
 372+ $this->mEmailFlag = $this->user->getOption( 'disablemail' ) == 1 ? 1 : 0;
 373+ $this->mNick = $this->user->getOption( 'nickname' );
 374+
 375+ $this->mQuickbar = $this->user->getOption( 'quickbar' );
 376+ $this->mSkin = Skin::normalizeKey( $this->user->getOption( 'skin' ) );
 377+ $this->mMath = $this->user->getOption( 'math' );
 378+ $this->mDate = $this->user->getDatePreference();
 379+ $this->mRows = $this->user->getOption( 'rows' );
 380+ $this->mCols = $this->user->getOption( 'cols' );
 381+ $this->mStubs = $this->user->getOption( 'stubthreshold' );
 382+ $this->mHourDiff = $this->user->getOption( 'timecorrection' );
 383+ $this->mSearch = $this->user->getOption( 'searchlimit' );
 384+ $this->mSearchLines = $this->user->getOption( 'contextlines' );
 385+ $this->mSearchChars = $this->user->getOption( 'contextchars' );
 386+ $this->mImageSize = $this->user->getOption( 'imagesize' );
 387+ $this->mThumbSize = $this->user->getOption( 'thumbsize' );
 388+ $this->mRecent = $this->user->getOption( 'rclimit' );
 389+ $this->mRecentDays = $this->user->getOption( 'rcdays' );
 390+ $this->mWatchlistEdits = $this->user->getOption( 'wllimit' );
 391+ $this->mUnderline = $this->user->getOption( 'underline' );
 392+ $this->mWatchlistDays = $this->user->getOption( 'watchlistdays' );
 393+ $this->mUseAjaxSearch = $this->user->getBoolOption( 'ajaxsearch' );
 394+ $this->mDisableMWSuggest = $this->user->getBoolOption( 'disablesuggest' );
 395+
 396+ $togs = User::getToggles();
 397+ foreach ( $togs as $tname ) {
 398+ $this->mToggles[$tname] = $this->user->getOption( $tname );
 399+ }
 400+
 401+ $namespaces = $wgContLang->getNamespaces();
 402+ foreach ( $namespaces as $i => $namespace ) {
 403+ if ( $i >= NS_MAIN ) {
 404+ $this->mSearchNs[$i] = $this->user->getOption( 'searchNs'.$i );
 405+ }
 406+ }
 407+
 408+ wfRunHooks( 'ResetPreferences', array( $this, $this->user ) );
 409+ }
 410+
 411+ /**
 412+ * @access private
 413+ */
 414+ function namespacesCheckboxes() {
 415+ global $wgContLang;
 416+
 417+ # Determine namespace checkboxes
 418+ $namespaces = $wgContLang->getNamespaces();
 419+ $r1 = null;
 420+
 421+ foreach ( $namespaces as $i => $name ) {
 422+ if ($i < 0)
 423+ continue;
 424+ $checked = $this->mSearchNs[$i] ? "checked='checked'" : '';
 425+ $name = str_replace( '_', ' ', $namespaces[$i] );
 426+
 427+ if ( empty($name) )
 428+ $name = wfMsg( 'blanknamespace' );
 429+
 430+ $r1 .= "<input type='checkbox' value='1' name='wpNs$i' id='wpNs$i' {$checked}/> <label for='wpNs$i'>{$name}</label><br />\n";
 431+ }
 432+ return $r1;
 433+ }
 434+
 435+
 436+ function getToggle( $tname, $trailer = false, $disabled = false ) {
 437+ global $wgUser, $wgLang;
 438+
 439+ $this->mUsedToggles[$tname] = true;
 440+ $ttext = $wgLang->getUserToggle( $tname );
 441+
 442+ $checked = $this->user->getOption( $tname ) == 1 ? ' checked="checked"' : '';
 443+ $disabled = $disabled ? ' disabled="disabled"' : '';
 444+ $trailer = $trailer ? $trailer : '';
 445+ return "<div class='toggle'><input type='checkbox' value='1' id=\"$tname\" name=\"wpOp$tname\"$checked$disabled />" .
 446+ " <span class='toggletext'><label for=\"$tname\">$ttext</label>$trailer</span></div>\n";
 447+ }
 448+
 449+ function getToggles( $items ) {
 450+ $out = "";
 451+ foreach( $items as $item ) {
 452+ if( $item === false )
 453+ continue;
 454+ if( is_array( $item ) ) {
 455+ list( $key, $trailer ) = $item;
 456+ } else {
 457+ $key = $item;
 458+ $trailer = false;
 459+ }
 460+ $out .= $this->getToggle( $key, $trailer );
 461+ }
 462+ return $out;
 463+ }
 464+
 465+ function addRow($td1, $td2) {
 466+ return "<tr><td class='mw-label'>$td1</td><td class='mw-input'>$td2</td></tr>";
 467+ }
 468+
 469+ /**
 470+ * Helper function for user information panel
 471+ * @param $td1 label for an item
 472+ * @param $td2 item or null
 473+ * @param $td3 optional help or null
 474+ * @return xhtml block
 475+ */
 476+ function tableRow( $td1, $td2 = null, $td3 = null ) {
 477+
 478+ if ( is_null( $td3 ) ) {
 479+ $td3 = '';
 480+ } else {
 481+ $td3 = Xml::tags( 'tr', null,
 482+ Xml::tags( 'td', array( 'class' => 'pref-label', 'colspan' => '2' ), $td3 )
 483+ );
 484+ }
 485+
 486+ if ( is_null( $td2 ) ) {
 487+ $td1 = Xml::tags( 'td', array( 'class' => 'pref-label', 'colspan' => '2' ), $td1 );
 488+ $td2 = '';
 489+ } else {
 490+ $td1 = Xml::tags( 'td', array( 'class' => 'pref-label' ), $td1 );
 491+ $td2 = Xml::tags( 'td', array( 'class' => 'pref-input' ), $td2 );
 492+ }
 493+
 494+ return Xml::tags( 'tr', null, $td1 . $td2 ). $td3 . "\n";
 495+
 496+ }
 497+
 498+ /**
 499+ * @access private
 500+ */
 501+ function mainPrefsForm( $status , $message = '' ) {
 502+ global $wgUser, $wgOut, $wgLang, $wgContLang;
 503+ global $wgAllowRealName, $wgImageLimits, $wgThumbLimits;
 504+ global $wgDisableLangConversion;
 505+ global $wgEnotifWatchlist, $wgEnotifUserTalk,$wgEnotifMinorEdits;
 506+ global $wgRCShowWatchingUsers, $wgEnotifRevealEditorAddress;
 507+ global $wgEnableEmail, $wgEnableUserEmail, $wgEmailAuthentication;
 508+ global $wgContLanguageCode, $wgDefaultSkin, $wgSkipSkins, $wgAuth;
 509+ global $wgEmailConfirmToEdit, $wgAjaxSearch, $wgEnableMWSuggest;
 510+
 511+ $wgOut->addScriptFile( 'prefs.js' );
 512+
 513+ $wgOut->disallowUserJs(); # Prevent hijacked user scripts from sniffing passwords etc.
 514+
 515+ if ( $this->mSuccess || 'success' == $status ) {
 516+ $wgOut->wrapWikiMsg( '<div class="successbox"><strong>$1</strong></div>', 'savedprefs' );
 517+ } else if ( 'error' == $status ) {
 518+ $wgOut->addWikiText( '<div class="errorbox"><strong>' . $message . '</strong></div>' );
 519+ } else if ( '' != $status ) {
 520+ $wgOut->addWikiText( $message . "\n----" );
 521+ }
 522+
 523+ $qbs = $wgLang->getQuickbarSettings();
 524+ $skinNames = $wgLang->getSkinNames();
 525+ $mathopts = $wgLang->getMathNames();
 526+ $dateopts = $wgLang->getDatePreferences();
 527+ $togs = User::getToggles();
 528+
 529+ $titleObj = SpecialPage::getTitleFor( 'EditUser' );
 530+
 531+ # Pre-expire some toggles so they won't show if disabled
 532+ $this->mUsedToggles[ 'shownumberswatching' ] = true;
 533+ $this->mUsedToggles[ 'showupdated' ] = true;
 534+ $this->mUsedToggles[ 'enotifwatchlistpages' ] = true;
 535+ $this->mUsedToggles[ 'enotifusertalkpages' ] = true;
 536+ $this->mUsedToggles[ 'enotifminoredits' ] = true;
 537+ $this->mUsedToggles[ 'enotifrevealaddr' ] = true;
 538+ $this->mUsedToggles[ 'ccmeonemails' ] = true;
 539+ $this->mUsedToggles[ 'uselivepreview' ] = true;
 540+
 541+
 542+ if ( !$this->mEmailFlag ) { $emfc = 'checked="checked"'; }
 543+ else { $emfc = ''; }
 544+
 545+
 546+ if ($wgEmailAuthentication && ($this->mUserEmail != '') ) {
 547+ if( $this->user->getEmailAuthenticationTimestamp() ) {
 548+ $emailauthenticated = wfMsg('emailauthenticated',$wgLang->timeanddate($this->user->getEmailAuthenticationTimestamp(), true ) ).'<br />';
 549+ $disableEmailPrefs = false;
 550+ } else {
 551+ $disableEmailPrefs = true;
 552+ $skin = $this->user->getSkin();
 553+ $emailauthenticated = wfMsg('emailnotauthenticated').'<br />' .
 554+ $skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Confirmemail' ),
 555+ wfMsg( 'emailconfirmlink' ) ) . '<br />';
 556+ }
 557+ } else {
 558+ $emailauthenticated = '';
 559+ $disableEmailPrefs = false;
 560+ }
 561+
 562+ if ($this->mUserEmail == '') {
 563+ $emailauthenticated = wfMsg( 'noemailprefs' ) . '<br />';
 564+ }
 565+
 566+ $ps = $this->namespacesCheckboxes();
 567+
 568+ $enotifwatchlistpages = ($wgEnotifWatchlist) ? $this->getToggle( 'enotifwatchlistpages', false, $disableEmailPrefs ) : '';
 569+ $enotifusertalkpages = ($wgEnotifUserTalk) ? $this->getToggle( 'enotifusertalkpages', false, $disableEmailPrefs ) : '';
 570+ $enotifminoredits = ($wgEnotifWatchlist && $wgEnotifMinorEdits) ? $this->getToggle( 'enotifminoredits', false, $disableEmailPrefs ) : '';
 571+ $enotifrevealaddr = (($wgEnotifWatchlist || $wgEnotifUserTalk) && $wgEnotifRevealEditorAddress) ? $this->getToggle( 'enotifrevealaddr', false, $disableEmailPrefs ) : '';
 572+
 573+ # </FIXME>
 574+
 575+ $wgOut->addHTML(
 576+ Xml::openElement( 'form', array(
 577+ 'action' => $titleObj->getLocalUrl(),
 578+ 'method' => 'post',
 579+ 'id' => 'mw-preferences-form',
 580+ ) ) .
 581+ Xml::openElement( 'div', array( 'id' => 'preferences' ) )
 582+ );
 583+
 584+ # User data
 585+
 586+ $wgOut->addHTML(
 587+ Xml::fieldset( wfMsg('prefs-personal') ) .
 588+ Xml::openElement( 'table' ) .
 589+ $this->tableRow( Xml::element( 'h2', null, wfMsg( 'prefs-personal' ) ) )
 590+ );
 591+
 592+ # Get groups to which the user belongs
 593+ $userEffectiveGroups = $this->user->getEffectiveGroups();
 594+ $userEffectiveGroupsArray = array();
 595+ foreach( $userEffectiveGroups as $ueg ) {
 596+ if( $ueg == '*' ) {
 597+ // Skip the default * group, seems useless here
 598+ continue;
 599+ }
 600+ $userEffectiveGroupsArray[] = User::makeGroupLinkHTML( $ueg );
 601+ }
 602+ asort( $userEffectiveGroupsArray );
 603+
 604+ $sk = $this->user->getSkin();
 605+ $toolLinks = array();
 606+ $toolLinks[] = $sk->makeKnownLinkObj( SpecialPage::getTitleFor( 'ListGroupRights' ), wfMsg( 'listgrouprights' ) );
 607+ # At the moment one tool link only but be prepared for the future...
 608+ # FIXME: Add a link to Special:Userrights for users who are allowed to use it.
 609+ # $wgUser->isAllowed( 'userrights' ) seems to strict in some cases
 610+
 611+ $userInformationHtml =
 612+ $this->tableRow( wfMsgHtml( 'username' ), htmlspecialchars( $this->user->getName() ) ) .
 613+ $this->tableRow( wfMsgHtml( 'uid' ), htmlspecialchars( $this->user->getId() ) ) .
 614+
 615+ $this->tableRow(
 616+ wfMsgExt( 'prefs-memberingroups', array( 'parseinline' ), count( $userEffectiveGroupsArray ) ),
 617+ implode( wfMsg( 'comma-separator' ), $userEffectiveGroupsArray ) .
 618+ '<br />(' . implode( ' | ', $toolLinks ) . ')'
 619+ ) .
 620+
 621+ $this->tableRow(
 622+ wfMsgHtml( 'prefs-edits' ),
 623+ $wgLang->formatNum( User::edits( $this->user->getId() ) )
 624+ );
 625+
 626+ if( wfRunHooks( 'PreferencesUserInformationPanel', array( $this, &$userInformationHtml ) ) ) {
 627+ $wgOut->addHtml( $userInformationHtml );
 628+ }
 629+
 630+ if ( $wgAllowRealName ) {
 631+ $wgOut->addHTML(
 632+ $this->tableRow(
 633+ Xml::label( wfMsg('yourrealname'), 'wpRealName' ),
 634+ Xml::input( 'wpRealName', 25, $this->mRealName, array( 'id' => 'wpRealName' ) ),
 635+ Xml::tags('div', array( 'class' => 'prefsectiontip' ),
 636+ wfMsgExt( 'prefs-help-realname', 'parseinline' )
 637+ )
 638+ )
 639+ );
 640+ }
 641+ if ( $wgEnableEmail ) {
 642+ $wgOut->addHTML(
 643+ $this->tableRow(
 644+ Xml::label( wfMsg('youremail'), 'wpUserEmail' ),
 645+ Xml::input( 'wpUserEmail', 25, $this->mUserEmail, array( 'id' => 'wpUserEmail' ) ),
 646+ Xml::tags('div', array( 'class' => 'prefsectiontip' ),
 647+ wfMsgExt( $wgEmailConfirmToEdit ? 'prefs-help-email-required' : 'prefs-help-email', 'parseinline' )
 648+ )
 649+ )
 650+ );
 651+ }
 652+
 653+ global $wgParser, $wgMaxSigChars;
 654+ if( mb_strlen( $this->mNick ) > $wgMaxSigChars ) {
 655+ $invalidSig = $this->tableRow(
 656+ '&nbsp;',
 657+ Xml::element( 'span', array( 'class' => 'error' ),
 658+ wfMsgExt( 'badsiglength', 'parsemag', $wgLang->formatNum( $wgMaxSigChars ) ) )
 659+ );
 660+ } elseif( !empty( $this->mToggles['fancysig'] ) &&
 661+ false === $wgParser->validateSig( $this->mNick ) ) {
 662+ $invalidSig = $this->tableRow(
 663+ '&nbsp;',
 664+ Xml::element( 'span', array( 'class' => 'error' ), wfMsg( 'badsig' ) )
 665+ );
 666+ } else {
 667+ $invalidSig = '';
 668+ }
 669+
 670+ $wgOut->addHTML(
 671+ $this->tableRow(
 672+ Xml::label( wfMsg( 'yournick' ), 'wpNick' ),
 673+ Xml::input( 'wpNick', 25, $this->mNick,
 674+ array(
 675+ 'id' => 'wpNick',
 676+ // Note: $wgMaxSigChars is enforced in Unicode characters,
 677+ // both on the backend and now in the browser.
 678+ // Badly-behaved requests may still try to submit
 679+ // an overlong string, however.
 680+ 'maxlength' => $wgMaxSigChars ) )
 681+ ) .
 682+ $invalidSig .
 683+ $this->tableRow( '&nbsp;', $this->getToggle( 'fancysig' ) )
 684+ );
 685+
 686+ list( $lsLabel, $lsSelect) = Xml::languageSelector( $this->mUserLanguage );
 687+ $wgOut->addHTML(
 688+ $this->tableRow( $lsLabel, $lsSelect )
 689+ );
 690+
 691+ /* see if there are multiple language variants to choose from*/
 692+ if(!$wgDisableLangConversion) {
 693+ $variants = $wgContLang->getVariants();
 694+ $variantArray = array();
 695+
 696+ $languages = Language::getLanguageNames( true );
 697+ foreach($variants as $v) {
 698+ $v = str_replace( '_', '-', strtolower($v));
 699+ if( array_key_exists( $v, $languages ) ) {
 700+ // If it doesn't have a name, we'll pretend it doesn't exist
 701+ $variantArray[$v] = $languages[$v];
 702+ }
 703+ }
 704+
 705+ $options = "\n";
 706+ foreach( $variantArray as $code => $name ) {
 707+ $selected = ($code == $this->mUserVariant);
 708+ $options .= Xml::option( "$code - $name", $code, $selected ) . "\n";
 709+ }
 710+
 711+ if(count($variantArray) > 1) {
 712+ $wgOut->addHtml(
 713+ $this->tableRow(
 714+ Xml::label( wfMsg( 'yourvariant' ), 'wpUserVariant' ),
 715+ Xml::tags( 'select',
 716+ array( 'name' => 'wpUserVariant', 'id' => 'wpUserVariant' ),
 717+ $options
 718+ )
 719+ )
 720+ );
 721+ }
 722+ }
 723+
 724+ # Password
 725+ if( $wgAuth->allowPasswordChange() ) {
 726+ $wgOut->addHTML(
 727+ $this->tableRow( Xml::element( 'h2', null, wfMsg( 'changepassword' ) ) ) .
 728+ $this->tableRow(
 729+ Xml::label( wfMsg( 'newpassword' ), 'wpNewpass' ),
 730+ Xml::password( 'wpNewpass', 25, $this->mNewpass, array( 'id' => 'wpNewpass' ) )
 731+ ) .
 732+ $this->tableRow(
 733+ Xml::label( wfMsg( 'retypenew' ), 'wpRetypePass' ),
 734+ Xml::password( 'wpRetypePass', 25, $this->mRetypePass, array( 'id' => 'wpRetypePass' ) )
 735+ ) .
 736+ Xml::tags( 'tr', null,
 737+ Xml::tags( 'td', array( 'colspan' => '2' ),
 738+ $this->getToggle( "rememberpassword" )
 739+ )
 740+ )
 741+ );
 742+ }
 743+
 744+ # <FIXME>
 745+ # Enotif
 746+ if ( $wgEnableEmail ) {
 747+
 748+ $moreEmail = '';
 749+ if ($wgEnableUserEmail) {
 750+ // fixme -- the "allowemail" pseudotoggle is a hacked-together
 751+ // inversion for the "disableemail" preference.
 752+ $emf = wfMsg( 'allowemail' );
 753+ $disabled = $disableEmailPrefs ? ' disabled="disabled"' : '';
 754+ $moreEmail =
 755+ "<input type='checkbox' $emfc $disabled value='1' name='wpEmailFlag' id='wpEmailFlag' /> <label for='wpEmailFlag'>$emf</label>" .
 756+ $this->getToggle( 'ccmeonemails', '', $disableEmailPrefs );
 757+ }
 758+
 759+
 760+ $wgOut->addHTML(
 761+ $this->tableRow( Xml::element( 'h2', null, wfMsg( 'email' ) ) ) .
 762+ $this->tableRow(
 763+ $emailauthenticated.
 764+ $enotifrevealaddr.
 765+ $enotifwatchlistpages.
 766+ $enotifusertalkpages.
 767+ $enotifminoredits.
 768+ $moreEmail
 769+ )
 770+ );
 771+ }
 772+ # </FIXME>
 773+
 774+ $wgOut->addHTML(
 775+ Xml::closeElement( 'table' ) .
 776+ Xml::closeElement( 'fieldset' )
 777+ );
 778+
 779+
 780+ # Quickbar
 781+ #
 782+ if ($this->mSkin == 'cologneblue' || $this->mSkin == 'standard') {
 783+ $wgOut->addHtml( "<fieldset>\n<legend>" . wfMsg( 'qbsettings' ) . "</legend>\n" );
 784+ for ( $i = 0; $i < count( $qbs ); ++$i ) {
 785+ if ( $i == $this->mQuickbar ) { $checked = ' checked="checked"'; }
 786+ else { $checked = ""; }
 787+ $wgOut->addHTML( "<div><label><input type='radio' name='wpQuickbar' value=\"$i\"$checked />{$qbs[$i]}</label></div>\n" );
 788+ }
 789+ $wgOut->addHtml( "</fieldset>\n\n" );
 790+ } else {
 791+ # Need to output a hidden option even if the relevant skin is not in use,
 792+ # otherwise the preference will get reset to 0 on submit
 793+ $wgOut->addHtml( wfHidden( 'wpQuickbar', $this->mQuickbar ) );
 794+ }
 795+
 796+ # Skin
 797+ #
 798+ $wgOut->addHTML( "<fieldset>\n<legend>\n" . wfMsg('skin') . "</legend>\n" );
 799+ $mptitle = Title::newMainPage();
 800+ $previewtext = wfMsg('skinpreview');
 801+ # Only show members of Skin::getSkinNames() rather than
 802+ # $skinNames (skins is all skin names from Language.php)
 803+ $validSkinNames = Skin::getSkinNames();
 804+ # Sort by UI skin name. First though need to update validSkinNames as sometimes
 805+ # the skinkey & UI skinname differ (e.g. "standard" skinkey is "Classic" in the UI).
 806+ foreach ($validSkinNames as $skinkey => & $skinname ) {
 807+ if ( isset( $skinNames[$skinkey] ) ) {
 808+ $skinname = $skinNames[$skinkey];
 809+ }
 810+ }
 811+ asort($validSkinNames);
 812+ foreach ($validSkinNames as $skinkey => $sn ) {
 813+ if ( in_array( $skinkey, $wgSkipSkins ) ) {
 814+ continue;
 815+ }
 816+ $checked = $skinkey == $this->mSkin ? ' checked="checked"' : '';
 817+
 818+ $mplink = htmlspecialchars($mptitle->getLocalURL("useskin=$skinkey"));
 819+ $previewlink = "<a target='_blank' href=\"$mplink\">$previewtext</a>";
 820+ if( $skinkey == $wgDefaultSkin )
 821+ $sn .= ' (' . wfMsg( 'default' ) . ')';
 822+ $wgOut->addHTML( "<input type='radio' name='wpSkin' id=\"wpSkin$skinkey\" value=\"$skinkey\"$checked /> <label for=\"wpSkin$skinkey\">{$sn}</label> $previewlink<br />\n" );
 823+ }
 824+ $wgOut->addHTML( "</fieldset>\n\n" );
 825+
 826+ # Math
 827+ #
 828+ global $wgUseTeX;
 829+ if( $wgUseTeX ) {
 830+ $wgOut->addHTML( "<fieldset>\n<legend>" . wfMsg('math') . '</legend>' );
 831+ foreach ( $mathopts as $k => $v ) {
 832+ $checked = ($k == $this->mMath);
 833+ $wgOut->addHTML(
 834+ Xml::openElement( 'div' ) .
 835+ Xml::radioLabel( wfMsg( $v ), 'wpMath', $k, "mw-sp-math-$k", $checked ) .
 836+ Xml::closeElement( 'div' ) . "\n"
 837+ );
 838+ }
 839+ $wgOut->addHTML( "</fieldset>\n\n" );
 840+ }
 841+
 842+ # Files
 843+ #
 844+ $wgOut->addHTML(
 845+ "<fieldset>\n" . Xml::element( 'legend', null, wfMsg( 'files' ) ) . "\n"
 846+ );
 847+
 848+ $imageLimitOptions = null;
 849+ foreach ( $wgImageLimits as $index => $limits ) {
 850+ $selected = ($index == $this->mImageSize);
 851+ $imageLimitOptions .= Xml::option( "{$limits[0]}×{$limits[1]}" .
 852+ wfMsg('unit-pixel'), $index, $selected );
 853+ }
 854+
 855+ $imageSizeId = 'wpImageSize';
 856+ $wgOut->addHTML(
 857+ "<div>" . Xml::label( wfMsg('imagemaxsize'), $imageSizeId ) . " " .
 858+ Xml::openElement( 'select', array( 'name' => $imageSizeId, 'id' => $imageSizeId ) ) .
 859+ $imageLimitOptions .
 860+ Xml::closeElement( 'select' ) . "</div>\n"
 861+ );
 862+
 863+ $imageThumbOptions = null;
 864+ foreach ( $wgThumbLimits as $index => $size ) {
 865+ $selected = ($index == $this->mThumbSize);
 866+ $imageThumbOptions .= Xml::option($size . wfMsg('unit-pixel'), $index,
 867+ $selected);
 868+ }
 869+
 870+ $thumbSizeId = 'wpThumbSize';
 871+ $wgOut->addHTML(
 872+ "<div>" . Xml::label( wfMsg('thumbsize'), $thumbSizeId ) . " " .
 873+ Xml::openElement( 'select', array( 'name' => $thumbSizeId, 'id' => $thumbSizeId ) ) .
 874+ $imageThumbOptions .
 875+ Xml::closeElement( 'select' ) . "</div>\n"
 876+ );
 877+
 878+ $wgOut->addHTML( "</fieldset>\n\n" );
 879+
 880+ # Date format
 881+ #
 882+ # Date/Time
 883+ #
 884+
 885+ $wgOut->addHTML(
 886+ Xml::openElement( 'fieldset' ) .
 887+ Xml::element( 'legend', null, wfMsg( 'datetime' ) ) . "\n"
 888+ );
 889+
 890+ if ($dateopts) {
 891+ $wgOut->addHTML(
 892+ Xml::openElement( 'fieldset' ) .
 893+ Xml::element( 'legend', null, wfMsg( 'dateformat' ) ) . "\n"
 894+ );
 895+ $idCnt = 0;
 896+ $epoch = '20010115161234'; # Wikipedia day
 897+ foreach( $dateopts as $key ) {
 898+ if( $key == 'default' ) {
 899+ $formatted = wfMsg( 'datedefault' );
 900+ } else {
 901+ $formatted = $wgLang->timeanddate( $epoch, false, $key );
 902+ }
 903+ $wgOut->addHTML(
 904+ Xml::tags( 'div', null,
 905+ Xml::radioLabel( $formatted, 'wpDate', $key, "wpDate$idCnt", $key == $this->mDate )
 906+ ) . "\n"
 907+ );
 908+ $idCnt++;
 909+ }
 910+ $wgOut->addHTML( Xml::closeElement( 'fieldset' ) . "\n" );
 911+ }
 912+
 913+ $nowlocal = $wgLang->time( $now = wfTimestampNow(), true );
 914+ $nowserver = $wgLang->time( $now, false );
 915+
 916+ $wgOut->addHTML(
 917+ Xml::openElement( 'fieldset' ) .
 918+ Xml::element( 'legend', null, wfMsg( 'timezonelegend' ) ) .
 919+ Xml::openElement( 'table' ) .
 920+ $this->addRow( wfMsg( 'servertime' ), $nowserver ) .
 921+ $this->addRow( wfMsg( 'localtime' ), $nowlocal ) .
 922+ $this->addRow(
 923+ Xml::label( wfMsg( 'timezoneoffset' ), 'wpHourDiff' ),
 924+ Xml::input( 'wpHourDiff', 6, $this->mHourDiff, array( 'id' => 'wpHourDiff' ) ) ) .
 925+ "<tr>
 926+ <td></td>
 927+ <td class='mw-submit'>" .
 928+ Xml::element( 'input',
 929+ array( 'type' => 'button',
 930+ 'value' => wfMsg( 'guesstimezone' ),
 931+ 'onclick' => 'javascript:guessTimezone()',
 932+ 'id' => 'guesstimezonebutton',
 933+ 'style' => 'display:none;' ) ) .
 934+ "</td>
 935+ </tr>" .
 936+ Xml::closeElement( 'table' ) .
 937+ Xml::tags( 'div', array( 'class' => 'prefsectiontip' ), wfMsgExt( 'timezonetext', 'parseinline' ) ).
 938+ Xml::closeElement( 'fieldset' ) .
 939+ Xml::closeElement( 'fieldset' ) . "\n\n"
 940+ );
 941+
 942+ # Editing
 943+ #
 944+ global $wgLivePreview;
 945+ $wgOut->addHTML( '<fieldset><legend>' . wfMsg( 'textboxsize' ) . '</legend>
 946+ <div>' .
 947+ wfInputLabel( wfMsg( 'rows' ), 'wpRows', 'wpRows', 3, $this->mRows ) .
 948+ ' ' .
 949+ wfInputLabel( wfMsg( 'columns' ), 'wpCols', 'wpCols', 3, $this->mCols ) .
 950+ "</div>" .
 951+ $this->getToggles( array(
 952+ 'editsection',
 953+ 'editsectiononrightclick',
 954+ 'editondblclick',
 955+ 'editwidth',
 956+ 'showtoolbar',
 957+ 'previewonfirst',
 958+ 'previewontop',
 959+ 'minordefault',
 960+ 'externaleditor',
 961+ 'externaldiff',
 962+ $wgLivePreview ? 'uselivepreview' : false,
 963+ 'forceeditsummary',
 964+ ) ) . '</fieldset>'
 965+ );
 966+
 967+ # Recent changes
 968+ $wgOut->addHtml( '<fieldset><legend>' . wfMsgHtml( 'prefs-rc' ) . '</legend>' );
 969+
 970+ $rc = '<table><tr>';
 971+ $rc .= '<td>' . Xml::label( wfMsg( 'recentchangesdays' ), 'wpRecentDays' ) . '</td>';
 972+ $rc .= '<td>' . Xml::input( 'wpRecentDays', 3, $this->mRecentDays, array( 'id' => 'wpRecentDays' ) ) . '</td>';
 973+ $rc .= '</tr><tr>';
 974+ $rc .= '<td>' . Xml::label( wfMsg( 'recentchangescount' ), 'wpRecent' ) . '</td>';
 975+ $rc .= '<td>' . Xml::input( 'wpRecent', 3, $this->mRecent, array( 'id' => 'wpRecent' ) ) . '</td>';
 976+ $rc .= '</tr></table>';
 977+ $wgOut->addHtml( $rc );
 978+
 979+ $wgOut->addHtml( '<br />' );
 980+
 981+ $toggles[] = 'hideminor';
 982+ if( $wgRCShowWatchingUsers )
 983+ $toggles[] = 'shownumberswatching';
 984+ $toggles[] = 'usenewrc';
 985+ $wgOut->addHtml( $this->getToggles( $toggles ) );
 986+
 987+ $wgOut->addHtml( '</fieldset>' );
 988+
 989+ # Watchlist
 990+ $wgOut->addHtml( '<fieldset><legend>' . wfMsgHtml( 'prefs-watchlist' ) . '</legend>' );
 991+
 992+ $wgOut->addHtml( wfInputLabel( wfMsg( 'prefs-watchlist-days' ), 'wpWatchlistDays', 'wpWatchlistDays', 3, $this->mWatchlistDays ) );
 993+ $wgOut->addHtml( '<br /><br />' );
 994+
 995+ $wgOut->addHtml( $this->getToggle( 'extendwatchlist' ) );
 996+ $wgOut->addHtml( wfInputLabel( wfMsg( 'prefs-watchlist-edits' ), 'wpWatchlistEdits', 'wpWatchlistEdits', 3, $this->mWatchlistEdits ) );
 997+ $wgOut->addHtml( '<br /><br />' );
 998+
 999+ $wgOut->addHtml( $this->getToggles( array( 'watchlisthideown', 'watchlisthidebots', 'watchlisthideminor' ) ) );
 1000+
 1001+ if( $this->user->isAllowed( 'createpage' ) || $this->user->isAllowed( 'createtalk' ) )
 1002+ $wgOut->addHtml( $this->getToggle( 'watchcreations' ) );
 1003+ foreach( array( 'edit' => 'watchdefault', 'move' => 'watchmoves', 'delete' => 'watchdeletion' ) as $action => $toggle ) {
 1004+ if( $this->user->isAllowed( $action ) )
 1005+ $wgOut->addHtml( $this->getToggle( $toggle ) );
 1006+ }
 1007+ $this->mUsedToggles['watchcreations'] = true;
 1008+ $this->mUsedToggles['watchdefault'] = true;
 1009+ $this->mUsedToggles['watchmoves'] = true;
 1010+ $this->mUsedToggles['watchdeletion'] = true;
 1011+
 1012+ $wgOut->addHtml( '</fieldset>' );
 1013+
 1014+ # Search
 1015+ $ajaxsearch = $wgAjaxSearch ?
 1016+ $this->addRow(
 1017+ Xml::label( wfMsg( 'useajaxsearch' ), 'wpUseAjaxSearch' ),
 1018+ Xml::check( 'wpUseAjaxSearch', $this->mUseAjaxSearch, array( 'id' => 'wpUseAjaxSearch' ) )
 1019+ ) : '';
 1020+ $mwsuggest = $wgEnableMWSuggest ?
 1021+ $this->addRow(
 1022+ Xml::label( wfMsg( 'mwsuggest-disable' ), 'wpDisableMWSuggest' ),
 1023+ Xml::check( 'wpDisableMWSuggest', $this->mDisableMWSuggest, array( 'id' => 'wpDisableMWSuggest' ) )
 1024+ ) : '';
 1025+ $wgOut->addHTML(
 1026+ // Elements for the search tab itself
 1027+ Xml::openElement( 'fieldset' ) .
 1028+ Xml::element( 'legend', null, wfMsg( 'searchresultshead' ) ) .
 1029+ // Elements for the search options in the search tab
 1030+ Xml::openElement( 'fieldset' ) .
 1031+ Xml::element( 'legend', null, wfMsg( 'prefs-searchoptions' ) ) .
 1032+ Xml::openElement( 'table' ) .
 1033+ $ajaxsearch .
 1034+ $this->addRow(
 1035+ Xml::label( wfMsg( 'resultsperpage' ), 'wpSearch' ),
 1036+ Xml::input( 'wpSearch', 4, $this->mSearch, array( 'id' => 'wpSearch' ) )
 1037+ ) .
 1038+ $this->addRow(
 1039+ Xml::label( wfMsg( 'contextlines' ), 'wpSearchLines' ),
 1040+ Xml::input( 'wpSearchLines', 4, $this->mSearchLines, array( 'id' => 'wpSearchLines' ) )
 1041+ ) .
 1042+ $this->addRow(
 1043+ Xml::label( wfMsg( 'contextchars' ), 'wpSearchChars' ),
 1044+ Xml::input( 'wpSearchChars', 4, $this->mSearchChars, array( 'id' => 'wpSearchChars' ) )
 1045+ ) .
 1046+ $mwsuggest .
 1047+ Xml::closeElement( 'table' ) .
 1048+ Xml::closeElement( 'fieldset' ) .
 1049+ // Elements for the namespace options in the search tab
 1050+ Xml::openElement( 'fieldset' ) .
 1051+ Xml::element( 'legend', null, wfMsg( 'prefs-namespaces' ) ) .
 1052+ wfMsgExt( 'defaultns', array( 'parse' ) ) .
 1053+ $ps .
 1054+ Xml::closeElement( 'fieldset' ) .
 1055+ // End of the search tab
 1056+ Xml::closeElement( 'fieldset' )
 1057+ );
 1058+
 1059+ # Misc
 1060+ #
 1061+ $wgOut->addHTML('<fieldset><legend>' . wfMsg('prefs-misc') . '</legend>');
 1062+ $wgOut->addHtml( '<label for="wpStubs">' . wfMsg( 'stub-threshold' ) . '</label>&nbsp;' );
 1063+ $wgOut->addHtml( Xml::input( 'wpStubs', 6, $this->mStubs, array( 'id' => 'wpStubs' ) ) );
 1064+ $msgUnderline = htmlspecialchars( wfMsg ( 'tog-underline' ) );
 1065+ $msgUnderlinenever = htmlspecialchars( wfMsg ( 'underline-never' ) );
 1066+ $msgUnderlinealways = htmlspecialchars( wfMsg ( 'underline-always' ) );
 1067+ $msgUnderlinedefault = htmlspecialchars( wfMsg ( 'underline-default' ) );
 1068+ $uopt = $this->user->getOption("underline");
 1069+ $s0 = $uopt == 0 ? ' selected="selected"' : '';
 1070+ $s1 = $uopt == 1 ? ' selected="selected"' : '';
 1071+ $s2 = $uopt == 2 ? ' selected="selected"' : '';
 1072+ $wgOut->addHTML("
 1073+<div class='toggle'><p><label for='wpOpunderline'>$msgUnderline</label>
 1074+<select name='wpOpunderline' id='wpOpunderline'>
 1075+<option value=\"0\"$s0>$msgUnderlinenever</option>
 1076+<option value=\"1\"$s1>$msgUnderlinealways</option>
 1077+<option value=\"2\"$s2>$msgUnderlinedefault</option>
 1078+</select></p></div>");
 1079+
 1080+ foreach ( $togs as $tname ) {
 1081+ if( !array_key_exists( $tname, $this->mUsedToggles ) ) {
 1082+ $wgOut->addHTML( $this->getToggle( $tname ) );
 1083+ }
 1084+ }
 1085+ $wgOut->addHTML( '</fieldset>' );
 1086+
 1087+ wfRunHooks( 'RenderPreferencesForm', array( $this, $wgOut ) );
 1088+
 1089+ $token = htmlspecialchars( $this->user->editToken() );
 1090+ $skin = $this->user->getSkin();
 1091+ $wgOut->addHTML( "
 1092+ <div id='prefsubmit'>
 1093+ <div>
 1094+ <input type='submit' name='wpSaveprefs' class='btnSavePrefs' value=\"" . wfMsgHtml( 'saveprefs' ) . '"'.$skin->tooltipAndAccesskey('save')." />
 1095+ <input type='submit' name='wpReset' value=\"" . wfMsgHtml( 'resetprefs' ) . "\" />
 1096+ </div>
 1097+
 1098+ </div>
 1099+
 1100+ <input type='hidden' name='wpEditToken' value=\"{$token}\" />
 1101+ </div></form>\n" );
 1102+
 1103+ $wgOut->addHtml( Xml::tags( 'div', array( 'class' => "prefcache" ),
 1104+ wfMsgExt( 'clearyourcache', 'parseinline' ) )
 1105+ );
 1106+ }
 1107+
 1108+ function makeSearchForm() {
 1109+ $thisTitle = Title::makeTitle( NS_SPECIAL, $this->getName() );
 1110+ $form = wfOpenElement( 'form', array( 'method' => 'post', 'action' => $thisTitle->getLocalUrl() ) );
 1111+ $form .= wfElement( 'label', array( 'for' => 'username' ), wfMsg( 'edituser-username' ) ) . ' ';
 1112+ $form .= wfElement( 'input', array( 'type' => 'text', 'name' => 'username', 'id' => 'username', 'value' => $this->target ) ) . ' ';
 1113+ $form .= wfElement( 'input', array( 'type' => 'submit', 'name' => 'dosearch', 'value' => wfMsg( 'edituser-dosearch' ) ) );
 1114+ $form .= wfElement( 'input', array( 'type' => 'hidden', 'name' => 'issearch', 'value' => '1' ) );
 1115+ $form .= wfCloseElement( 'form' );
 1116+ return $form;
 1117+ }
 1118+}
Property changes on: trunk/extensions/EditUser/1.13/EditUser_body.php
___________________________________________________________________
Added: svn:eol-style
11119 + native
Index: trunk/extensions/EditUser/1.14/EditUser_body.php
@@ -0,0 +1,1129 @@
 2+<?php
 3+/* Shamelessly copied and modified from /includes/specials/SpecialPreferences.php v1.14 */
 4+class EditUser extends SpecialPage {
 5+ var $mQuickbar, $mOldpass, $mNewpass, $mRetypePass, $mStubs;
 6+ var $mRows, $mCols, $mSkin, $mMath, $mDate, $mUserEmail, $mEmailFlag, $mNick;
 7+ var $mUserLanguage, $mUserVariant;
 8+ var $mSearch, $mRecent, $mRecentDays, $mHourDiff, $mSearchLines, $mSearchChars, $mAction;
 9+ var $mReset, $mPosted, $mToggles, $mSearchNs, $mRealName, $mImageSize;
 10+ var $mUnderline, $mWatchlistEdits;
 11+ var $user, $target;
 12+
 13+ function __construct() {
 14+ SpecialPage::SpecialPage('EditUser', 'edituser');
 15+ }
 16+ /**
 17+ * Constructor
 18+ * Load some values
 19+ */
 20+ function loadGlobals( $par ) {
 21+ global $wgContLang, $wgAllowRealName, $wgRequest;
 22+ $request = $wgRequest;
 23+ $this->user = User::newFromName($par);
 24+ $this->user->load();
 25+ $this->mQuickbar = $request->getVal( 'wpQuickbar' );
 26+ $this->mNewpass = $request->getVal( 'wpNewpass' );
 27+ $this->mRetypePass = $request->getVal( 'wpRetypePass' );
 28+ $this->mStubs = $request->getVal( 'wpStubs' );
 29+ $this->mRows = $request->getVal( 'wpRows' );
 30+ $this->mCols = $request->getVal( 'wpCols' );
 31+ $this->mSkin = $request->getVal( 'wpSkin' );
 32+ $this->mMath = $request->getVal( 'wpMath' );
 33+ $this->mDate = $request->getVal( 'wpDate' );
 34+ $this->mUserEmail = $request->getVal( 'wpUserEmail' );
 35+ $this->mRealName = $wgAllowRealName ? $request->getVal( 'wpRealName' ) : '';
 36+ $this->mEmailFlag = $request->getCheck( 'wpEmailFlag' ) ? 0 : 1;
 37+ $this->mNick = $request->getVal( 'wpNick' );
 38+ $this->mUserLanguage = $request->getVal( 'wpUserLanguage' );
 39+ $this->mUserVariant = $request->getVal( 'wpUserVariant' );
 40+ $this->mSearch = $request->getVal( 'wpSearch' );
 41+ $this->mRecent = $request->getVal( 'wpRecent' );
 42+ $this->mRecentDays = $request->getVal( 'wpRecentDays' );
 43+ $this->mHourDiff = $request->getVal( 'wpHourDiff' );
 44+ $this->mSearchLines = $request->getVal( 'wpSearchLines' );
 45+ $this->mSearchChars = $request->getVal( 'wpSearchChars' );
 46+ $this->mImageSize = $request->getVal( 'wpImageSize' );
 47+ $this->mThumbSize = $request->getInt( 'wpThumbSize' );
 48+ $this->mUnderline = $request->getInt( 'wpOpunderline' );
 49+ $this->mAction = $request->getVal( 'action' );
 50+ $this->mReset = $request->getCheck( 'wpReset' );
 51+ $this->mPosted = $request->wasPosted();
 52+ $this->mSuccess = $request->getCheck( 'success' );
 53+ $this->mWatchlistDays = $request->getVal( 'wpWatchlistDays' );
 54+ $this->mWatchlistEdits = $request->getVal( 'wpWatchlistEdits' );
 55+ $this->mDisableMWSuggest = $request->getCheck( 'wpDisableMWSuggest' );
 56+ $this->mSaveprefs = $request->getCheck( 'wpSaveprefs' ) &&
 57+ $this->mPosted &&
 58+ $this->user->matchEditToken( $request->getVal( 'wpEditToken' ) );
 59+
 60+ # User toggles (the big ugly unsorted list of checkboxes)
 61+ $this->mToggles = array();
 62+ if ( $this->mPosted ) {
 63+ $togs = User::getToggles();
 64+ foreach ( $togs as $tname ) {
 65+ $this->mToggles[$tname] = $request->getCheck( "wpOp$tname" ) ? 1 : 0;
 66+ }
 67+ }
 68+
 69+ $this->mUsedToggles = array();
 70+
 71+ # Search namespace options
 72+ # Note: namespaces don't necessarily have consecutive keys
 73+ $this->mSearchNs = array();
 74+ if ( $this->mPosted ) {
 75+ $namespaces = $wgContLang->getNamespaces();
 76+ foreach ( $namespaces as $i => $namespace ) {
 77+ if ( $i >= 0 ) {
 78+ $this->mSearchNs[$i] = $request->getCheck( "wpNs$i" ) ? 1 : 0;
 79+ }
 80+ }
 81+ }
 82+
 83+ # Validate language
 84+ if ( !preg_match( '/^[a-z\-]*$/', $this->mUserLanguage ) ) {
 85+ $this->mUserLanguage = 'nolanguage';
 86+ }
 87+
 88+ wfRunHooks( 'InitPreferencesForm', array( $this, $request ) );
 89+ }
 90+
 91+ public function execute( $par ) {
 92+ global $wgOut, $wgUser, $wgRequest;
 93+ if( !$wgUser->isAllowed( 'edituser' ) ) {
 94+ $wgOut->permissionRequired( 'edituser' );
 95+ return false;
 96+ }
 97+
 98+ wfLoadExtensionMessages( 'EditUser' );
 99+
 100+ $this->setHeaders();
 101+ $this->target = (isset($par)) ? $par : $wgRequest->getText('username', '');
 102+ if($this->target === '') {
 103+ $wgOut->addHtml($this->makeSearchForm());
 104+ return;
 105+ }
 106+ $targetuser = User::NewFromName( $this->target );
 107+ if( $targetuser->getID() == 0 ) {
 108+ $wgOut->addWikiText( wfMsg( 'edituser-nouser' ) );
 109+ return;
 110+ }
 111+ if( $targetuser->isAllowed('edituser-exempt') ) {
 112+ $wgOut->addWikiText( wfMsg( 'edituser-exempt' ) );
 113+ return;
 114+ }
 115+ $this->loadGlobals($this->target);
 116+ $wgOut->addHtml($this->makeSearchForm());
 117+ $wgOut->addHtml('<br />');
 118+ if ( wfReadOnly() ) {
 119+ $wgOut->readOnlyPage();
 120+ return;
 121+ }
 122+ if ( $this->mReset ) {
 123+ $this->resetPrefs();
 124+ $this->mainPrefsForm( 'reset', wfMsg( 'prefsreset' ) );
 125+ } else if ( $this->mSaveprefs ) {
 126+ $this->savePreferences();
 127+ } else {
 128+ $this->resetPrefs();
 129+ $this->mainPrefsForm( '' );
 130+ }
 131+ }
 132+ /**
 133+ * @access private
 134+ */
 135+ function validateInt( &$val, $min=0, $max=0x7fffffff ) {
 136+ $val = intval($val);
 137+ $val = min($val, $max);
 138+ $val = max($val, $min);
 139+ return $val;
 140+ }
 141+
 142+ /**
 143+ * @access private
 144+ */
 145+ function validateFloat( &$val, $min, $max=0x7fffffff ) {
 146+ $val = floatval( $val );
 147+ $val = min( $val, $max );
 148+ $val = max( $val, $min );
 149+ return( $val );
 150+ }
 151+
 152+ /**
 153+ * @access private
 154+ */
 155+ function validateIntOrNull( &$val, $min=0, $max=0x7fffffff ) {
 156+ $val = trim($val);
 157+ if($val === '') {
 158+ return null;
 159+ } else {
 160+ return $this->validateInt( $val, $min, $max );
 161+ }
 162+ }
 163+
 164+ /**
 165+ * @access private
 166+ */
 167+ function validateDate( $val ) {
 168+ global $wgLang, $wgContLang;
 169+ if ( $val !== false && (
 170+ in_array( $val, (array)$wgLang->getDatePreferences() ) ||
 171+ in_array( $val, (array)$wgContLang->getDatePreferences() ) ) )
 172+ {
 173+ return $val;
 174+ } else {
 175+ return $wgLang->getDefaultDateFormat();
 176+ }
 177+ }
 178+
 179+ /**
 180+ * Used to validate the user inputed timezone before saving it as
 181+ * 'timecorrection', will return '00:00' if fed bogus data.
 182+ * Note: It's not a 100% correct implementation timezone-wise, it will
 183+ * accept stuff like '14:30',
 184+ * @access private
 185+ * @param string $s the user input
 186+ * @return string
 187+ */
 188+ function validateTimeZone( $s ) {
 189+ if ( $s !== '' ) {
 190+ if ( strpos( $s, ':' ) ) {
 191+ # HH:MM
 192+ $array = explode( ':' , $s );
 193+ $hour = intval( $array[0] );
 194+ $minute = intval( $array[1] );
 195+ } else {
 196+ $minute = intval( $s * 60 );
 197+ $hour = intval( $minute / 60 );
 198+ $minute = abs( $minute ) % 60;
 199+ }
 200+ # Max is +14:00 and min is -12:00, see:
 201+ # http://en.wikipedia.org/wiki/Timezone
 202+ $hour = min( $hour, 14 );
 203+ $hour = max( $hour, -12 );
 204+ $minute = min( $minute, 59 );
 205+ $minute = max( $minute, 0 );
 206+ $s = sprintf( "%02d:%02d", $hour, $minute );
 207+ }
 208+ return $s;
 209+ }
 210+
 211+ /**
 212+ * @access private
 213+ */
 214+ function savePreferences() {
 215+ global $wgUser, $wgOut, $wgParser;
 216+ global $wgEnableUserEmail, $wgEnableEmail;
 217+ global $wgEmailAuthentication, $wgRCMaxAge;
 218+ global $wgAuth, $wgEmailConfirmToEdit;
 219+
 220+
 221+ if ( $this->mNewpass !== '' && $wgAuth->allowPasswordChange() ) {
 222+ if ( $this->mNewpass != $this->mRetypePass ) {
 223+ wfRunHooks( 'PrefsPasswordAudit', array( $this->user, $this->mNewpass, 'badretype' ) );
 224+ $this->mainPrefsForm( 'error', wfMsg( 'badretype' ) );
 225+ return;
 226+ }
 227+
 228+ try {
 229+ $this->user->setPassword( $this->mNewpass );
 230+ wfRunHooks( 'PrefsPasswordAudit', array( $this->user, $this->mNewpass, 'success' ) );
 231+ $this->mNewpass = $this->mOldpass = $this->mRetypePass = '';
 232+ } catch( PasswordError $e ) {
 233+ wfRunHooks( 'PrefsPasswordAudit', array( $this->user, $this->mNewpass, 'error' ) );
 234+ $this->mainPrefsForm( 'error', $e->getMessage() );
 235+ return;
 236+ }
 237+ }
 238+ $this->user->setRealName( $this->mRealName );
 239+ $oldOptions = $this->user->mOptions;
 240+
 241+ if( $this->user->getOption( 'language' ) !== $this->mUserLanguage ) {
 242+ $needRedirect = true;
 243+ } else {
 244+ $needRedirect = false;
 245+ }
 246+
 247+ # Validate the signature and clean it up as needed
 248+ global $wgMaxSigChars;
 249+ if( mb_strlen( $this->mNick ) > $wgMaxSigChars ) {
 250+ global $wgLang;
 251+ $this->mainPrefsForm( 'error',
 252+ wfMsgExt( 'badsiglength', 'parsemag', $wgLang->formatNum( $wgMaxSigChars ) ) );
 253+ return;
 254+ } elseif( $this->mToggles['fancysig'] ) {
 255+ if( $wgParser->validateSig( $this->mNick ) !== false ) {
 256+ $this->mNick = $wgParser->cleanSig( $this->mNick );
 257+ } else {
 258+ $this->mainPrefsForm( 'error', wfMsg( 'badsig' ) );
 259+ return;
 260+ }
 261+ } else {
 262+ // When no fancy sig used, make sure ~{3,5} get removed.
 263+ $this->mNick = $wgParser->cleanSigInSig( $this->mNick );
 264+ }
 265+
 266+ $this->user->setOption( 'language', $this->mUserLanguage );
 267+ $this->user->setOption( 'variant', $this->mUserVariant );
 268+ $this->user->setOption( 'nickname', $this->mNick );
 269+ $this->user->setOption( 'quickbar', $this->mQuickbar );
 270+ $this->user->setOption( 'skin', $this->mSkin );
 271+ global $wgUseTeX;
 272+ if( $wgUseTeX ) {
 273+ $this->user->setOption( 'math', $this->mMath );
 274+ }
 275+ $this->user->setOption( 'date', $this->validateDate( $this->mDate ) );
 276+ $this->user->setOption( 'searchlimit', $this->validateIntOrNull( $this->mSearch ) );
 277+ $this->user->setOption( 'contextlines', $this->validateIntOrNull( $this->mSearchLines ) );
 278+ $this->user->setOption( 'contextchars', $this->validateIntOrNull( $this->mSearchChars ) );
 279+ $this->user->setOption( 'rclimit', $this->validateIntOrNull( $this->mRecent ) );
 280+ $this->user->setOption( 'rcdays', $this->validateInt($this->mRecentDays, 1, ceil($wgRCMaxAge / (3600*24))));
 281+ $this->user->setOption( 'wllimit', $this->validateIntOrNull( $this->mWatchlistEdits, 0, 1000 ) );
 282+ $this->user->setOption( 'rows', $this->validateInt( $this->mRows, 4, 1000 ) );
 283+ $this->user->setOption( 'cols', $this->validateInt( $this->mCols, 4, 1000 ) );
 284+ $this->user->setOption( 'stubthreshold', $this->validateIntOrNull( $this->mStubs ) );
 285+ $this->user->setOption( 'timecorrection', $this->validateTimeZone( $this->mHourDiff, -12, 14 ) );
 286+ $this->user->setOption( 'imagesize', $this->mImageSize );
 287+ $this->user->setOption( 'thumbsize', $this->mThumbSize );
 288+ $this->user->setOption( 'underline', $this->validateInt($this->mUnderline, 0, 2) );
 289+ $this->user->setOption( 'watchlistdays', $this->validateFloat( $this->mWatchlistDays, 0, 7 ) );
 290+ $this->user->setOption( 'disablesuggest', $this->mDisableMWSuggest );
 291+
 292+ # Set search namespace options
 293+ foreach( $this->mSearchNs as $i => $value ) {
 294+ $this->user->setOption( "searchNs{$i}", $value );
 295+ }
 296+
 297+ if( $wgEnableEmail && $wgEnableUserEmail ) {
 298+ $this->user->setOption( 'disablemail', $this->mEmailFlag );
 299+ }
 300+
 301+ # Set user toggles
 302+ foreach ( $this->mToggles as $tname => $tvalue ) {
 303+ $this->user->setOption( $tname, $tvalue );
 304+ }
 305+
 306+ $error = false;
 307+ if( $wgEnableEmail ) {
 308+ $newadr = $this->mUserEmail;
 309+ $oldadr = $this->user->getEmail();
 310+ if( ($newadr != '') && ($newadr != $oldadr) ) {
 311+ # the user has supplied a new email address on the login page
 312+ if( $this->user->isValidEmailAddr( $newadr ) ) {
 313+ # new behaviour: set this new emailaddr from login-page into user database record
 314+ $this->user->setEmail( $newadr );
 315+ # auto-authenticate it
 316+ $this->user->confirmEmail();
 317+ } else {
 318+ $error = wfMsg( 'invalidemailaddress' );
 319+ }
 320+ } else {
 321+ if( $wgEmailConfirmToEdit && empty( $newadr ) ) {
 322+ $this->mainPrefsForm( 'error', wfMsg( 'noemailtitle' ) );
 323+ return;
 324+ }
 325+ $this->user->setEmail( $this->mUserEmail );
 326+ }
 327+ if( $oldadr != $newadr ) {
 328+ wfRunHooks( 'PrefsEmailAudit', array( $this->user, $oldadr, $newadr ) );
 329+ }
 330+ }
 331+
 332+ if( !$wgAuth->updateExternalDB( $this->user ) ){
 333+ $this->mainPrefsForm( 'error', wfMsg( 'externaldberror' ) );
 334+ return;
 335+ }
 336+
 337+ $msg = '';
 338+ if ( !wfRunHooks( 'SavePreferences', array( $this, $this->user, &$msg, $oldOptions ) ) ) {
 339+ $this->mainPrefsForm( 'error', $msg );
 340+ return;
 341+ }
 342+
 343+ $this->user->saveSettings();
 344+
 345+ if( $needRedirect && $error === false ) {
 346+ $title = SpecialPage::getTitleFor( 'EditUser' );
 347+ $wgOut->redirect( $title->getFullURL( 'success' ) );
 348+ return;
 349+ }
 350+
 351+ $wgOut->parserOptions( ParserOptions::newFromUser( $this->user ) );
 352+ $this->mainPrefsForm( $error === false ? 'success' : 'error', $error);
 353+ }
 354+
 355+ /**
 356+ * @access private
 357+ */
 358+ function resetPrefs() {
 359+ global $wgUser, $wgLang, $wgContLang, $wgContLanguageCode, $wgAllowRealName;
 360+
 361+ $this->mNewpass = $this->mRetypePass = '';
 362+ $this->mUserEmail = $this->user->getEmail();
 363+ $this->mUserEmailAuthenticationtimestamp = $this->user->getEmailAuthenticationtimestamp();
 364+ $this->mRealName = ($wgAllowRealName) ? $this->user->getRealName() : '';
 365+
 366+ # language value might be blank, default to content language
 367+ $this->mUserLanguage = $this->user->getOption( 'language', $wgContLanguageCode );
 368+
 369+ $this->mUserVariant = $this->user->getOption( 'variant');
 370+ $this->mEmailFlag = $this->user->getOption( 'disablemail' ) == 1 ? 1 : 0;
 371+ $this->mNick = $this->user->getOption( 'nickname' );
 372+
 373+ $this->mQuickbar = $this->user->getOption( 'quickbar' );
 374+ $this->mSkin = Skin::normalizeKey( $this->user->getOption( 'skin' ) );
 375+ $this->mMath = $this->user->getOption( 'math' );
 376+ $this->mDate = $this->user->getDatePreference();
 377+ $this->mRows = $this->user->getOption( 'rows' );
 378+ $this->mCols = $this->user->getOption( 'cols' );
 379+ $this->mStubs = $this->user->getOption( 'stubthreshold' );
 380+ $this->mHourDiff = $this->user->getOption( 'timecorrection' );
 381+ $this->mSearch = $this->user->getOption( 'searchlimit' );
 382+ $this->mSearchLines = $this->user->getOption( 'contextlines' );
 383+ $this->mSearchChars = $this->user->getOption( 'contextchars' );
 384+ $this->mImageSize = $this->user->getOption( 'imagesize' );
 385+ $this->mThumbSize = $this->user->getOption( 'thumbsize' );
 386+ $this->mRecent = $this->user->getOption( 'rclimit' );
 387+ $this->mRecentDays = $this->user->getOption( 'rcdays' );
 388+ $this->mWatchlistEdits = $this->user->getOption( 'wllimit' );
 389+ $this->mUnderline = $this->user->getOption( 'underline' );
 390+ $this->mWatchlistDays = $this->user->getOption( 'watchlistdays' );
 391+ $this->mDisableMWSuggest = $this->user->getBoolOption( 'disablesuggest' );
 392+
 393+ $togs = User::getToggles();
 394+ foreach ( $togs as $tname ) {
 395+ $this->mToggles[$tname] = $this->user->getOption( $tname );
 396+ }
 397+
 398+ $namespaces = $wgContLang->getNamespaces();
 399+ foreach ( $namespaces as $i => $namespace ) {
 400+ if ( $i >= NS_MAIN ) {
 401+ $this->mSearchNs[$i] = $this->user->getOption( 'searchNs'.$i );
 402+ }
 403+ }
 404+
 405+ wfRunHooks( 'ResetPreferences', array( $this, $this->user ) );
 406+ }
 407+
 408+ /**
 409+ * @access private
 410+ */
 411+ function namespacesCheckboxes() {
 412+ global $wgContLang;
 413+
 414+ # Determine namespace checkboxes
 415+ $namespaces = $wgContLang->getNamespaces();
 416+ $r1 = null;
 417+
 418+ foreach ( $namespaces as $i => $name ) {
 419+ if ($i < 0)
 420+ continue;
 421+ $checked = $this->mSearchNs[$i] ? "checked='checked'" : '';
 422+ $name = str_replace( '_', ' ', $namespaces[$i] );
 423+
 424+ if ( empty($name) )
 425+ $name = wfMsg( 'blanknamespace' );
 426+
 427+ $r1 .= "<input type='checkbox' value='1' name='wpNs$i' id='wpNs$i' {$checked}/> <label for='wpNs$i'>{$name}</label><br />\n";
 428+ }
 429+ return $r1;
 430+ }
 431+
 432+
 433+ function getToggle( $tname, $trailer = false, $disabled = false ) {
 434+ global $wgUser, $wgLang;
 435+
 436+ $this->mUsedToggles[$tname] = true;
 437+ $ttext = $wgLang->getUserToggle( $tname );
 438+
 439+ $checked = $this->user->getOption( $tname ) == 1 ? ' checked="checked"' : '';
 440+ $disabled = $disabled ? ' disabled="disabled"' : '';
 441+ $trailer = $trailer ? $trailer : '';
 442+ return "<div class='toggle'><input type='checkbox' value='1' id=\"$tname\" name=\"wpOp$tname\"$checked$disabled />" .
 443+ " <span class='toggletext'><label for=\"$tname\">$ttext</label>$trailer</span></div>\n";
 444+ }
 445+
 446+ function getToggles( $items ) {
 447+ $out = "";
 448+ foreach( $items as $item ) {
 449+ if( $item === false )
 450+ continue;
 451+ if( is_array( $item ) ) {
 452+ list( $key, $trailer ) = $item;
 453+ } else {
 454+ $key = $item;
 455+ $trailer = false;
 456+ }
 457+ $out .= $this->getToggle( $key, $trailer );
 458+ }
 459+ return $out;
 460+ }
 461+
 462+ function addRow($td1, $td2) {
 463+ return "<tr><td class='mw-label'>$td1</td><td class='mw-input'>$td2</td></tr>";
 464+ }
 465+
 466+ /**
 467+ * Helper function for user information panel
 468+ * @param $td1 label for an item
 469+ * @param $td2 item or null
 470+ * @param $td3 optional help or null
 471+ * @return xhtml block
 472+ */
 473+ function tableRow( $td1, $td2 = null, $td3 = null ) {
 474+
 475+ if ( is_null( $td3 ) ) {
 476+ $td3 = '';
 477+ } else {
 478+ $td3 = Xml::tags( 'tr', null,
 479+ Xml::tags( 'td', array( 'class' => 'pref-label', 'colspan' => '2' ), $td3 )
 480+ );
 481+ }
 482+
 483+ if ( is_null( $td2 ) ) {
 484+ $td1 = Xml::tags( 'td', array( 'class' => 'pref-label', 'colspan' => '2' ), $td1 );
 485+ $td2 = '';
 486+ } else {
 487+ $td1 = Xml::tags( 'td', array( 'class' => 'pref-label' ), $td1 );
 488+ $td2 = Xml::tags( 'td', array( 'class' => 'pref-input' ), $td2 );
 489+ }
 490+
 491+ return Xml::tags( 'tr', null, $td1 . $td2 ). $td3 . "\n";
 492+
 493+ }
 494+
 495+ /**
 496+ * @access private
 497+ */
 498+ function mainPrefsForm( $status , $message = '' ) {
 499+ global $wgUser, $wgOut, $wgLang, $wgContLang, $wgAuth;
 500+ global $wgAllowRealName, $wgImageLimits, $wgThumbLimits;
 501+ global $wgDisableLangConversion, $wgDisableTitleConversion;
 502+ global $wgEnotifWatchlist, $wgEnotifUserTalk,$wgEnotifMinorEdits;
 503+ global $wgRCShowWatchingUsers, $wgEnotifRevealEditorAddress;
 504+ global $wgEnableEmail, $wgEnableUserEmail, $wgEmailAuthentication;
 505+ global $wgContLanguageCode, $wgDefaultSkin, $wgCookieExpiration;
 506+ global $wgEmailConfirmToEdit, $wgEnableMWSuggest;
 507+
 508+ $wgOut->addScriptFile( 'prefs.js' );
 509+
 510+ $wgOut->disallowUserJs(); # Prevent hijacked user scripts from sniffing passwords etc.
 511+
 512+ if ( $this->mSuccess || 'success' == $status ) {
 513+ $wgOut->wrapWikiMsg( '<div class="successbox"><strong>$1</strong></div>', 'savedprefs' );
 514+ } else if ( 'error' == $status ) {
 515+ $wgOut->addWikiText( '<div class="errorbox"><strong>' . $message . '</strong></div>' );
 516+ } else if ( '' != $status ) {
 517+ $wgOut->addWikiText( $message . "\n----" );
 518+ }
 519+
 520+ $qbs = $wgLang->getQuickbarSettings();
 521+ $skinNames = $wgLang->getSkinNames();
 522+ $mathopts = $wgLang->getMathNames();
 523+ $dateopts = $wgLang->getDatePreferences();
 524+ $togs = User::getToggles();
 525+
 526+ $titleObj = SpecialPage::getTitleFor( 'EditUser' );
 527+
 528+ # Pre-expire some toggles so they won't show if disabled
 529+ $this->mUsedToggles[ 'shownumberswatching' ] = true;
 530+ $this->mUsedToggles[ 'showupdated' ] = true;
 531+ $this->mUsedToggles[ 'enotifwatchlistpages' ] = true;
 532+ $this->mUsedToggles[ 'enotifusertalkpages' ] = true;
 533+ $this->mUsedToggles[ 'enotifminoredits' ] = true;
 534+ $this->mUsedToggles[ 'enotifrevealaddr' ] = true;
 535+ $this->mUsedToggles[ 'ccmeonemails' ] = true;
 536+ $this->mUsedToggles[ 'uselivepreview' ] = true;
 537+ $this->mUsedToggles[ 'noconvertlink' ] = true;
 538+
 539+
 540+ if ( !$this->mEmailFlag ) { $emfc = 'checked="checked"'; }
 541+ else { $emfc = ''; }
 542+
 543+
 544+ if ($wgEmailAuthentication && ($this->mUserEmail != '') ) {
 545+ if( $this->user->getEmailAuthenticationTimestamp() ) {
 546+ // date and time are separate parameters to facilitate localisation.
 547+ // $time is kept for backward compat reasons.
 548+ // 'emailauthenticated' is also used in SpecialConfirmemail.php
 549+ $time = $wgLang->timeAndDate( $this->user->getEmailAuthenticationTimestamp(), true );
 550+ $d = $wgLang->date( $this->user->getEmailAuthenticationTimestamp(), true );
 551+ $t = $wgLang->time( $this->user->getEmailAuthenticationTimestamp(), true );
 552+ $emailauthenticated = wfMsg('emailauthenticated', $time, $d, $t ).'<br />';
 553+ $disableEmailPrefs = false;
 554+ } else {
 555+ $disableEmailPrefs = true;
 556+ $skin = $this->user->getSkin();
 557+ $emailauthenticated = wfMsg('emailnotauthenticated').'<br />' .
 558+ $skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Confirmemail' ),
 559+ wfMsg( 'emailconfirmlink' ) ) . '<br />';
 560+ }
 561+ } else {
 562+ $emailauthenticated = '';
 563+ $disableEmailPrefs = false;
 564+ }
 565+
 566+ if ($this->mUserEmail == '') {
 567+ $emailauthenticated = wfMsg( 'noemailprefs' ) . '<br />';
 568+ }
 569+
 570+ $ps = $this->namespacesCheckboxes();
 571+
 572+ $enotifwatchlistpages = ($wgEnotifWatchlist) ? $this->getToggle( 'enotifwatchlistpages', false, $disableEmailPrefs ) : '';
 573+ $enotifusertalkpages = ($wgEnotifUserTalk) ? $this->getToggle( 'enotifusertalkpages', false, $disableEmailPrefs ) : '';
 574+ $enotifminoredits = ($wgEnotifWatchlist && $wgEnotifMinorEdits) ? $this->getToggle( 'enotifminoredits', false, $disableEmailPrefs ) : '';
 575+ $enotifrevealaddr = (($wgEnotifWatchlist || $wgEnotifUserTalk) && $wgEnotifRevealEditorAddress) ? $this->getToggle( 'enotifrevealaddr', false, $disableEmailPrefs ) : '';
 576+
 577+ # </FIXME>
 578+
 579+ $wgOut->addHTML(
 580+ Xml::openElement( 'form', array(
 581+ 'action' => $titleObj->getLocalUrl(),
 582+ 'method' => 'post',
 583+ 'id' => 'mw-preferences-form',
 584+ ) ) .
 585+ Xml::openElement( 'div', array( 'id' => 'preferences' ) )
 586+ );
 587+
 588+ # User data
 589+
 590+ $wgOut->addHTML(
 591+ Xml::fieldset( wfMsg('prefs-personal') ) .
 592+ Xml::openElement( 'table' ) .
 593+ $this->tableRow( Xml::element( 'h2', null, wfMsg( 'prefs-personal' ) ) )
 594+ );
 595+
 596+ # Get groups to which the user belongs
 597+ $userEffectiveGroups = $this->user->getEffectiveGroups();
 598+ $userEffectiveGroupsArray = array();
 599+ foreach( $userEffectiveGroups as $ueg ) {
 600+ if( $ueg == '*' ) {
 601+ // Skip the default * group, seems useless here
 602+ continue;
 603+ }
 604+ $userEffectiveGroupsArray[] = User::makeGroupLinkHTML( $ueg );
 605+ }
 606+ asort( $userEffectiveGroupsArray );
 607+
 608+ $sk = $this->user->getSkin();
 609+ $toolLinks = array();
 610+ $toolLinks[] = $sk->makeKnownLinkObj( SpecialPage::getTitleFor( 'ListGroupRights' ), wfMsg( 'listgrouprights' ) );
 611+ # At the moment one tool link only but be prepared for the future...
 612+ # FIXME: Add a link to Special:Userrights for users who are allowed to use it.
 613+ # $wgUser->isAllowed( 'userrights' ) seems to strict in some cases
 614+
 615+ $userInformationHtml =
 616+ $this->tableRow( wfMsgHtml( 'username' ), htmlspecialchars( $this->user->getName() ) ) .
 617+ $this->tableRow( wfMsgHtml( 'uid' ), $wgLang->formatNum( htmlspecialchars( $this->user->getId() ) ) ).
 618+
 619+ $this->tableRow(
 620+ wfMsgExt( 'prefs-memberingroups', array( 'parseinline' ), count( $userEffectiveGroupsArray ) ),
 621+ $wgLang->commaList( $userEffectiveGroupsArray ) .
 622+ '<br />(' . implode( ' | ', $toolLinks ) . ')'
 623+ ) .
 624+
 625+ $this->tableRow(
 626+ wfMsgHtml( 'prefs-edits' ),
 627+ $wgLang->formatNum( $this->user->getEditCount() )
 628+ );
 629+
 630+ if( wfRunHooks( 'PreferencesUserInformationPanel', array( $this, &$userInformationHtml ) ) ) {
 631+ $wgOut->addHtml( $userInformationHtml );
 632+ }
 633+
 634+ if ( $wgAllowRealName ) {
 635+ $wgOut->addHTML(
 636+ $this->tableRow(
 637+ Xml::label( wfMsg('yourrealname'), 'wpRealName' ),
 638+ Xml::input( 'wpRealName', 25, $this->mRealName, array( 'id' => 'wpRealName' ) ),
 639+ Xml::tags('div', array( 'class' => 'prefsectiontip' ),
 640+ wfMsgExt( 'prefs-help-realname', 'parseinline' )
 641+ )
 642+ )
 643+ );
 644+ }
 645+ if ( $wgEnableEmail ) {
 646+ $wgOut->addHTML(
 647+ $this->tableRow(
 648+ Xml::label( wfMsg('youremail'), 'wpUserEmail' ),
 649+ Xml::input( 'wpUserEmail', 25, $this->mUserEmail, array( 'id' => 'wpUserEmail' ) ),
 650+ Xml::tags('div', array( 'class' => 'prefsectiontip' ),
 651+ wfMsgExt( $wgEmailConfirmToEdit ? 'prefs-help-email-required' : 'prefs-help-email', 'parseinline' )
 652+ )
 653+ )
 654+ );
 655+ }
 656+
 657+ global $wgParser, $wgMaxSigChars;
 658+ if( mb_strlen( $this->mNick ) > $wgMaxSigChars ) {
 659+ $invalidSig = $this->tableRow(
 660+ '&nbsp;',
 661+ Xml::element( 'span', array( 'class' => 'error' ),
 662+ wfMsgExt( 'badsiglength', 'parsemag', $wgLang->formatNum( $wgMaxSigChars ) ) )
 663+ );
 664+ } elseif( !empty( $this->mToggles['fancysig'] ) &&
 665+ false === $wgParser->validateSig( $this->mNick ) ) {
 666+ $invalidSig = $this->tableRow(
 667+ '&nbsp;',
 668+ Xml::element( 'span', array( 'class' => 'error' ), wfMsg( 'badsig' ) )
 669+ );
 670+ } else {
 671+ $invalidSig = '';
 672+ }
 673+
 674+ $wgOut->addHTML(
 675+ $this->tableRow(
 676+ Xml::label( wfMsg( 'yournick' ), 'wpNick' ),
 677+ Xml::input( 'wpNick', 25, $this->mNick,
 678+ array(
 679+ 'id' => 'wpNick',
 680+ // Note: $wgMaxSigChars is enforced in Unicode characters,
 681+ // both on the backend and now in the browser.
 682+ // Badly-behaved requests may still try to submit
 683+ // an overlong string, however.
 684+ 'maxlength' => $wgMaxSigChars ) )
 685+ ) .
 686+ $invalidSig .
 687+ $this->tableRow( '&nbsp;', $this->getToggle( 'fancysig' ) )
 688+ );
 689+
 690+ list( $lsLabel, $lsSelect) = Xml::languageSelector( $this->mUserLanguage );
 691+ $wgOut->addHTML(
 692+ $this->tableRow( $lsLabel, $lsSelect )
 693+ );
 694+
 695+ /* see if there are multiple language variants to choose from*/
 696+ if(!$wgDisableLangConversion) {
 697+ $variants = $wgContLang->getVariants();
 698+ $variantArray = array();
 699+
 700+ $languages = Language::getLanguageNames( true );
 701+ foreach($variants as $v) {
 702+ $v = str_replace( '_', '-', strtolower($v));
 703+ if( array_key_exists( $v, $languages ) ) {
 704+ // If it doesn't have a name, we'll pretend it doesn't exist
 705+ $variantArray[$v] = $languages[$v];
 706+ }
 707+ }
 708+
 709+ $options = "\n";
 710+ foreach( $variantArray as $code => $name ) {
 711+ $selected = ($code == $this->mUserVariant);
 712+ $options .= Xml::option( "$code - $name", $code, $selected ) . "\n";
 713+ }
 714+
 715+ if(count($variantArray) > 1) {
 716+ $wgOut->addHtml(
 717+ $this->tableRow(
 718+ Xml::label( wfMsg( 'yourvariant' ), 'wpUserVariant' ),
 719+ Xml::tags( 'select',
 720+ array( 'name' => 'wpUserVariant', 'id' => 'wpUserVariant' ),
 721+ $options
 722+ )
 723+ )
 724+ );
 725+ }
 726+
 727+ if(count($variantArray) > 1 && !$wgDisableLangConversion && !$wgDisableTitleConversion) {
 728+ $wgOut->addHtml(
 729+ Xml::tags( 'tr', null,
 730+ Xml::tags( 'td', array( 'colspan' => '2' ),
 731+ $this->getToggle( "noconvertlink" )
 732+ )
 733+ )
 734+ );
 735+ }
 736+ }
 737+
 738+ # Password
 739+ if( $wgAuth->allowPasswordChange() ) {
 740+ $wgOut->addHTML(
 741+ $this->tableRow( Xml::element( 'h2', null, wfMsg( 'changepassword' ) ) ) .
 742+ $this->tableRow(
 743+ Xml::label( wfMsg( 'newpassword' ), 'wpNewpass' ),
 744+ Xml::password( 'wpNewpass', 25, $this->mNewpass, array( 'id' => 'wpNewpass' ) )
 745+ ) .
 746+ $this->tableRow(
 747+ Xml::label( wfMsg( 'retypenew' ), 'wpRetypePass' ),
 748+ Xml::password( 'wpRetypePass', 25, $this->mRetypePass, array( 'id' => 'wpRetypePass' ) )
 749+ )
 750+ );
 751+ if( $wgCookieExpiration > 0 ){
 752+ $wgOut->addHTML(
 753+ Xml::tags( 'tr', null,
 754+ Xml::tags( 'td', array( 'colspan' => '2' ),
 755+ $this->getToggle( "rememberpassword" )
 756+ )
 757+ )
 758+ );
 759+ } else {
 760+ $this->mUsedToggles['rememberpassword'] = true;
 761+ }
 762+ }
 763+
 764+ # <FIXME>
 765+ # Enotif
 766+ if ( $wgEnableEmail ) {
 767+
 768+ $moreEmail = '';
 769+ if ($wgEnableUserEmail) {
 770+ // fixme -- the "allowemail" pseudotoggle is a hacked-together
 771+ // inversion for the "disableemail" preference.
 772+ $emf = wfMsg( 'allowemail' );
 773+ $disabled = $disableEmailPrefs ? ' disabled="disabled"' : '';
 774+ $moreEmail =
 775+ "<input type='checkbox' $emfc $disabled value='1' name='wpEmailFlag' id='wpEmailFlag' /> <label for='wpEmailFlag'>$emf</label>" .
 776+ $this->getToggle( 'ccmeonemails', '', $disableEmailPrefs );
 777+ }
 778+
 779+
 780+ $wgOut->addHTML(
 781+ $this->tableRow( Xml::element( 'h2', null, wfMsg( 'email' ) ) ) .
 782+ $this->tableRow(
 783+ $emailauthenticated.
 784+ $enotifrevealaddr.
 785+ $enotifwatchlistpages.
 786+ $enotifusertalkpages.
 787+ $enotifminoredits.
 788+ $moreEmail
 789+ )
 790+ );
 791+ }
 792+ # </FIXME>
 793+
 794+ $wgOut->addHTML(
 795+ Xml::closeElement( 'table' ) .
 796+ Xml::closeElement( 'fieldset' )
 797+ );
 798+
 799+
 800+ # Quickbar
 801+ #
 802+ if ($this->mSkin == 'cologneblue' || $this->mSkin == 'standard') {
 803+ $wgOut->addHtml( "<fieldset>\n<legend>" . wfMsg( 'qbsettings' ) . "</legend>\n" );
 804+ for ( $i = 0; $i < count( $qbs ); ++$i ) {
 805+ if ( $i == $this->mQuickbar ) { $checked = ' checked="checked"'; }
 806+ else { $checked = ""; }
 807+ $wgOut->addHTML( "<div><label><input type='radio' name='wpQuickbar' value=\"$i\"$checked />{$qbs[$i]}</label></div>\n" );
 808+ }
 809+ $wgOut->addHtml( "</fieldset>\n\n" );
 810+ } else {
 811+ # Need to output a hidden option even if the relevant skin is not in use,
 812+ # otherwise the preference will get reset to 0 on submit
 813+ $wgOut->addHtml( wfHidden( 'wpQuickbar', $this->mQuickbar ) );
 814+ }
 815+
 816+ # Skin
 817+ #
 818+ $wgOut->addHTML( "<fieldset>\n<legend>\n" . wfMsg('skin') . "</legend>\n" );
 819+ $mptitle = Title::newMainPage();
 820+ $previewtext = wfMsg('skin-preview');
 821+ # Only show members of Skin::getSkinNames() rather than
 822+ # $skinNames (skins is all skin names from Language.php)
 823+ $validSkinNames = Skin::getUsableSkins();
 824+ # Sort by UI skin name. First though need to update validSkinNames as sometimes
 825+ # the skinkey & UI skinname differ (e.g. "standard" skinkey is "Classic" in the UI).
 826+ foreach ($validSkinNames as $skinkey => & $skinname ) {
 827+ if ( isset( $skinNames[$skinkey] ) ) {
 828+ $skinname = $skinNames[$skinkey];
 829+ }
 830+ }
 831+ asort($validSkinNames);
 832+ foreach ($validSkinNames as $skinkey => $sn ) {
 833+ $checked = $skinkey == $this->mSkin ? ' checked="checked"' : '';
 834+
 835+ $mplink = htmlspecialchars($mptitle->getLocalURL("useskin=$skinkey"));
 836+ $previewlink = "(<a target='_blank' href=\"$mplink\">$previewtext</a>)";
 837+ if( $skinkey == $wgDefaultSkin )
 838+ $sn .= ' (' . wfMsg( 'default' ) . ')';
 839+ $wgOut->addHTML( "<input type='radio' name='wpSkin' id=\"wpSkin$skinkey\" value=\"$skinkey\"$checked /> <label for=\"wpSkin$skinkey\">{$sn}</label> $previewlink<br />\n" );
 840+ }
 841+ $wgOut->addHTML( "</fieldset>\n\n" );
 842+
 843+ # Math
 844+ #
 845+ global $wgUseTeX;
 846+ if( $wgUseTeX ) {
 847+ $wgOut->addHTML( "<fieldset>\n<legend>" . wfMsg('math') . '</legend>' );
 848+ foreach ( $mathopts as $k => $v ) {
 849+ $checked = ($k == $this->mMath);
 850+ $wgOut->addHTML(
 851+ Xml::openElement( 'div' ) .
 852+ Xml::radioLabel( wfMsg( $v ), 'wpMath', $k, "mw-sp-math-$k", $checked ) .
 853+ Xml::closeElement( 'div' ) . "\n"
 854+ );
 855+ }
 856+ $wgOut->addHTML( "</fieldset>\n\n" );
 857+ }
 858+
 859+ # Files
 860+ #
 861+ $wgOut->addHTML(
 862+ "<fieldset>\n" . Xml::element( 'legend', null, wfMsg( 'files' ) ) . "\n"
 863+ );
 864+
 865+ $imageLimitOptions = null;
 866+ foreach ( $wgImageLimits as $index => $limits ) {
 867+ $selected = ($index == $this->mImageSize);
 868+ $imageLimitOptions .= Xml::option( "{$limits[0]}×{$limits[1]}" .
 869+ wfMsg('unit-pixel'), $index, $selected );
 870+ }
 871+
 872+ $imageSizeId = 'wpImageSize';
 873+ $wgOut->addHTML(
 874+ "<div>" . Xml::label( wfMsg('imagemaxsize'), $imageSizeId ) . " " .
 875+ Xml::openElement( 'select', array( 'name' => $imageSizeId, 'id' => $imageSizeId ) ) .
 876+ $imageLimitOptions .
 877+ Xml::closeElement( 'select' ) . "</div>\n"
 878+ );
 879+
 880+ $imageThumbOptions = null;
 881+ foreach ( $wgThumbLimits as $index => $size ) {
 882+ $selected = ($index == $this->mThumbSize);
 883+ $imageThumbOptions .= Xml::option($size . wfMsg('unit-pixel'), $index,
 884+ $selected);
 885+ }
 886+
 887+ $thumbSizeId = 'wpThumbSize';
 888+ $wgOut->addHTML(
 889+ "<div>" . Xml::label( wfMsg('thumbsize'), $thumbSizeId ) . " " .
 890+ Xml::openElement( 'select', array( 'name' => $thumbSizeId, 'id' => $thumbSizeId ) ) .
 891+ $imageThumbOptions .
 892+ Xml::closeElement( 'select' ) . "</div>\n"
 893+ );
 894+
 895+ $wgOut->addHTML( "</fieldset>\n\n" );
 896+
 897+ # Date format
 898+ #
 899+ # Date/Time
 900+ #
 901+
 902+ $wgOut->addHTML(
 903+ Xml::openElement( 'fieldset' ) .
 904+ Xml::element( 'legend', null, wfMsg( 'datetime' ) ) . "\n"
 905+ );
 906+
 907+ if ($dateopts) {
 908+ $wgOut->addHTML(
 909+ Xml::openElement( 'fieldset' ) .
 910+ Xml::element( 'legend', null, wfMsg( 'dateformat' ) ) . "\n"
 911+ );
 912+ $idCnt = 0;
 913+ $epoch = '20010115161234'; # Wikipedia day
 914+ foreach( $dateopts as $key ) {
 915+ if( $key == 'default' ) {
 916+ $formatted = wfMsg( 'datedefault' );
 917+ } else {
 918+ $formatted = $wgLang->timeanddate( $epoch, false, $key );
 919+ }
 920+ $wgOut->addHTML(
 921+ Xml::tags( 'div', null,
 922+ Xml::radioLabel( $formatted, 'wpDate', $key, "wpDate$idCnt", $key == $this->mDate )
 923+ ) . "\n"
 924+ );
 925+ $idCnt++;
 926+ }
 927+ $wgOut->addHTML( Xml::closeElement( 'fieldset' ) . "\n" );
 928+ }
 929+
 930+ $nowlocal = $wgLang->time( $now = wfTimestampNow(), true );
 931+ $nowserver = $wgLang->time( $now, false );
 932+
 933+ $wgOut->addHTML(
 934+ Xml::openElement( 'fieldset' ) .
 935+ Xml::element( 'legend', null, wfMsg( 'timezonelegend' ) ) .
 936+ Xml::openElement( 'table' ) .
 937+ $this->addRow( wfMsg( 'servertime' ), $nowserver ) .
 938+ $this->addRow( wfMsg( 'localtime' ), $nowlocal ) .
 939+ $this->addRow(
 940+ Xml::label( wfMsg( 'timezoneoffset' ), 'wpHourDiff' ),
 941+ Xml::input( 'wpHourDiff', 6, $this->mHourDiff, array( 'id' => 'wpHourDiff' ) ) ) .
 942+ "<tr>
 943+ <td></td>
 944+ <td class='mw-submit'>" .
 945+ Xml::element( 'input',
 946+ array( 'type' => 'button',
 947+ 'value' => wfMsg( 'guesstimezone' ),
 948+ 'onclick' => 'javascript:guessTimezone()',
 949+ 'id' => 'guesstimezonebutton',
 950+ 'style' => 'display:none;' ) ) .
 951+ "</td>
 952+ </tr>" .
 953+ Xml::closeElement( 'table' ) .
 954+ Xml::tags( 'div', array( 'class' => 'prefsectiontip' ), wfMsgExt( 'timezonetext', 'parseinline' ) ).
 955+ Xml::closeElement( 'fieldset' ) .
 956+ Xml::closeElement( 'fieldset' ) . "\n\n"
 957+ );
 958+
 959+ # Editing
 960+ #
 961+ global $wgLivePreview;
 962+ $wgOut->addHTML( '<fieldset><legend>' . wfMsg( 'textboxsize' ) . '</legend>
 963+ <div>' .
 964+ wfInputLabel( wfMsg( 'rows' ), 'wpRows', 'wpRows', 3, $this->mRows ) .
 965+ ' ' .
 966+ wfInputLabel( wfMsg( 'columns' ), 'wpCols', 'wpCols', 3, $this->mCols ) .
 967+ "</div>" .
 968+ $this->getToggles( array(
 969+ 'editsection',
 970+ 'editsectiononrightclick',
 971+ 'editondblclick',
 972+ 'editwidth',
 973+ 'showtoolbar',
 974+ 'previewonfirst',
 975+ 'previewontop',
 976+ 'minordefault',
 977+ 'externaleditor',
 978+ 'externaldiff',
 979+ $wgLivePreview ? 'uselivepreview' : false,
 980+ 'forceeditsummary',
 981+ ) ) . '</fieldset>'
 982+ );
 983+
 984+ # Recent changes
 985+ $wgOut->addHtml( '<fieldset><legend>' . wfMsgHtml( 'prefs-rc' ) . '</legend>' );
 986+
 987+ $rc = '<table><tr>';
 988+ $rc .= '<td>' . Xml::label( wfMsg( 'recentchangesdays' ), 'wpRecentDays' ) . '</td>';
 989+ $rc .= '<td>' . Xml::input( 'wpRecentDays', 3, $this->mRecentDays, array( 'id' => 'wpRecentDays' ) ) . '</td>';
 990+ $rc .= '</tr><tr>';
 991+ $rc .= '<td>' . Xml::label( wfMsg( 'recentchangescount' ), 'wpRecent' ) . '</td>';
 992+ $rc .= '<td>' . Xml::input( 'wpRecent', 3, $this->mRecent, array( 'id' => 'wpRecent' ) ) . '</td>';
 993+ $rc .= '</tr></table>';
 994+ $wgOut->addHtml( $rc );
 995+
 996+ $wgOut->addHtml( '<br />' );
 997+
 998+ $toggles[] = 'hideminor';
 999+ if( $wgRCShowWatchingUsers )
 1000+ $toggles[] = 'shownumberswatching';
 1001+ $toggles[] = 'usenewrc';
 1002+ $wgOut->addHtml( $this->getToggles( $toggles ) );
 1003+
 1004+ $wgOut->addHtml( '</fieldset>' );
 1005+
 1006+ # Watchlist
 1007+ $wgOut->addHtml( '<fieldset><legend>' . wfMsgHtml( 'prefs-watchlist' ) . '</legend>' );
 1008+
 1009+ $wgOut->addHtml( wfInputLabel( wfMsg( 'prefs-watchlist-days' ), 'wpWatchlistDays', 'wpWatchlistDays', 3, $this->mWatchlistDays ) );
 1010+ $wgOut->addHtml( '<br /><br />' );
 1011+
 1012+ $wgOut->addHtml( $this->getToggle( 'extendwatchlist' ) );
 1013+ $wgOut->addHtml( wfInputLabel( wfMsg( 'prefs-watchlist-edits' ), 'wpWatchlistEdits', 'wpWatchlistEdits', 3, $this->mWatchlistEdits ) );
 1014+ $wgOut->addHtml( '<br /><br />' );
 1015+
 1016+ $wgOut->addHtml( $this->getToggles( array( 'watchlisthideminor', 'watchlisthidebots', 'watchlisthideown', 'watchlisthideanons', 'watchlisthideliu' ) ) );
 1017+
 1018+ if( $this->user->isAllowed( 'createpage' ) || $this->user->isAllowed( 'createtalk' ) )
 1019+ $wgOut->addHtml( $this->getToggle( 'watchcreations' ) );
 1020+ foreach( array( 'edit' => 'watchdefault', 'move' => 'watchmoves', 'delete' => 'watchdeletion' ) as $action => $toggle ) {
 1021+ if( $this->user->isAllowed( $action ) )
 1022+ $wgOut->addHtml( $this->getToggle( $toggle ) );
 1023+ }
 1024+ $this->mUsedToggles['watchcreations'] = true;
 1025+ $this->mUsedToggles['watchdefault'] = true;
 1026+ $this->mUsedToggles['watchmoves'] = true;
 1027+ $this->mUsedToggles['watchdeletion'] = true;
 1028+
 1029+ $wgOut->addHtml( '</fieldset>' );
 1030+
 1031+ # Search
 1032+ $mwsuggest = $wgEnableMWSuggest ?
 1033+ $this->addRow(
 1034+ Xml::label( wfMsg( 'mwsuggest-disable' ), 'wpDisableMWSuggest' ),
 1035+ Xml::check( 'wpDisableMWSuggest', $this->mDisableMWSuggest, array( 'id' => 'wpDisableMWSuggest' ) )
 1036+ ) : '';
 1037+ $wgOut->addHTML(
 1038+ // Elements for the search tab itself
 1039+ Xml::openElement( 'fieldset' ) .
 1040+ Xml::element( 'legend', null, wfMsg( 'searchresultshead' ) ) .
 1041+ // Elements for the search options in the search tab
 1042+ Xml::openElement( 'fieldset' ) .
 1043+ Xml::element( 'legend', null, wfMsg( 'prefs-searchoptions' ) ) .
 1044+ Xml::openElement( 'table' ) .
 1045+ $this->addRow(
 1046+ Xml::label( wfMsg( 'resultsperpage' ), 'wpSearch' ),
 1047+ Xml::input( 'wpSearch', 4, $this->mSearch, array( 'id' => 'wpSearch' ) )
 1048+ ) .
 1049+ $this->addRow(
 1050+ Xml::label( wfMsg( 'contextlines' ), 'wpSearchLines' ),
 1051+ Xml::input( 'wpSearchLines', 4, $this->mSearchLines, array( 'id' => 'wpSearchLines' ) )
 1052+ ) .
 1053+ $this->addRow(
 1054+ Xml::label( wfMsg( 'contextchars' ), 'wpSearchChars' ),
 1055+ Xml::input( 'wpSearchChars', 4, $this->mSearchChars, array( 'id' => 'wpSearchChars' ) )
 1056+ ) .
 1057+ $mwsuggest .
 1058+ Xml::closeElement( 'table' ) .
 1059+ Xml::closeElement( 'fieldset' ) .
 1060+ // Elements for the namespace options in the search tab
 1061+ Xml::openElement( 'fieldset' ) .
 1062+ Xml::element( 'legend', null, wfMsg( 'prefs-namespaces' ) ) .
 1063+ wfMsgExt( 'defaultns', array( 'parse' ) ) .
 1064+ $ps .
 1065+ Xml::closeElement( 'fieldset' ) .
 1066+ // End of the search tab
 1067+ Xml::closeElement( 'fieldset' )
 1068+ );
 1069+
 1070+ # Misc
 1071+ #
 1072+ $wgOut->addHTML('<fieldset><legend>' . wfMsg('prefs-misc') . '</legend>');
 1073+ $wgOut->addHtml( '<label for="wpStubs">' . wfMsg( 'stub-threshold' ) . '</label>&nbsp;' );
 1074+ $wgOut->addHtml( Xml::input( 'wpStubs', 6, $this->mStubs, array( 'id' => 'wpStubs' ) ) );
 1075+ $msgUnderline = htmlspecialchars( wfMsg ( 'tog-underline' ) );
 1076+ $msgUnderlinenever = htmlspecialchars( wfMsg ( 'underline-never' ) );
 1077+ $msgUnderlinealways = htmlspecialchars( wfMsg ( 'underline-always' ) );
 1078+ $msgUnderlinedefault = htmlspecialchars( wfMsg ( 'underline-default' ) );
 1079+ $uopt = $this->user->getOption("underline");
 1080+ $s0 = $uopt == 0 ? ' selected="selected"' : '';
 1081+ $s1 = $uopt == 1 ? ' selected="selected"' : '';
 1082+ $s2 = $uopt == 2 ? ' selected="selected"' : '';
 1083+ $wgOut->addHTML("
 1084+<div class='toggle'><p><label for='wpOpunderline'>$msgUnderline</label>
 1085+<select name='wpOpunderline' id='wpOpunderline'>
 1086+<option value=\"0\"$s0>$msgUnderlinenever</option>
 1087+<option value=\"1\"$s1>$msgUnderlinealways</option>
 1088+<option value=\"2\"$s2>$msgUnderlinedefault</option>
 1089+</select></p></div>");
 1090+
 1091+ foreach ( $togs as $tname ) {
 1092+ if( !array_key_exists( $tname, $this->mUsedToggles ) ) {
 1093+ $wgOut->addHTML( $this->getToggle( $tname ) );
 1094+ }
 1095+ }
 1096+ $wgOut->addHTML( '</fieldset>' );
 1097+
 1098+ wfRunHooks( 'RenderPreferencesForm', array( $this, $wgOut ) );
 1099+
 1100+ $token = htmlspecialchars( $this->user->editToken() );
 1101+ $skin = $this->user->getSkin();
 1102+ $wgOut->addHTML( "
 1103+ <div id='prefsubmit'>
 1104+ <div>
 1105+ <input type='submit' name='wpSaveprefs' class='btnSavePrefs' value=\"" . wfMsgHtml( 'saveprefs' ) . '"'.$skin->tooltipAndAccesskey('save')." />
 1106+ <input type='submit' name='wpReset' value=\"" . wfMsgHtml( 'resetprefs' ) . "\" />
 1107+ </div>
 1108+
 1109+ </div>
 1110+
 1111+ <input type='hidden' name='wpEditToken' value=\"{$token}\" />
 1112+ <input type='hidden' name='username' value=\"{$this->target}\" />
 1113+ </div></form>\n" );
 1114+
 1115+ $wgOut->addHtml( Xml::tags( 'div', array( 'class' => "prefcache" ),
 1116+ wfMsgExt( 'clearyourcache', 'parseinline' ) )
 1117+ );
 1118+ }
 1119+
 1120+ function makeSearchForm() {
 1121+ $thisTitle = Title::makeTitle( NS_SPECIAL, $this->getName() );
 1122+ $form = wfOpenElement( 'form', array( 'method' => 'post', 'action' => $thisTitle->getLocalUrl() ) );
 1123+ $form .= wfElement( 'label', array( 'for' => 'username' ), wfMsg( 'edituser-username' ) ) . ' ';
 1124+ $form .= wfElement( 'input', array( 'type' => 'text', 'name' => 'username', 'id' => 'username', 'value' => $this->target ) ) . ' ';
 1125+ $form .= wfElement( 'input', array( 'type' => 'submit', 'name' => 'dosearch', 'value' => wfMsg( 'edituser-dosearch' ) ) );
 1126+ $form .= wfElement( 'input', array( 'type' => 'hidden', 'name' => 'issearch', 'value' => '1' ) );
 1127+ $form .= wfCloseElement( 'form' );
 1128+ return $form;
 1129+ }
 1130+}
Property changes on: trunk/extensions/EditUser/1.14/EditUser_body.php
___________________________________________________________________
Added: svn:eol-style
11131 + native
Index: trunk/extensions/EditUser/EditUser.php
@@ -4,23 +4,29 @@
55 */
66
77 if(!defined('MEDIAWIKI')) {
8 - echo("This file is an extension to the MediaWiki software and is not a valid access point");
 8+ echo "This file is an extension to the MediaWiki software and is not a valid access point";
99 die(1);
1010 }
1111
 12+$dir = dirname(__FILE__) . '/';
 13+
 14+if(!file_exists($dir . substr($wgVersion, 0, 4) . 'EditUser_body.php')) {
 15+ wfDebug("Your MediaWiki version \"$wgVersion\" is not supported by the EditUser extension");
 16+ return;
 17+}
 18+
1219 $wgExtensionCredits['specialpage'][] = array(
1320 'name' => 'EditUser',
14 - 'version' => '1.4.2',
 21+ 'version' => '1.5.0',
1522 'author' => 'Ryan Schmidt',
1623 'description' => 'Allows privileged users to edit other users\' preferences',
1724 'descriptionmsg' => 'edituser-desc',
1825 'url' => 'http://www.mediawiki.org/wiki/Extension:EditUser',
1926 );
2027
21 -$dir = dirname(__FILE__) . '/';
2228 $wgExtensionMessagesFiles['EditUser'] = $dir . 'EditUser.i18n.php';
2329 $wgExtensionAliasesFiles['EditUser'] = $dir . 'EditUser.alias.php';
24 -$wgAutoloadClasses['EditUser'] = $dir . 'EditUser_body.php';
 30+$wgAutoloadClasses['EditUser'] = $dir . substr($wgVersion, 0, 4) . 'EditUser_body.php';
2531 $wgSpecialPages['EditUser'] = 'EditUser';
2632 $wgAvailableRights[] = 'edituser';
2733 $wgAvaliableRights[] = 'edituser-exempt';

Status & tagging log