r49327 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r49326‎ | r49327 | r49328 >
Date:03:16, 9 April 2009
Author:werdna
Status:deferred
Tags:
Comment:
Add a working Preferences form based on the logic in the new Preferences class
Modified paths:
  • /branches/preferences-work/phase3/includes/AutoLoader.php (modified) (history)
  • /branches/preferences-work/phase3/includes/HTMLForm.php (modified) (history)
  • /branches/preferences-work/phase3/includes/SpecialPage.php (modified) (history)
  • /branches/preferences-work/phase3/includes/User.php (modified) (history)
  • /branches/preferences-work/phase3/includes/specials/SpecialPreferences.php (modified) (history)

Diff [purge]

Index: branches/preferences-work/phase3/includes/User.php
@@ -1879,7 +1879,7 @@
18801880 }
18811881
18821882 if ( array_key_exists( $oname, $this->mOptions ) ) {
1883 - return trim( $this->mOptions[$oname] );
 1883+ return $this->mOptions[$oname];
18841884 } else {
18851885 return $defaultOverride;
18861886 }
Index: branches/preferences-work/phase3/includes/HTMLForm.php
@@ -548,4 +548,12 @@
549549 function getInputHTML( $value ) {
550550 return !empty($this->mParams['raw']) ? $value : htmlspecialchars($value);
551551 }
 552+
 553+ function getTableRow( $value ) {
 554+ if ( !empty($this->mParams['rawrow']) ) {
 555+ return $value;
 556+ }
 557+
 558+ return parent::getTableRow( $value );
 559+ }
552560 }
Index: branches/preferences-work/phase3/includes/AutoLoader.php
@@ -484,7 +484,6 @@
485485 'PageArchive' => 'includes/specials/SpecialUndelete.php',
486486 'SpecialResetpass' => 'includes/specials/SpecialResetpass.php',
487487 'PopularPagesPage' => 'includes/specials/SpecialPopularpages.php',
488 - 'PreferencesForm' => 'includes/specials/SpecialPreferences.php',
489488 'RandomPage' => 'includes/specials/SpecialRandompage.php',
490489 'SpecialRevisionDelete' => 'includes/specials/SpecialRevisiondelete.php',
491490 'RevisionDeleter' => 'includes/specials/SpecialRevisiondelete.php',
@@ -495,6 +494,7 @@
496495 'SpecialImport' => 'includes/specials/SpecialImport.php',
497496 'SpecialListGroupRights' => 'includes/specials/SpecialListgrouprights.php',
498497 'SpecialMostlinkedtemplates' => 'includes/specials/SpecialMostlinkedtemplates.php',
 498+ 'SpecialPreferences' => 'includes/specials/SpecialPreferences.php',
499499 'SpecialPrefixindex' => 'includes/specials/SpecialPrefixindex.php',
500500 'SpecialRandomredirect' => 'includes/specials/SpecialRandomredirect.php',
501501 'SpecialRecentchanges' => 'includes/specials/SpecialRecentchanges.php',
Index: branches/preferences-work/phase3/includes/specials/SpecialPreferences.php
@@ -1,1308 +1,44 @@
22 <?php
3 -/**
4 - * Hold things related to displaying and saving user preferences.
5 - * @file
6 - * @ingroup SpecialPage
7 - */
83
9 -/**
10 - * Entry point that create the "Preferences" object
11 - */
12 -function wfSpecialPreferences() {
13 - global $wgRequest;
14 -
15 - $form = new PreferencesForm( $wgRequest );
16 - $form->execute();
17 -}
18 -
19 -/**
20 - * Preferences form handling
21 - * This object will show the preferences form and can save it as well.
22 - * @ingroup SpecialPage
23 - */
24 -class PreferencesForm {
25 - var $mQuickbar, $mStubs;
26 - var $mRows, $mCols, $mSkin, $mMath, $mDate, $mUserEmail, $mEmailFlag, $mNick;
27 - var $mUserLanguage, $mUserVariant;
28 - var $mSearch, $mRecent, $mRecentDays, $mTimeZone, $mHourDiff, $mSearchLines, $mSearchChars, $mAction;
29 - var $mReset, $mPosted, $mToggles, $mSearchNs, $mRealName, $mImageSize;
30 - var $mUnderline, $mWatchlistEdits, $mGender;
31 -
32 - /**
33 - * Constructor
34 - * Load some values
35 - */
36 - function __construct( &$request ) {
37 - global $wgContLang, $wgUser, $wgAllowRealName;
38 -
39 - $this->mQuickbar = $request->getVal( 'wpQuickbar' );
40 - $this->mStubs = $request->getVal( 'wpStubs' );
41 - $this->mRows = $request->getVal( 'wpRows' );
42 - $this->mCols = $request->getVal( 'wpCols' );
43 - $this->mSkin = Skin::normalizeKey( $request->getVal( 'wpSkin' ) );
44 - $this->mMath = $request->getVal( 'wpMath' );
45 - $this->mDate = $request->getVal( 'wpDate' );
46 - $this->mUserEmail = $request->getVal( 'wpUserEmail' );
47 - $this->mRealName = $wgAllowRealName ? $request->getVal( 'wpRealName' ) : '';
48 - $this->mEmailFlag = $request->getCheck( 'wpEmailFlag' ) ? 0 : 1;
49 - $this->mNick = $request->getVal( 'wpNick' );
50 - $this->mUserLanguage = $request->getVal( 'wpUserLanguage' );
51 - $this->mUserVariant = $request->getVal( 'wpUserVariant' );
52 - $this->mSearch = $request->getVal( 'wpSearch' );
53 - $this->mRecent = $request->getVal( 'wpRecent' );
54 - $this->mRecentDays = $request->getVal( 'wpRecentDays' );
55 - $this->mTimeZone = $request->getVal( 'wpTimeZone' );
56 - $this->mHourDiff = $request->getVal( 'wpHourDiff' );
57 - $this->mSearchLines = $request->getVal( 'wpSearchLines' );
58 - $this->mSearchChars = $request->getVal( 'wpSearchChars' );
59 - $this->mImageSize = $request->getVal( 'wpImageSize' );
60 - $this->mThumbSize = $request->getInt( 'wpThumbSize' );
61 - $this->mUnderline = $request->getInt( 'wpOpunderline' );
62 - $this->mAction = $request->getVal( 'action' );
63 - $this->mReset = $request->getCheck( 'wpReset' );
64 - $this->mRestoreprefs = $request->getCheck( 'wpRestore' );
65 - $this->mPosted = $request->wasPosted();
66 - $this->mSuccess = $request->getCheck( 'success' );
67 - $this->mWatchlistDays = $request->getVal( 'wpWatchlistDays' );
68 - $this->mWatchlistEdits = $request->getVal( 'wpWatchlistEdits' );
69 - $this->mDisableMWSuggest = $request->getCheck( 'wpDisableMWSuggest' );
70 - $this->mGender = $request->getVal( 'wpGender' );
71 -
72 - $this->mSaveprefs = $request->getCheck( 'wpSaveprefs' ) &&
73 - $this->mPosted &&
74 - $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) );
75 -
76 - # User toggles (the big ugly unsorted list of checkboxes)
77 - $this->mToggles = array();
78 - if ( $this->mPosted ) {
79 - $togs = User::getToggles();
80 - foreach ( $togs as $tname ) {
81 - $this->mToggles[$tname] = $request->getCheck( "wpOp$tname" ) ? 1 : 0;
82 - }
83 - }
84 -
85 - $this->mUsedToggles = array();
86 -
87 - # Search namespace options
88 - # Note: namespaces don't necessarily have consecutive keys
89 - $this->mSearchNs = array();
90 - if ( $this->mPosted ) {
91 - $namespaces = $wgContLang->getNamespaces();
92 - foreach ( $namespaces as $i => $namespace ) {
93 - if ( $i >= 0 ) {
94 - $this->mSearchNs[$i] = $request->getCheck( "wpNs$i" ) ? 1 : 0;
95 - }
96 - }
97 - }
98 -
99 - # Validate language
100 - if ( !preg_match( '/^[a-z\-]*$/', $this->mUserLanguage ) ) {
101 - $this->mUserLanguage = 'nolanguage';
102 - }
103 -
104 - wfRunHooks( 'InitPreferencesForm', array( $this, $request ) );
 4+class SpecialPreferences extends SpecialPage {
 5+ function __construct() {
 6+ parent::__construct( 'Preferences' );
1057 }
106 -
107 - function execute() {
108 - global $wgUser, $wgOut, $wgTitle;
109 -
110 - if ( $wgUser->isAnon() ) {
111 - $wgOut->showErrorPage( 'prefsnologin', 'prefsnologintext', array($wgTitle->getPrefixedDBkey()) );
112 - return;
113 - }
114 - if ( wfReadOnly() ) {
115 - $wgOut->readOnlyPage();
116 - return;
117 - }
118 - if ( $this->mReset ) {
119 - $this->resetPrefs();
120 - $this->mainPrefsForm( 'reset', wfMsg( 'prefsreset' ) );
121 - } else if ( $this->mSaveprefs ) {
122 - $this->savePreferences();
123 - } else if ( $this->mRestoreprefs ) {
124 - $this->restorePreferences();
125 - } else {
126 - $this->resetPrefs();
127 - $this->mainPrefsForm( '' );
128 - }
129 - }
130 - /**
131 - * @access private
132 - */
133 - function validateInt( &$val, $min=0, $max=0x7fffffff ) {
134 - $val = intval($val);
135 - $val = min($val, $max);
136 - $val = max($val, $min);
137 - return $val;
138 - }
139 -
140 - /**
141 - * @access private
142 - */
143 - function validateFloat( &$val, $min, $max=0x7fffffff ) {
144 - $val = floatval( $val );
145 - $val = min( $val, $max );
146 - $val = max( $val, $min );
147 - return( $val );
148 - }
149 -
150 - /**
151 - * @access private
152 - */
153 - function validateIntOrNull( &$val, $min=0, $max=0x7fffffff ) {
154 - $val = trim($val);
155 - if($val === '') {
156 - return null;
157 - } else {
158 - return $this->validateInt( $val, $min, $max );
159 - }
160 - }
161 -
162 - /**
163 - * @access private
164 - */
165 - function validateDate( $val ) {
166 - global $wgLang, $wgContLang;
167 - if ( $val !== false && (
168 - in_array( $val, (array)$wgLang->getDatePreferences() ) ||
169 - in_array( $val, (array)$wgContLang->getDatePreferences() ) ) )
170 - {
171 - return $val;
172 - } else {
173 - return $wgLang->getDefaultDateFormat();
174 - }
175 - }
176 -
177 - /**
178 - * Used to validate the user inputed timezone before saving it as
179 - * 'timecorrection', will return 'System' if fed bogus data.
180 - * @access private
181 - * @param string $tz the user input Zoneinfo timezone
182 - * @param string $s the user input offset string
183 - * @return string
184 - */
185 - function validateTimeZone( $tz, $s ) {
186 - $data = explode( '|', $tz, 3 );
187 - switch ( $data[0] ) {
188 - case 'ZoneInfo':
189 - case 'System':
190 - return $tz;
191 - case 'Offset':
192 - default:
193 - $data = explode( ':', $s, 2 );
194 - $minDiff = 0;
195 - if( count( $data ) == 2 ) {
196 - $data[0] = intval( $data[0] );
197 - $data[1] = intval( $data[1] );
198 - $minDiff = abs( $data[0] ) * 60 + $data[1];
199 - if ( $data[0] < 0 ) $minDiff = -$minDiff;
200 - } else {
201 - $minDiff = intval( $data[0] ) * 60;
202 - }
203 -
204 - # Max is +14:00 and min is -12:00, see:
205 - # http://en.wikipedia.org/wiki/Timezone
206 - $minDiff = min( $minDiff, 840 ); # 14:00
207 - $minDiff = max( $minDiff, -720 ); # -12:00
208 - return 'Offset|'.$minDiff;
209 - }
210 - }
211 -
212 - function validateGender( $val ) {
213 - $valid = array( 'male', 'female', 'unknown' );
214 - if ( in_array($val, $valid) ) {
215 - return $val;
216 - } else {
217 - return User::getDefaultOption( 'gender' );
218 - }
219 - }
220 -
221 - /**
222 - * @access private
223 - */
224 - function savePreferences() {
225 - global $wgUser, $wgOut, $wgParser;
226 - global $wgEnableUserEmail, $wgEnableEmail;
227 - global $wgEmailAuthentication, $wgRCMaxAge;
228 - global $wgAuth, $wgEmailConfirmToEdit;
229 -
230 - $wgUser->setRealName( $this->mRealName );
231 - $oldOptions = $wgUser->mOptions;
232 -
233 - if( $wgUser->getOption( 'language' ) !== $this->mUserLanguage ) {
234 - $needRedirect = true;
235 - } else {
236 - $needRedirect = false;
237 - }
238 -
239 - # Validate the signature and clean it up as needed
240 - global $wgMaxSigChars;
241 - if( mb_strlen( $this->mNick ) > $wgMaxSigChars ) {
242 - global $wgLang;
243 - $this->mainPrefsForm( 'error',
244 - wfMsgExt( 'badsiglength', 'parsemag', $wgLang->formatNum( $wgMaxSigChars ) ) );
245 - return;
246 - } elseif( $this->mToggles['fancysig'] ) {
247 - if( $wgParser->validateSig( $this->mNick ) !== false ) {
248 - $this->mNick = $wgParser->cleanSig( $this->mNick );
249 - } else {
250 - $this->mainPrefsForm( 'error', wfMsg( 'badsig' ) );
251 - return;
252 - }
253 - } else {
254 - // When no fancy sig used, make sure ~{3,5} get removed.
255 - $this->mNick = $wgParser->cleanSigInSig( $this->mNick );
256 - }
257 -
258 - $wgUser->setOption( 'language', $this->mUserLanguage );
259 - $wgUser->setOption( 'variant', $this->mUserVariant );
260 - $wgUser->setOption( 'nickname', $this->mNick );
261 - $wgUser->setOption( 'quickbar', $this->mQuickbar );
262 - global $wgAllowUserSkin;
263 - if( $wgAllowUserSkin ) {
264 - $wgUser->setOption( 'skin', $this->mSkin );
265 - }
266 - global $wgUseTeX;
267 - if( $wgUseTeX ) {
268 - $wgUser->setOption( 'math', $this->mMath );
269 - }
270 - $wgUser->setOption( 'date', $this->validateDate( $this->mDate ) );
271 - $wgUser->setOption( 'searchlimit', $this->validateIntOrNull( $this->mSearch ) );
272 - $wgUser->setOption( 'contextlines', $this->validateIntOrNull( $this->mSearchLines ) );
273 - $wgUser->setOption( 'contextchars', $this->validateIntOrNull( $this->mSearchChars ) );
274 - $wgUser->setOption( 'rclimit', $this->validateIntOrNull( $this->mRecent ) );
275 - $wgUser->setOption( 'rcdays', $this->validateInt($this->mRecentDays, 1, ceil($wgRCMaxAge / (3600*24))));
276 - $wgUser->setOption( 'wllimit', $this->validateIntOrNull( $this->mWatchlistEdits, 0, 1000 ) );
277 - $wgUser->setOption( 'rows', $this->validateInt( $this->mRows, 4, 1000 ) );
278 - $wgUser->setOption( 'cols', $this->validateInt( $this->mCols, 4, 1000 ) );
279 - $wgUser->setOption( 'stubthreshold', $this->validateIntOrNull( $this->mStubs ) );
280 - $wgUser->setOption( 'timecorrection', $this->validateTimeZone( $this->mTimeZone, $this->mHourDiff ) );
281 - $wgUser->setOption( 'imagesize', $this->mImageSize );
282 - $wgUser->setOption( 'thumbsize', $this->mThumbSize );
283 - $wgUser->setOption( 'underline', $this->validateInt($this->mUnderline, 0, 2) );
284 - $wgUser->setOption( 'watchlistdays', $this->validateFloat( $this->mWatchlistDays, 0, 7 ) );
285 - $wgUser->setOption( 'disablesuggest', $this->mDisableMWSuggest );
286 - $wgUser->setOption( 'gender', $this->validateGender( $this->mGender ) );
287 -
288 - # Set search namespace options
289 - foreach( $this->mSearchNs as $i => $value ) {
290 - $wgUser->setOption( "searchNs{$i}", $value );
291 - }
292 -
293 - if( $wgEnableEmail && $wgEnableUserEmail ) {
294 - $wgUser->setOption( 'disablemail', $this->mEmailFlag );
295 - }
296 -
297 - # Set user toggles
298 - foreach ( $this->mToggles as $tname => $tvalue ) {
299 - $wgUser->setOption( $tname, $tvalue );
300 - }
301 -
302 - $error = false;
303 - if( $wgEnableEmail ) {
304 - $newadr = $this->mUserEmail;
305 - $oldadr = $wgUser->getEmail();
306 - if( ($newadr != '') && ($newadr != $oldadr) ) {
307 - # the user has supplied a new email address on the login page
308 - if( $wgUser->isValidEmailAddr( $newadr ) ) {
309 - # new behaviour: set this new emailaddr from login-page into user database record
310 - $wgUser->setEmail( $newadr );
311 - # but flag as "dirty" = unauthenticated
312 - $wgUser->invalidateEmail();
313 - if ($wgEmailAuthentication) {
314 - # Mail a temporary password to the dirty address.
315 - # User can come back through the confirmation URL to re-enable email.
316 - $result = $wgUser->sendConfirmationMail();
317 - if( WikiError::isError( $result ) ) {
318 - $error = wfMsg( 'mailerror', htmlspecialchars( $result->getMessage() ) );
319 - } else {
320 - $error = wfMsg( 'eauthentsent', $wgUser->getName() );
321 - }
322 - }
323 - } else {
324 - $error = wfMsg( 'invalidemailaddress' );
325 - }
326 - } else {
327 - if( $wgEmailConfirmToEdit && empty( $newadr ) ) {
328 - $this->mainPrefsForm( 'error', wfMsg( 'noemailtitle' ) );
329 - return;
330 - }
331 - $wgUser->setEmail( $this->mUserEmail );
332 - }
333 - if( $oldadr != $newadr ) {
334 - wfRunHooks( 'PrefsEmailAudit', array( $wgUser, $oldadr, $newadr ) );
335 - }
336 - }
337 -
338 - if( !$wgAuth->updateExternalDB( $wgUser ) ){
339 - $this->mainPrefsForm( 'error', wfMsg( 'externaldberror' ) );
340 - return;
341 - }
342 -
343 - $msg = '';
344 - if ( !wfRunHooks( 'SavePreferences', array( $this, $wgUser, &$msg, $oldOptions ) ) ) {
345 - $this->mainPrefsForm( 'error', $msg );
346 - return;
347 - }
348 -
349 - $wgUser->setCookies();
350 - $wgUser->saveSettings();
351 -
352 - if( $needRedirect && $error === false ) {
353 - $title = SpecialPage::getTitleFor( 'Preferences' );
354 - $wgOut->redirect( $title->getFullURL( 'success' ) );
355 - return;
356 - }
357 -
358 - $wgOut->parserOptions( ParserOptions::newFromUser( $wgUser ) );
359 - $this->mainPrefsForm( $error === false ? 'success' : 'error', $error);
360 - }
361 -
362 - /**
363 - * @access private
364 - */
365 - function resetPrefs() {
366 - global $wgUser, $wgLang, $wgContLang, $wgContLanguageCode, $wgAllowRealName, $wgLocalTZoffset;
367 -
368 - $this->mUserEmail = $wgUser->getEmail();
369 - $this->mUserEmailAuthenticationtimestamp = $wgUser->getEmailAuthenticationtimestamp();
370 - $this->mRealName = ($wgAllowRealName) ? $wgUser->getRealName() : '';
371 -
372 - # language value might be blank, default to content language
373 - $this->mUserLanguage = $wgUser->getOption( 'language', $wgContLanguageCode );
374 -
375 - $this->mUserVariant = $wgUser->getOption( 'variant');
376 - $this->mEmailFlag = $wgUser->getOption( 'disablemail' ) == 1 ? 1 : 0;
377 - $this->mNick = $wgUser->getOption( 'nickname' );
378 -
379 - $this->mQuickbar = $wgUser->getOption( 'quickbar' );
380 - $this->mSkin = Skin::normalizeKey( $wgUser->getOption( 'skin' ) );
381 - $this->mMath = $wgUser->getOption( 'math' );
382 - $this->mDate = $wgUser->getDatePreference();
383 - $this->mRows = $wgUser->getOption( 'rows' );
384 - $this->mCols = $wgUser->getOption( 'cols' );
385 - $this->mStubs = $wgUser->getOption( 'stubthreshold' );
386 -
387 - $tz = $wgUser->getOption( 'timecorrection' );
388 - $data = explode( '|', $tz, 3 );
389 - $minDiff = null;
390 - switch ( $data[0] ) {
391 - case 'ZoneInfo':
392 - $this->mTimeZone = $tz;
393 - # Check if the specified TZ exists, and change to 'Offset' if
394 - # not.
395 - if ( !function_exists('timezone_open') || @timezone_open( $data[2] ) === false ) {
396 - $this->mTimeZone = 'Offset';
397 - $minDiff = intval( $data[1] );
398 - }
399 - break;
400 - case '':
401 - case 'System':
402 - $this->mTimeZone = 'System|'.$wgLocalTZoffset;
403 - break;
404 - case 'Offset':
405 - $this->mTimeZone = 'Offset';
406 - $minDiff = intval( $data[1] );
407 - break;
408 - default:
409 - $this->mTimeZone = 'Offset';
410 - $data = explode( ':', $tz, 2 );
411 - if( count( $data ) == 2 ) {
412 - $data[0] = intval( $data[0] );
413 - $data[1] = intval( $data[1] );
414 - $minDiff = abs( $data[0] ) * 60 + $data[1];
415 - if ( $data[0] < 0 ) $minDiff = -$minDiff;
416 - } else {
417 - $minDiff = intval( $data[0] ) * 60;
418 - }
419 - break;
420 - }
421 - if ( is_null( $minDiff ) ) {
422 - $this->mHourDiff = '';
423 - } else {
424 - $this->mHourDiff = sprintf( '%+03d:%02d', floor($minDiff/60), abs($minDiff)%60 );
425 - }
426 -
427 - $this->mSearch = $wgUser->getOption( 'searchlimit' );
428 - $this->mSearchLines = $wgUser->getOption( 'contextlines' );
429 - $this->mSearchChars = $wgUser->getOption( 'contextchars' );
430 - $this->mImageSize = $wgUser->getOption( 'imagesize' );
431 - $this->mThumbSize = $wgUser->getOption( 'thumbsize' );
432 - $this->mRecent = $wgUser->getOption( 'rclimit' );
433 - $this->mRecentDays = $wgUser->getOption( 'rcdays' );
434 - $this->mWatchlistEdits = $wgUser->getOption( 'wllimit' );
435 - $this->mUnderline = $wgUser->getOption( 'underline' );
436 - $this->mWatchlistDays = $wgUser->getOption( 'watchlistdays' );
437 - $this->mDisableMWSuggest = $wgUser->getBoolOption( 'disablesuggest' );
438 - $this->mGender = $wgUser->getOption( 'gender' );
439 -
440 - $togs = User::getToggles();
441 - foreach ( $togs as $tname ) {
442 - $this->mToggles[$tname] = $wgUser->getOption( $tname );
443 - }
444 -
445 - $namespaces = $wgContLang->getNamespaces();
446 - foreach ( $namespaces as $i => $namespace ) {
447 - if ( $i >= NS_MAIN ) {
448 - $this->mSearchNs[$i] = $wgUser->getOption( 'searchNs'.$i );
449 - }
450 - }
451 -
452 - wfRunHooks( 'ResetPreferences', array( $this, $wgUser ) );
453 - }
4548
455 - /**
456 - * @access private
457 - */
458 - function restorePreferences() {
459 - global $wgUser, $wgOut;
460 - $wgUser->restoreOptions();
461 - $wgUser->setCookies();
462 - $wgUser->saveSettings();
463 - $title = SpecialPage::getTitleFor( 'Preferences' );
464 - $wgOut->redirect( $title->getFullURL( 'success' ) );
 9+ function execute( $par ) {
 10+ global $wgOut, $wgUser;
 11+
 12+ $wgOut->setPageTitle( wfMsg( 'preferences' ) );
 13+
 14+ $formDescriptor = Preferences::getPreferences( $wgUser );
 15+
 16+ $htmlForm = new HTMLForm( $formDescriptor, 'prefs' );
 17+
 18+ $htmlForm->setSubmitText( wfMsg('saveprefs') );
 19+ $htmlForm->setTitle( $this->getTitle() );
 20+ $htmlForm->setSubmitCallback( array( 'SpecialPreferences', 'trySubmit' ) );
 21+
 22+ $htmlForm->show();
46523 }
466 -
467 - /**
468 - * @access private
469 - */
470 - function namespacesCheckboxes() {
471 - global $wgContLang;
472 -
473 - # Determine namespace checkboxes
474 - $namespaces = $wgContLang->getNamespaces();
475 - $r1 = null;
476 -
477 - foreach ( $namespaces as $i => $name ) {
478 - if ($i < 0)
479 - continue;
480 - $checked = $this->mSearchNs[$i] ? "checked='checked'" : '';
481 - $name = str_replace( '_', ' ', $namespaces[$i] );
482 -
483 - if ( empty($name) )
484 - $name = wfMsg( 'blanknamespace' );
485 -
486 - $r1 .= "<input type='checkbox' value='1' name='wpNs$i' id='wpNs$i' {$checked}/> <label for='wpNs$i'>{$name}</label><br />\n";
487 - }
488 - return $r1;
489 - }
490 -
491 -
492 - function getToggle( $tname, $trailer = false, $disabled = false ) {
493 - global $wgUser, $wgLang;
494 -
495 - $this->mUsedToggles[$tname] = true;
496 - $ttext = $wgLang->getUserToggle( $tname );
497 -
498 - $checked = $wgUser->getOption( $tname ) == 1 ? ' checked="checked"' : '';
499 - $disabled = $disabled ? ' disabled="disabled"' : '';
500 - $trailer = $trailer ? $trailer : '';
501 - return "<div class='toggle'><input type='checkbox' value='1' id=\"$tname\" name=\"wpOp$tname\"$checked$disabled />" .
502 - " <span class='toggletext'><label for=\"$tname\">$ttext</label>$trailer</span></div>\n";
503 - }
504 -
505 - function getToggles( $items ) {
506 - $out = "";
507 - foreach( $items as $item ) {
508 - if( $item === false )
509 - continue;
510 - if( is_array( $item ) ) {
511 - list( $key, $trailer ) = $item;
512 - } else {
513 - $key = $item;
514 - $trailer = false;
515 - }
516 - $out .= $this->getToggle( $key, $trailer );
517 - }
518 - return $out;
519 - }
520 -
521 - function addRow($td1, $td2) {
522 - return "<tr><td class='mw-label'>$td1</td><td class='mw-input'>$td2</td></tr>";
523 - }
524 -
525 - /**
526 - * Helper function for user information panel
527 - * @param $td1 label for an item
528 - * @param $td2 item or null
529 - * @param $td3 optional help or null
530 - * @return xhtml block
531 - */
532 - function tableRow( $td1, $td2 = null, $td3 = null ) {
533 -
534 - if ( is_null( $td3 ) ) {
535 - $td3 = '';
536 - } else {
537 - $td3 = Xml::tags( 'tr', null,
538 - Xml::tags( 'td', array( 'class' => 'pref-label', 'colspan' => '2' ), $td3 )
 24+
 25+ static function trySubmit( $formData ) {
 26+ global $wgUser;
 27+
 28+ // Stuff that shouldn't be saved as a preference.
 29+ $saveBlacklist = array(
 30+ 'realname',
 31+ 'emailaddress',
53932 );
 33+
 34+ foreach( $saveBlacklist as $b )
 35+ unset( $formData[$b] );
 36+
 37+ foreach( $formData as $key => $value ) {
 38+ $wgUser->setOption( $key, $value );
54039 }
541 -
542 - if ( is_null( $td2 ) ) {
543 - $td1 = Xml::tags( 'td', array( 'class' => 'pref-label', 'colspan' => '2' ), $td1 );
544 - $td2 = '';
545 - } else {
546 - $td1 = Xml::tags( 'td', array( 'class' => 'pref-label' ), $td1 );
547 - $td2 = Xml::tags( 'td', array( 'class' => 'pref-input' ), $td2 );
548 - }
549 -
550 - return Xml::tags( 'tr', null, $td1 . $td2 ). $td3 . "\n";
551 -
 40+
 41+ $wgUser->saveSettings();
 42+
 43+ return true;
55244 }
553 -
554 - /**
555 - * @access private
556 - */
557 - function mainPrefsForm( $status , $message = '' ) {
558 - global $wgUser, $wgOut, $wgLang, $wgContLang, $wgAuth;
559 - global $wgAllowRealName, $wgImageLimits, $wgThumbLimits;
560 - global $wgDisableLangConversion, $wgDisableTitleConversion;
561 - global $wgEnotifWatchlist, $wgEnotifUserTalk,$wgEnotifMinorEdits;
562 - global $wgRCShowWatchingUsers, $wgEnotifRevealEditorAddress;
563 - global $wgEnableEmail, $wgEnableUserEmail, $wgEmailAuthentication;
564 - global $wgContLanguageCode, $wgDefaultSkin, $wgCookieExpiration;
565 - global $wgEmailConfirmToEdit, $wgEnableMWSuggest, $wgLocalTZoffset;
566 -
567 - $wgOut->setPageTitle( wfMsg( 'preferences' ) );
568 - $wgOut->setArticleRelated( false );
569 - $wgOut->setRobotPolicy( 'noindex,nofollow' );
570 - $wgOut->addScriptFile( 'prefs.js' );
571 -
572 - $wgOut->disallowUserJs(); # Prevent hijacked user scripts from sniffing passwords etc.
573 -
574 - if ( $this->mSuccess || 'success' == $status ) {
575 - $wgOut->wrapWikiMsg( '<div class="successbox"><strong>$1</strong></div>', 'savedprefs' );
576 - } else if ( 'error' == $status ) {
577 - $wgOut->addWikiText( '<div class="errorbox"><strong>' . $message . '</strong></div>' );
578 - } else if ( '' != $status ) {
579 - $wgOut->addWikiText( $message . "\n----" );
580 - }
581 -
582 - $qbs = $wgLang->getQuickbarSettings();
583 - $mathopts = $wgLang->getMathNames();
584 - $dateopts = $wgLang->getDatePreferences();
585 - $togs = User::getToggles();
586 -
587 - $titleObj = SpecialPage::getTitleFor( 'Preferences' );
588 -
589 - # Pre-expire some toggles so they won't show if disabled
590 - $this->mUsedToggles[ 'shownumberswatching' ] = true;
591 - $this->mUsedToggles[ 'showupdated' ] = true;
592 - $this->mUsedToggles[ 'enotifwatchlistpages' ] = true;
593 - $this->mUsedToggles[ 'enotifusertalkpages' ] = true;
594 - $this->mUsedToggles[ 'enotifminoredits' ] = true;
595 - $this->mUsedToggles[ 'enotifrevealaddr' ] = true;
596 - $this->mUsedToggles[ 'ccmeonemails' ] = true;
597 - $this->mUsedToggles[ 'uselivepreview' ] = true;
598 - $this->mUsedToggles[ 'noconvertlink' ] = true;
599 -
600 -
601 - if ( !$this->mEmailFlag ) { $emfc = 'checked="checked"'; }
602 - else { $emfc = ''; }
603 -
604 -
605 - if ($wgEmailAuthentication && ($this->mUserEmail != '') ) {
606 - if( $wgUser->getEmailAuthenticationTimestamp() ) {
607 - // date and time are separate parameters to facilitate localisation.
608 - // $time is kept for backward compat reasons.
609 - // 'emailauthenticated' is also used in SpecialConfirmemail.php
610 - $time = $wgLang->timeAndDate( $wgUser->getEmailAuthenticationTimestamp(), true );
611 - $d = $wgLang->date( $wgUser->getEmailAuthenticationTimestamp(), true );
612 - $t = $wgLang->time( $wgUser->getEmailAuthenticationTimestamp(), true );
613 - $emailauthenticated = wfMsg('emailauthenticated', $time, $d, $t ).'<br />';
614 - $disableEmailPrefs = false;
615 - } else {
616 - $disableEmailPrefs = true;
617 - $skin = $wgUser->getSkin();
618 - $emailauthenticated = wfMsg('emailnotauthenticated').'<br />' .
619 - $skin->makeKnownLinkObj( SpecialPage::getTitleFor( 'Confirmemail' ),
620 - wfMsg( 'emailconfirmlink' ) ) . '<br />';
621 - }
622 - } else {
623 - $emailauthenticated = '';
624 - $disableEmailPrefs = false;
625 - }
626 -
627 - if ($this->mUserEmail == '') {
628 - $emailauthenticated = wfMsg( 'noemailprefs' ) . '<br />';
629 - }
630 -
631 - $ps = $this->namespacesCheckboxes();
632 -
633 - $enotifwatchlistpages = ($wgEnotifWatchlist) ? $this->getToggle( 'enotifwatchlistpages', false, $disableEmailPrefs ) : '';
634 - $enotifusertalkpages = ($wgEnotifUserTalk) ? $this->getToggle( 'enotifusertalkpages', false, $disableEmailPrefs ) : '';
635 - $enotifminoredits = ($wgEnotifWatchlist && $wgEnotifMinorEdits) ? $this->getToggle( 'enotifminoredits', false, $disableEmailPrefs ) : '';
636 - $enotifrevealaddr = (($wgEnotifWatchlist || $wgEnotifUserTalk) && $wgEnotifRevealEditorAddress) ? $this->getToggle( 'enotifrevealaddr', false, $disableEmailPrefs ) : '';
637 -
638 - # </FIXME>
639 -
640 - $wgOut->addHTML(
641 - Xml::openElement( 'form', array(
642 - 'action' => $titleObj->getLocalUrl(),
643 - 'method' => 'post',
644 - 'id' => 'mw-preferences-form',
645 - ) ) .
646 - Xml::openElement( 'div', array( 'id' => 'preferences' ) )
647 - );
648 -
649 - # User data
650 -
651 - $wgOut->addHTML(
652 - Xml::fieldset( wfMsg('prefs-personal') ) .
653 - Xml::openElement( 'table' ) .
654 - $this->tableRow( Xml::element( 'h2', null, wfMsg( 'prefs-personal' ) ) )
655 - );
656 -
657 - # Get groups to which the user belongs
658 - $userEffectiveGroups = $wgUser->getEffectiveGroups();
659 - $userEffectiveGroupsArray = array();
660 - foreach( $userEffectiveGroups as $ueg ) {
661 - if( $ueg == '*' ) {
662 - // Skip the default * group, seems useless here
663 - continue;
664 - }
665 - $userEffectiveGroupsArray[] = User::makeGroupLinkHTML( $ueg );
666 - }
667 - asort( $userEffectiveGroupsArray );
668 -
669 - $sk = $wgUser->getSkin();
670 - $toolLinks = array();
671 - $toolLinks[] = $sk->makeKnownLinkObj( SpecialPage::getTitleFor( 'ListGroupRights' ), wfMsg( 'listgrouprights' ) );
672 - # At the moment one tool link only but be prepared for the future...
673 - # FIXME: Add a link to Special:Userrights for users who are allowed to use it.
674 - # $wgUser->isAllowed( 'userrights' ) seems to strict in some cases
675 -
676 - $userInformationHtml =
677 - $this->tableRow( wfMsgHtml( 'username' ), htmlspecialchars( $wgUser->getName() ) ) .
678 - $this->tableRow( wfMsgHtml( 'uid' ), htmlspecialchars( $wgUser->getId() ) ) .
679 -
680 - $this->tableRow(
681 - wfMsgExt( 'prefs-memberingroups', array( 'parseinline' ), count( $userEffectiveGroupsArray ) ),
682 - $wgLang->commaList( $userEffectiveGroupsArray ) .
683 - '<br />(' . $wgLang->pipeList( $toolLinks ) . ')'
684 - ) .
685 -
686 - $this->tableRow(
687 - wfMsgHtml( 'prefs-edits' ),
688 - $wgLang->formatNum( $wgUser->getEditCount() )
689 - );
690 -
691 - if( wfRunHooks( 'PreferencesUserInformationPanel', array( $this, &$userInformationHtml ) ) ) {
692 - $wgOut->addHTML( $userInformationHtml );
693 - }
694 -
695 - if ( $wgAllowRealName ) {
696 - $wgOut->addHTML(
697 - $this->tableRow(
698 - Xml::label( wfMsg('yourrealname'), 'wpRealName' ),
699 - Xml::input( 'wpRealName', 25, $this->mRealName, array( 'id' => 'wpRealName' ) ),
700 - Xml::tags('div', array( 'class' => 'prefsectiontip' ),
701 - wfMsgExt( 'prefs-help-realname', 'parseinline' )
702 - )
703 - )
704 - );
705 - }
706 - if ( $wgEnableEmail ) {
707 - $wgOut->addHTML(
708 - $this->tableRow(
709 - Xml::label( wfMsg('youremail'), 'wpUserEmail' ),
710 - Xml::input( 'wpUserEmail', 25, $this->mUserEmail, array( 'id' => 'wpUserEmail' ) ),
711 - Xml::tags('div', array( 'class' => 'prefsectiontip' ),
712 - wfMsgExt( $wgEmailConfirmToEdit ? 'prefs-help-email-required' : 'prefs-help-email', 'parseinline' )
713 - )
714 - )
715 - );
716 - }
717 -
718 - global $wgParser, $wgMaxSigChars;
719 - if( mb_strlen( $this->mNick ) > $wgMaxSigChars ) {
720 - $invalidSig = $this->tableRow(
721 - '&nbsp;',
722 - Xml::element( 'span', array( 'class' => 'error' ),
723 - wfMsgExt( 'badsiglength', 'parsemag', $wgLang->formatNum( $wgMaxSigChars ) ) )
724 - );
725 - } elseif( !empty( $this->mToggles['fancysig'] ) &&
726 - false === $wgParser->validateSig( $this->mNick ) ) {
727 - $invalidSig = $this->tableRow(
728 - '&nbsp;',
729 - Xml::element( 'span', array( 'class' => 'error' ), wfMsg( 'badsig' ) )
730 - );
731 - } else {
732 - $invalidSig = '';
733 - }
734 -
735 - $wgOut->addHTML(
736 - $this->tableRow(
737 - Xml::label( wfMsg( 'yournick' ), 'wpNick' ),
738 - Xml::input( 'wpNick', 25, $this->mNick,
739 - array(
740 - 'id' => 'wpNick',
741 - // Note: $wgMaxSigChars is enforced in Unicode characters,
742 - // both on the backend and now in the browser.
743 - // Badly-behaved requests may still try to submit
744 - // an overlong string, however.
745 - 'maxlength' => $wgMaxSigChars ) )
746 - ) .
747 - $invalidSig .
748 - $this->tableRow( '&nbsp;', $this->getToggle( 'fancysig' ) )
749 - );
750 -
751 - $gender = new XMLSelect( 'wpGender', 'wpGender', $this->mGender );
752 - $gender->addOption( wfMsg( 'gender-unknown' ), 'unknown' );
753 - $gender->addOption( wfMsg( 'gender-male' ), 'male' );
754 - $gender->addOption( wfMsg( 'gender-female' ), 'female' );
755 -
756 - $wgOut->addHTML(
757 - $this->tableRow(
758 - Xml::label( wfMsg( 'yourgender' ), 'wpGender' ),
759 - $gender->getHTML(),
760 - Xml::tags( 'div', array( 'class' => 'prefsectiontip' ),
761 - wfMsgExt( 'prefs-help-gender', 'parseinline' )
762 - )
763 - )
764 - );
765 -
766 - list( $lsLabel, $lsSelect) = Xml::languageSelector( $this->mUserLanguage, false );
767 - $wgOut->addHTML(
768 - $this->tableRow( $lsLabel, $lsSelect )
769 - );
770 -
771 - /* see if there are multiple language variants to choose from*/
772 - if(!$wgDisableLangConversion) {
773 - $variants = $wgContLang->getVariants();
774 - $variantArray = array();
775 -
776 - $languages = Language::getLanguageNames( true );
777 - foreach($variants as $v) {
778 - $v = str_replace( '_', '-', strtolower($v));
779 - if( array_key_exists( $v, $languages ) ) {
780 - // If it doesn't have a name, we'll pretend it doesn't exist
781 - $variantArray[$v] = $languages[$v];
782 - }
783 - }
784 -
785 - $options = "\n";
786 - foreach( $variantArray as $code => $name ) {
787 - $selected = ($code == $this->mUserVariant);
788 - $options .= Xml::option( "$code - $name", $code, $selected ) . "\n";
789 - }
790 -
791 - if(count($variantArray) > 1) {
792 - $wgOut->addHTML(
793 - $this->tableRow(
794 - Xml::label( wfMsg( 'yourvariant' ), 'wpUserVariant' ),
795 - Xml::tags( 'select',
796 - array( 'name' => 'wpUserVariant', 'id' => 'wpUserVariant' ),
797 - $options
798 - )
799 - )
800 - );
801 - }
802 -
803 - if(count($variantArray) > 1 && !$wgDisableLangConversion && !$wgDisableTitleConversion) {
804 - $wgOut->addHTML(
805 - Xml::tags( 'tr', null,
806 - Xml::tags( 'td', array( 'colspan' => '2' ),
807 - $this->getToggle( "noconvertlink" )
808 - )
809 - )
810 - );
811 - }
812 - }
813 -
814 - # Password
815 - if( $wgAuth->allowPasswordChange() ) {
816 - $link = $wgUser->getSkin()->link( SpecialPage::getTitleFor( 'ResetPass' ), wfMsgHtml( 'prefs-resetpass' ),
817 - array() , array('returnto' => SpecialPage::getTitleFor( 'Preferences') ) );
818 - $wgOut->addHTML(
819 - $this->tableRow( Xml::element( 'h2', null, wfMsg( 'changepassword' ) ) ) .
820 - $this->tableRow( '<ul><li>' . $link . '</li></ul>' ) );
821 - }
822 -
823 - # <FIXME>
824 - # Enotif
825 - if ( $wgEnableEmail ) {
826 -
827 - $moreEmail = '';
828 - if ($wgEnableUserEmail) {
829 - // fixme -- the "allowemail" pseudotoggle is a hacked-together
830 - // inversion for the "disableemail" preference.
831 - $emf = wfMsg( 'allowemail' );
832 - $disabled = $disableEmailPrefs ? ' disabled="disabled"' : '';
833 - $moreEmail =
834 - "<input type='checkbox' $emfc $disabled value='1' name='wpEmailFlag' id='wpEmailFlag' /> <label for='wpEmailFlag'>$emf</label>" .
835 - $this->getToggle( 'ccmeonemails', '', $disableEmailPrefs );
836 - }
837 -
838 -
839 - $wgOut->addHTML(
840 - $this->tableRow( Xml::element( 'h2', null, wfMsg( 'email' ) ) ) .
841 - $this->tableRow(
842 - $emailauthenticated.
843 - $enotifrevealaddr.
844 - $enotifwatchlistpages.
845 - $enotifusertalkpages.
846 - $enotifminoredits.
847 - $moreEmail
848 - )
849 - );
850 - }
851 - # </FIXME>
852 -
853 - $wgOut->addHTML(
854 - Xml::closeElement( 'table' ) .
855 - Xml::closeElement( 'fieldset' )
856 - );
857 -
858 -
859 - # Quickbar
860 - #
861 - if ($this->mSkin == 'cologneblue' || $this->mSkin == 'standard') {
862 - $wgOut->addHTML( "<fieldset>\n<legend>" . wfMsg( 'qbsettings' ) . "</legend>\n" );
863 - for ( $i = 0; $i < count( $qbs ); ++$i ) {
864 - if ( $i == $this->mQuickbar ) { $checked = ' checked="checked"'; }
865 - else { $checked = ""; }
866 - $wgOut->addHTML( "<div><label><input type='radio' name='wpQuickbar' value=\"$i\"$checked />{$qbs[$i]}</label></div>\n" );
867 - }
868 - $wgOut->addHTML( "</fieldset>\n\n" );
869 - } else {
870 - # Need to output a hidden option even if the relevant skin is not in use,
871 - # otherwise the preference will get reset to 0 on submit
872 - $wgOut->addHTML( Xml::hidden( 'wpQuickbar', $this->mQuickbar ) );
873 - }
874 -
875 - # Skin
876 - #
877 - global $wgAllowUserSkin;
878 - if( $wgAllowUserSkin ) {
879 - $wgOut->addHTML( "<fieldset>\n<legend>\n" . wfMsg( 'skin' ) . "</legend>\n" );
880 - $mptitle = Title::newMainPage();
881 - $previewtext = wfMsg( 'skin-preview' );
882 - # Only show members of Skin::getSkinNames() rather than
883 - # $skinNames (skins is all skin names from Language.php)
884 - $validSkinNames = Skin::getUsableSkins();
885 - # Sort by UI skin name. First though need to update validSkinNames as sometimes
886 - # the skinkey & UI skinname differ (e.g. "standard" skinkey is "Classic" in the UI).
887 - foreach ( $validSkinNames as $skinkey => &$skinname ) {
888 - $msgName = "skinname-{$skinkey}";
889 - $localisedSkinName = wfMsg( $msgName );
890 - if ( !wfEmptyMsg( $msgName, $localisedSkinName ) ) {
891 - $skinname = $localisedSkinName;
892 - }
893 - }
894 - asort($validSkinNames);
895 - foreach( $validSkinNames as $skinkey => $sn ) {
896 - $checked = $skinkey == $this->mSkin ? ' checked="checked"' : '';
897 - $mplink = htmlspecialchars( $mptitle->getLocalURL( "useskin=$skinkey" ) );
898 - $previewlink = "(<a target='_blank' href=\"$mplink\">$previewtext</a>)";
899 - $extraLinks = '';
900 - global $wgAllowUserCss, $wgAllowUserJs;
901 - if( $wgAllowUserCss ) {
902 - $cssPage = Title::makeTitleSafe( NS_USER, $wgUser->getName().'/'.$skinkey.'.css' );
903 - $customCSS = $sk->makeLinkObj( $cssPage, wfMsgExt('prefs-custom-css', array() ) );
904 - $extraLinks .= " ($customCSS)";
905 - }
906 - if( $wgAllowUserJs ) {
907 - $jsPage = Title::makeTitleSafe( NS_USER, $wgUser->getName().'/'.$skinkey.'.js' );
908 - $customJS = $sk->makeLinkObj( $jsPage, wfMsgHtml('prefs-custom-js') );
909 - $extraLinks .= " ($customJS)";
910 - }
911 - if( $skinkey == $wgDefaultSkin )
912 - $sn .= ' (' . wfMsg( 'default' ) . ')';
913 - $wgOut->addHTML( "<input type='radio' name='wpSkin' id=\"wpSkin$skinkey\" value=\"$skinkey\"$checked />
914 - <label for=\"wpSkin$skinkey\">{$sn}</label> $previewlink{$extraLinks}<br />\n" );
915 - }
916 - $wgOut->addHTML( "</fieldset>\n\n" );
917 - }
918 -
919 - # Math
920 - #
921 - global $wgUseTeX;
922 - if( $wgUseTeX ) {
923 - $wgOut->addHTML( "<fieldset>\n<legend>" . wfMsg('math') . '</legend>' );
924 - foreach ( $mathopts as $k => $v ) {
925 - $checked = ($k == $this->mMath);
926 - $wgOut->addHTML(
927 - Xml::openElement( 'div' ) .
928 - Xml::radioLabel( wfMsg( $v ), 'wpMath', $k, "mw-sp-math-$k", $checked ) .
929 - Xml::closeElement( 'div' ) . "\n"
930 - );
931 - }
932 - $wgOut->addHTML( "</fieldset>\n\n" );
933 - }
934 -
935 - # Files
936 - #
937 - $imageLimitOptions = null;
938 - foreach ( $wgImageLimits as $index => $limits ) {
939 - $selected = ($index == $this->mImageSize);
940 - $imageLimitOptions .= Xml::option( "{$limits[0]}×{$limits[1]}" .
941 - wfMsg('unit-pixel'), $index, $selected );
942 - }
943 -
944 - $imageThumbOptions = null;
945 - foreach ( $wgThumbLimits as $index => $size ) {
946 - $selected = ($index == $this->mThumbSize);
947 - $imageThumbOptions .= Xml::option($size . wfMsg('unit-pixel'), $index,
948 - $selected);
949 - }
950 -
951 - $imageSizeId = 'wpImageSize';
952 - $thumbSizeId = 'wpThumbSize';
953 - $wgOut->addHTML(
954 - Xml::fieldset( wfMsg( 'files' ) ) . "\n" .
955 - Xml::openElement( 'table' ) .
956 - '<tr>
957 - <td class="mw-label">' .
958 - Xml::label( wfMsg( 'imagemaxsize' ), $imageSizeId ) .
959 - '</td>
960 - <td class="mw-input">' .
961 - Xml::openElement( 'select', array( 'name' => $imageSizeId, 'id' => $imageSizeId ) ) .
962 - $imageLimitOptions .
963 - Xml::closeElement( 'select' ) .
964 - '</td>
965 - </tr><tr>
966 - <td class="mw-label">' .
967 - Xml::label( wfMsg( 'thumbsize' ), $thumbSizeId ) .
968 - '</td>
969 - <td class="mw-input">' .
970 - Xml::openElement( 'select', array( 'name' => $thumbSizeId, 'id' => $thumbSizeId ) ) .
971 - $imageThumbOptions .
972 - Xml::closeElement( 'select' ) .
973 - '</td>
974 - </tr>' .
975 - Xml::closeElement( 'table' ) .
976 - Xml::closeElement( 'fieldset' )
977 - );
978 -
979 - # Date format
980 - #
981 - # Date/Time
982 - #
983 -
984 - $wgOut->addHTML(
985 - Xml::openElement( 'fieldset' ) .
986 - Xml::element( 'legend', null, wfMsg( 'datetime' ) ) . "\n"
987 - );
988 -
989 - if ($dateopts) {
990 - $wgOut->addHTML(
991 - Xml::openElement( 'fieldset' ) .
992 - Xml::element( 'legend', null, wfMsg( 'dateformat' ) ) . "\n"
993 - );
994 - $idCnt = 0;
995 - $epoch = '20010115161234'; # Wikipedia day
996 - foreach( $dateopts as $key ) {
997 - if( $key == 'default' ) {
998 - $formatted = wfMsg( 'datedefault' );
999 - } else {
1000 - $formatted = $wgLang->timeanddate( $epoch, false, $key );
1001 - }
1002 - $wgOut->addHTML(
1003 - Xml::tags( 'div', null,
1004 - Xml::radioLabel( $formatted, 'wpDate', $key, "wpDate$idCnt", $key == $this->mDate )
1005 - ) . "\n"
1006 - );
1007 - $idCnt++;
1008 - }
1009 - $wgOut->addHTML( Xml::closeElement( 'fieldset' ) . "\n" );
1010 - }
1011 -
1012 - $nowlocal = Xml::openElement( 'span', array( 'id' => 'wpLocalTime' ) ) .
1013 - $wgLang->time( $now = wfTimestampNow(), true ) .
1014 - Xml::closeElement( 'span' );
1015 - $nowserver = $wgLang->time( $now, false ) .
1016 - Xml::hidden( 'wpServerTime', substr( $now, 8, 2 ) * 60 + substr( $now, 10, 2 ) );
1017 -
1018 - $wgOut->addHTML(
1019 - Xml::openElement( 'fieldset' ) .
1020 - Xml::element( 'legend', null, wfMsg( 'timezonelegend' ) ) .
1021 - Xml::openElement( 'table' ) .
1022 - $this->addRow( wfMsg( 'servertime' ), $nowserver ) .
1023 - $this->addRow( wfMsg( 'localtime' ), $nowlocal )
1024 - );
1025 - $opt = Xml::openElement( 'select', array(
1026 - 'name' => 'wpTimeZone',
1027 - 'id' => 'wpTimeZone',
1028 - 'onchange' => 'javascript:updateTimezoneSelection(false)' ) );
1029 - $opt .= Xml::option( wfMsg( 'timezoneuseserverdefault' ), "System|$wgLocalTZoffset", $this->mTimeZone === "System|$wgLocalTZoffset" );
1030 - $opt .= Xml::option( wfMsg( 'timezoneuseoffset' ), 'Offset', $this->mTimeZone === 'Offset' );
1031 -
1032 - if ( function_exists( 'timezone_identifiers_list' ) ) {
1033 - # Read timezone list
1034 - $tzs = timezone_identifiers_list();
1035 - sort( $tzs );
1036 -
1037 - # Precache localized region names
1038 - $tzRegions = array();
1039 - $tzRegions['Africa'] = wfMsg( 'timezoneregion-africa' );
1040 - $tzRegions['America'] = wfMsg( 'timezoneregion-america' );
1041 - $tzRegions['Antarctica'] = wfMsg( 'timezoneregion-antarctica' );
1042 - $tzRegions['Arctic'] = wfMsg( 'timezoneregion-arctic' );
1043 - $tzRegions['Asia'] = wfMsg( 'timezoneregion-asia' );
1044 - $tzRegions['Atlantic'] = wfMsg( 'timezoneregion-atlantic' );
1045 - $tzRegions['Australia'] = wfMsg( 'timezoneregion-australia' );
1046 - $tzRegions['Europe'] = wfMsg( 'timezoneregion-europe' );
1047 - $tzRegions['Indian'] = wfMsg( 'timezoneregion-indian' );
1048 - $tzRegions['Pacific'] = wfMsg( 'timezoneregion-pacific' );
1049 - asort( $tzRegions );
1050 -
1051 - $selZone = explode( '|', $this->mTimeZone, 3 );
1052 - $selZone = ( $selZone[0] == 'ZoneInfo' ) ? $selZone[2] : null;
1053 - $now = date_create( 'now' );
1054 - $optgroup = '';
1055 -
1056 - foreach ( $tzs as $tz ) {
1057 - $z = explode( '/', $tz, 2 );
1058 -
1059 - # timezone_identifiers_list() returns a number of
1060 - # backwards-compatibility entries. This filters them out of the
1061 - # list presented to the user.
1062 - if ( count( $z ) != 2 || !array_key_exists( $z[0], $tzRegions ) )
1063 - continue;
1064 -
1065 - # Localize region
1066 - $z[0] = $tzRegions[$z[0]];
1067 -
1068 - # Create region groups
1069 - if ( $optgroup != $z[0] ) {
1070 - if ( $optgroup !== '' ) {
1071 - $opt .= Xml::closeElement( 'optgroup' );
1072 - }
1073 - $optgroup = $z[0];
1074 - $opt .= Xml::openElement( 'optgroup', array( 'label' => $z[0] ) ) . "\n";
1075 - }
1076 -
1077 - $minDiff = floor( timezone_offset_get( timezone_open( $tz ), $now ) / 60 );
1078 - $opt .= Xml::option( str_replace( '_', ' ', $z[0] . '/' . $z[1] ), "ZoneInfo|$minDiff|$tz", $selZone === $tz, array( 'label' => $z[1] ) ) . "\n";
1079 - }
1080 - if ( $optgroup !== '' ) $opt .= Xml::closeElement( 'optgroup' );
1081 - }
1082 - $opt .= Xml::closeElement( 'select' );
1083 - $wgOut->addHTML(
1084 - $this->addRow(
1085 - Xml::label( wfMsg( 'timezoneselect' ), 'wpTimeZone' ),
1086 - $opt )
1087 - );
1088 - $wgOut->addHTML(
1089 - $this->addRow(
1090 - Xml::label( wfMsg( 'timezoneoffset' ), 'wpHourDiff' ),
1091 - Xml::input( 'wpHourDiff', 6, $this->mHourDiff, array(
1092 - 'id' => 'wpHourDiff',
1093 - 'onfocus' => 'javascript:updateTimezoneSelection(true)',
1094 - 'onblur' => 'javascript:updateTimezoneSelection(false)' ) ) ) .
1095 - "<tr>
1096 - <td></td>
1097 - <td class='mw-submit'>" .
1098 - Xml::element( 'input',
1099 - array( 'type' => 'button',
1100 - 'value' => wfMsg( 'guesstimezone' ),
1101 - 'onclick' => 'javascript:guessTimezone()',
1102 - 'id' => 'guesstimezonebutton',
1103 - 'style' => 'display:none;' ) ) .
1104 - "</td>
1105 - </tr>" .
1106 - Xml::closeElement( 'table' ) .
1107 - Xml::tags( 'div', array( 'class' => 'prefsectiontip' ), wfMsgExt( 'timezonetext', 'parseinline' ) ).
1108 - Xml::closeElement( 'fieldset' ) .
1109 - Xml::closeElement( 'fieldset' ) . "\n\n"
1110 - );
1111 -
1112 - # Editing
1113 - #
1114 - global $wgLivePreview;
1115 - $wgOut->addHTML(
1116 - Xml::fieldset( wfMsg( 'textboxsize' ) ) .
1117 - wfMsgHTML( 'prefs-edit-boxsize' ) . ' ' .
1118 - Xml::inputLabel( wfMsg( 'rows' ), 'wpRows', 'wpRows', 3, $this->mRows ) . ' ' .
1119 - Xml::inputLabel( wfMsg( 'columns' ), 'wpCols', 'wpCols', 3, $this->mCols ) .
1120 - $this->getToggles( array(
1121 - 'editsection',
1122 - 'editsectiononrightclick',
1123 - 'editondblclick',
1124 - 'editwidth',
1125 - 'showtoolbar',
1126 - 'previewonfirst',
1127 - 'previewontop',
1128 - 'minordefault',
1129 - 'externaleditor',
1130 - 'externaldiff',
1131 - $wgLivePreview ? 'uselivepreview' : false,
1132 - 'forceeditsummary',
1133 - ) )
1134 - );
1135 -
1136 - $wgOut->addHTML( Xml::closeElement( 'fieldset' ) );
1137 -
1138 - # Recent changes
1139 - global $wgRCMaxAge, $wgUseRCPatrol;
1140 - $wgOut->addHTML(
1141 - Xml::fieldset( wfMsg( 'prefs-rc' ) ) .
1142 - Xml::openElement( 'table' ) .
1143 - '<tr>
1144 - <td class="mw-label">' .
1145 - Xml::label( wfMsg( 'recentchangesdays' ), 'wpRecentDays' ) .
1146 - '</td>
1147 - <td class="mw-input">' .
1148 - Xml::input( 'wpRecentDays', 3, $this->mRecentDays, array( 'id' => 'wpRecentDays' ) ) . ' ' .
1149 - wfMsgExt( 'recentchangesdays-max', 'parsemag',
1150 - $wgLang->formatNum( ceil( $wgRCMaxAge / ( 3600 * 24 ) ) ) ) .
1151 - '</td>
1152 - </tr><tr>
1153 - <td class="mw-label">' .
1154 - Xml::label( wfMsg( 'recentchangescount' ), 'wpRecent' ) .
1155 - '</td>
1156 - <td class="mw-input">' .
1157 - Xml::input( 'wpRecent', 3, $this->mRecent, array( 'id' => 'wpRecent' ) ) .
1158 - '</td>
1159 - </tr>' .
1160 - Xml::closeElement( 'table' ) .
1161 - '<br />'
1162 - );
1163 -
1164 - $toggles[] = 'hideminor';
1165 - if( $wgUseRCPatrol ) {
1166 - $toggles[] = 'hidepatrolled';
1167 - $toggles[] = 'newpageshidepatrolled';
1168 - }
1169 - if( $wgRCShowWatchingUsers ) $toggles[] = 'shownumberswatching';
1170 - $toggles[] = 'usenewrc';
1171 -
1172 - $wgOut->addHTML(
1173 - $this->getToggles( $toggles ) .
1174 - Xml::closeElement( 'fieldset' )
1175 - );
1176 -
1177 - # Watchlist
1178 - $watchlistToggles = array( 'watchlisthideminor', 'watchlisthidebots', 'watchlisthideown',
1179 - 'watchlisthideanons', 'watchlisthideliu' );
1180 - if( $wgUseRCPatrol ) $watchlistToggles[] = 'watchlisthidepatrolled';
1181 -
1182 - $wgOut->addHTML(
1183 - Xml::fieldset( wfMsg( 'prefs-watchlist' ) ) .
1184 - Xml::inputLabel( wfMsg( 'prefs-watchlist-days' ), 'wpWatchlistDays', 'wpWatchlistDays', 3, $this->mWatchlistDays ) . ' ' .
1185 - wfMsgHTML( 'prefs-watchlist-days-max' ) .
1186 - '<br /><br />' .
1187 - $this->getToggle( 'extendwatchlist' ) .
1188 - Xml::inputLabel( wfMsg( 'prefs-watchlist-edits' ), 'wpWatchlistEdits', 'wpWatchlistEdits', 3, $this->mWatchlistEdits ) . ' ' .
1189 - wfMsgHTML( 'prefs-watchlist-edits-max' ) .
1190 - '<br /><br />' .
1191 - $this->getToggles( $watchlistToggles )
1192 - );
1193 -
1194 - if( $wgUser->isAllowed( 'createpage' ) || $wgUser->isAllowed( 'createtalk' ) ) {
1195 - $wgOut->addHTML( $this->getToggle( 'watchcreations' ) );
1196 - }
1197 -
1198 - foreach( array( 'edit' => 'watchdefault', 'move' => 'watchmoves', 'delete' => 'watchdeletion' ) as $action => $toggle ) {
1199 - if( $wgUser->isAllowed( $action ) )
1200 - $wgOut->addHTML( $this->getToggle( $toggle ) );
1201 - }
1202 - $this->mUsedToggles['watchcreations'] = true;
1203 - $this->mUsedToggles['watchdefault'] = true;
1204 - $this->mUsedToggles['watchmoves'] = true;
1205 - $this->mUsedToggles['watchdeletion'] = true;
1206 -
1207 - $wgOut->addHTML( Xml::closeElement( 'fieldset' ) );
1208 -
1209 - # Search
1210 - $mwsuggest = $wgEnableMWSuggest ?
1211 - $this->addRow(
1212 - Xml::label( wfMsg( 'mwsuggest-disable' ), 'wpDisableMWSuggest' ),
1213 - Xml::check( 'wpDisableMWSuggest', $this->mDisableMWSuggest, array( 'id' => 'wpDisableMWSuggest' ) )
1214 - ) : '';
1215 - $wgOut->addHTML(
1216 - // Elements for the search tab itself
1217 - Xml::openElement( 'fieldset' ) .
1218 - Xml::element( 'legend', null, wfMsg( 'searchresultshead' ) ) .
1219 - // Elements for the search options in the search tab
1220 - Xml::openElement( 'fieldset' ) .
1221 - Xml::element( 'legend', null, wfMsg( 'prefs-searchoptions' ) ) .
1222 - Xml::openElement( 'table' ) .
1223 - $this->addRow(
1224 - Xml::label( wfMsg( 'resultsperpage' ), 'wpSearch' ),
1225 - Xml::input( 'wpSearch', 4, $this->mSearch, array( 'id' => 'wpSearch' ) )
1226 - ) .
1227 - $this->addRow(
1228 - Xml::label( wfMsg( 'contextlines' ), 'wpSearchLines' ),
1229 - Xml::input( 'wpSearchLines', 4, $this->mSearchLines, array( 'id' => 'wpSearchLines' ) )
1230 - ) .
1231 - $this->addRow(
1232 - Xml::label( wfMsg( 'contextchars' ), 'wpSearchChars' ),
1233 - Xml::input( 'wpSearchChars', 4, $this->mSearchChars, array( 'id' => 'wpSearchChars' ) )
1234 - ) .
1235 - $mwsuggest .
1236 - Xml::closeElement( 'table' ) .
1237 - Xml::closeElement( 'fieldset' ) .
1238 - // Elements for the namespace options in the search tab
1239 - Xml::openElement( 'fieldset' ) .
1240 - Xml::element( 'legend', null, wfMsg( 'prefs-namespaces' ) ) .
1241 - wfMsgExt( 'defaultns', array( 'parse' ) ) .
1242 - $ps .
1243 - Xml::closeElement( 'fieldset' ) .
1244 - // End of the search tab
1245 - Xml::closeElement( 'fieldset' )
1246 - );
1247 -
1248 - # Misc
1249 - #
1250 - $uopt = $wgUser->getOption( 'underline' );
1251 - $wgOut->addHTML(
1252 - Xml::fieldset( wfMsg( 'prefs-misc' ) ) .
1253 - Xml::openElement( 'table' ) .
1254 - '<tr>
1255 - <td class="mw-label">' .
1256 - // Xml::label() cannot be used because 'stub-threshold' contains plain HTML
1257 - Xml::tags( 'label', array( 'for' => 'wpStubs' ), wfMsg( 'stub-threshold' ) ) .
1258 - '</td>
1259 - <td class="mw-input">' .
1260 - Xml::input( 'wpStubs', 6, $this->mStubs, array( 'id' => 'wpStubs' ) ) .
1261 - '</td>
1262 - </tr><tr>
1263 - <td class="mw-label">' .
1264 - Xml::label( wfMsg( 'tog-underline' ), 'wpOpunderline' ) .
1265 - '</td>
1266 - <td class="mw-input">' .
1267 - Xml::openElement( 'select', array( 'id' => 'wpOpunderline', 'name' => 'wpOpunderline' ) ) .
1268 - Xml::option( wfMsg ( 'underline-never' ), '0', $uopt == 0 ) .
1269 - Xml::option( wfMsg ( 'underline-always' ), '1', $uopt == 1 ) .
1270 - Xml::option( wfMsg ( 'underline-default' ), '2', $uopt == 2 ) .
1271 - Xml::closeElement( 'select' ) .
1272 - '</td>
1273 - </tr>' .
1274 - Xml::closeElement( 'table' )
1275 - );
1276 -
1277 - # And now the rest = Misc.
1278 - foreach ( $togs as $tname ) {
1279 - if( !array_key_exists( $tname, $this->mUsedToggles ) ) {
1280 - if( $tname == 'norollbackdiff' && $wgUser->isAllowed( 'rollback' ) )
1281 - $wgOut->addHTML( $this->getToggle( $tname ) );
1282 - else
1283 - $wgOut->addHTML( $this->getToggle( $tname ) );
1284 - }
1285 - }
1286 -
1287 - $wgOut->addHTML( '</fieldset>' );
1288 -
1289 - wfRunHooks( 'RenderPreferencesForm', array( $this, $wgOut ) );
1290 -
1291 - $token = htmlspecialchars( $wgUser->editToken() );
1292 - $skin = $wgUser->getSkin();
1293 - $rtl = $wgContLang->isRTL() ? 'left' : 'right';
1294 - $wgOut->addHTML( "
1295 - <table id='prefsubmit' cellpadding='0' width='100%' style='background:none;'><tr>
1296 - <td><input type='submit' name='wpSaveprefs' class='btnSavePrefs' value=\"" . wfMsgHtml( 'saveprefs' ) .
1297 - '"'.$skin->tooltipAndAccesskey('save')." />
1298 - <input type='submit' name='wpReset' value=\"" . wfMsgHtml( 'resetprefs' ) . "\" /></td>
1299 - <td align='$rtl'><input type='submit' name='wpRestore' value=\"" . wfMsgHtml( 'restoreprefs' ) . "\" /></td>
1300 - </tr></table>
1301 -
1302 - <input type='hidden' name='wpEditToken' value=\"{$token}\" />
1303 - </div></form>\n" );
1304 -
1305 - $wgOut->addHTML( Xml::tags( 'div', array( 'class' => "prefcache" ),
1306 - wfMsgExt( 'clearyourcache', 'parseinline' ) )
1307 - );
1308 - }
130945 }
Index: branches/preferences-work/phase3/includes/SpecialPage.php
@@ -121,7 +121,7 @@
122122 'Ipblocklist' => array( 'SpecialPage', 'Ipblocklist' ),
123123 'Resetpass' => 'SpecialResetpass',
124124 'DeletedContributions' => 'DeletedContributionsPage',
125 - 'Preferences' => array( 'SpecialPage', 'Preferences' ),
 125+ 'Preferences' => 'SpecialPreferences',
126126 'Contributions' => 'SpecialContributions',
127127 'Listgrouprights' => 'SpecialListGroupRights',
128128 'Listusers' => array( 'SpecialPage', 'Listusers' ),

Status & tagging log