r49325 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r49324‎ | r49325 | r49326 >
Date:02:35, 9 April 2009
Author:werdna
Status:deferred
Tags:
Comment:

* Add the user information panel to the new preferences form.
* Add signature cleaning.
* Replace some $wgUser with $user.
* Prod form values in from the user object. Note that 'default' refers to 'state before any user input is given', and not 'preference default', which comes from the user object.
* Fix loadOptions() in User object.
* Add some stuff stored in the User object to the preferences list
Modified paths:
  • /branches/preferences-work/phase3/includes/HTMLForm.php (modified) (history)
  • /branches/preferences-work/phase3/includes/Preferences.php (modified) (history)
  • /branches/preferences-work/phase3/includes/User.php (modified) (history)
  • /branches/preferences-work/phase3/languages/messages/MessagesEn.php (modified) (history)

Diff [purge]

Index: branches/preferences-work/phase3/includes/User.php
@@ -1921,25 +1921,19 @@
19221922 */
19231923 function setOption( $oname, $val ) {
19241924 $this->load();
1925 - if ( is_null( $this->mOptions ) ) {
1926 - $this->mOptions = User::getDefaultOptions();
1927 - }
 1925+ $this->loadOptions();
 1926+
19281927 if ( $oname == 'skin' ) {
19291928 # Clear cached skin, so the new one displays immediately in Special:Preferences
19301929 unset( $this->mSkin );
19311930 }
1932 - // Filter out any newlines that may have passed through input validation.
1933 - // Newlines are used to separate items in the options blob.
1934 - if( $val ) {
1935 - $val = str_replace( "\r\n", "\n", $val );
1936 - $val = str_replace( "\r", "\n", $val );
1937 - $val = str_replace( "\n", " ", $val );
1938 - }
 1931+
19391932 // Explicitly NULL values should refer to defaults
19401933 global $wgDefaultUserOptions;
19411934 if( is_null($val) && isset($wgDefaultUserOptions[$oname]) ) {
19421935 $val = $wgDefaultUserOptions[$oname];
19431936 }
 1937+
19441938 $this->mOptions[$oname] = $val;
19451939 }
19461940
@@ -2288,24 +2282,6 @@
22892283 }
22902284
22912285 /**
2292 - * Encode this user's options as a string
2293 - * @return \string Encoded options
2294 - * @private
2295 - */
2296 - function encodeOptions() {
2297 - $this->load();
2298 - if ( is_null( $this->mOptions ) ) {
2299 - $this->mOptions = User::getDefaultOptions();
2300 - }
2301 - $a = array();
2302 - foreach ( $this->mOptions as $oname => $oval ) {
2303 - array_push( $a, $oname.'='.$oval );
2304 - }
2305 - $s = implode( "\n", $a );
2306 - return $s;
2307 - }
2308 -
2309 - /**
23102286 * Set this user's options from an encoded string
23112287 * @param $str \string Encoded options to import
23122288 * @private
@@ -3431,6 +3407,8 @@
34323408 while( $row = $dbr->fetchObject( $res ) ) {
34333409 $this->mOptions[$row->up_property] = unserialize( $row->up_value );
34343410 }
 3411+
 3412+ $this->mOptionsLoaded = true;
34353413 }
34363414
34373415 protected function saveOptions() {
Index: branches/preferences-work/phase3/includes/HTMLForm.php
@@ -18,6 +18,7 @@
1919 'check' => 'HTMLCheckField',
2020 'toggle' => 'HTMLCheckField',
2121 'int' => 'HTMLIntField',
 22+ 'info' => 'HTMLInfoField',
2223 );
2324
2425 function __construct( $descriptor, $messagePrefix ) {
@@ -107,6 +108,7 @@
108109
109110 // Check for validation
110111 foreach( $this->mFlatFields as $fieldname => $field ) {
 112+ if ( !empty($field->mParams['nodata']) ) continue;
111113 if ( $field->validate( $this->mFieldData[$fieldname],
112114 $this->mFieldData ) !== true ) {
113115 return isset($this->mValidationErrorMessage) ?
@@ -213,7 +215,10 @@
214216
215217 foreach( $fields as $key => $value ) {
216218 if ( is_object( $value ) ) {
217 - $tableHtml .= $value->getTableRow( $this->mFieldData[$key] );
 219+ $v = empty($value->mParams['nodata'])
 220+ ? $this->mFieldData[$key]
 221+ : $value->getDefault();
 222+ $tableHtml .= $value->getTableRow( $v );
218223 } elseif ( is_array( $value ) ) {
219224 $section = $this->displaySection( $value );
220225 $legend = wfMsg( "{$this->mMessagePrefix}-$key" );
@@ -232,9 +237,16 @@
233238 $fieldData = array();
234239
235240 foreach( $this->mFlatFields as $fieldname => $field ) {
 241+ if ( !empty($field->mParams['nodata']) ) continue;
236242 $fieldData[$fieldname] = $field->loadDataFromRequest( $wgRequest );
237243 }
238244
 245+ // Filter data.
 246+ foreach( $fieldData as $name => &$value ) {
 247+ $field = $this->mFlatFields[$name];
 248+ $value = $field->filter( $value, $this->mFlatFields );
 249+ }
 250+
239251 $this->mFieldData = $fieldData;
240252 }
241253 }
@@ -250,6 +262,14 @@
251263 return true;
252264 }
253265
 266+ function filter( $value, $alldata ) {
 267+ if( isset( $this->mFilterCallback ) ) {
 268+ $value = call_user_func( $this->mFilterCallback, $value, $alldata );
 269+ }
 270+
 271+ return $value;
 272+ }
 273+
254274 function loadDataFromRequest( $request ) {
255275 if ($request->getCheck( $this->mName ) ) {
256276 return $request->getText( $this->mName );
@@ -292,6 +312,10 @@
293313 if ( isset( $params['validation-callback'] ) ) {
294314 $this->mValidationCallback = $params['validation-callback'];
295315 }
 316+
 317+ if ( isset( $params['filter-callback'] ) ) {
 318+ $this->mFilterCallback = $params['filter-callback'];
 319+ }
296320 }
297321
298322 function getTableRow( $value ) {
@@ -441,6 +465,8 @@
442466 function validate( $value, $alldata ) {
443467 $p = parent::validate( $value, $alldata );
444468 if ($p !== true) return $p;
 469+
 470+ if (!is_array($value)) return false;
445471 // If all options are valid, array_intersect of the valid options and the provided
446472 // options will return the provided options.
447473 $validValues = array_intersect( $value, array_keys($this->mParams['options']) );
@@ -453,6 +479,7 @@
454480 function getInputHTML( $value ) {
455481 $html = '';
456482 foreach( $this->mParams['options'] as $key => $label ) {
 483+ global $wgRequest;
457484 $checkbox = Xml::check( $this->mName.'[]', in_array( $key, $value ),
458485 array( 'id' => $this->mID, 'value' => $key ) );
459486 $checkbox .= ' ' . Xml::tags( 'label', array( 'for' => $this->mID ), $label );
@@ -466,11 +493,24 @@
467494 function loadDataFromRequest( $request ) {
468495 // won't work with getCheck
469496 if ($request->getCheck( 'wpEditToken' ) ) {
470 - return $request->getArray( $this->mName );
 497+ $arr = $request->getArray( $this->mName );
 498+
 499+ if (!$arr)
 500+ $arr = array();
 501+
 502+ return $arr;
471503 } else {
472504 return $this->getDefault();
473505 }
474506 }
 507+
 508+ function getDefault() {
 509+ if ( isset( $this->mDefault ) ) {
 510+ return $this->mDefault;
 511+ } else {
 512+ return array();
 513+ }
 514+ }
475515 }
476516
477517 class HTMLRadioField extends HTMLFormField {
@@ -497,3 +537,15 @@
498538 return $html;
499539 }
500540 }
 541+
 542+class HTMLInfoField extends HTMLFormField {
 543+ function __construct( $info ) {
 544+ $info['nodata'] = true;
 545+
 546+ parent::__construct($info);
 547+ }
 548+
 549+ function getInputHTML( $value ) {
 550+ return !empty($this->mParams['raw']) ? $value : htmlspecialchars($value);
 551+ }
 552+}
Index: branches/preferences-work/phase3/includes/Preferences.php
@@ -3,15 +3,95 @@
44 class Preferences {
55 static $defaultPreferences = null;
66
7 - static function getPreferences() {
 7+ static function getPreferences( $user ) {
88 if (self::$defaultPreferences)
99 return self::$defaultPreferences;
1010
11 - global $wgLang, $wgRCMaxAge, $wgUser;
 11+ global $wgLang, $wgRCMaxAge;
1212
1313 $defaultPreferences = array();
1414
1515 ## User info #####################################
 16+ // Information panel
 17+ $defaultPreferences['username'] =
 18+ array(
 19+ 'type' => 'info',
 20+ 'label-message' => 'username',
 21+ 'default' => $user->getName(),
 22+ 'section' => 'user',
 23+ );
 24+
 25+ $defaultPreferences['userid'] =
 26+ array(
 27+ 'type' => 'info',
 28+ 'label-message' => 'uid',
 29+ 'default' => $user->getId(),
 30+ 'section' => 'user',
 31+ );
 32+
 33+ # Get groups to which the user belongs
 34+ $userEffectiveGroups = $user->getEffectiveGroups();
 35+ $userEffectiveGroupsArray = array();
 36+ foreach( $userEffectiveGroups as $ueg ) {
 37+ if( $ueg == '*' ) {
 38+ // Skip the default * group, seems useless here
 39+ continue;
 40+ }
 41+ $userEffectiveGroupsArray[] = User::makeGroupLinkHTML( $ueg );
 42+ }
 43+ asort( $userEffectiveGroupsArray );
 44+
 45+ $defaultPreferences['usergroups'] =
 46+ array(
 47+ 'type' => 'info',
 48+ 'label' => wfMsgExt( 'prefs-memberingroups', 'parseinline',
 49+ count($userEffectiveGroupsArray) ),
 50+ 'default' => $wgLang->commaList( $userEffectiveGroupsArray ),
 51+ 'raw' => true,
 52+ 'section' => 'user',
 53+ );
 54+
 55+ $defaultPreferences['editcount'] =
 56+ array(
 57+ 'type' => 'info',
 58+ 'label-message' => 'prefs-edits',
 59+ 'default' => $user->getEditCount(),
 60+ 'section' => 'user',
 61+ );
 62+
 63+ if ($user->getRegistration()) {
 64+ $defaultPreferences['registrationdate'] =
 65+ array(
 66+ 'type' => 'info',
 67+ 'label-message' => 'prefs-registration',
 68+ 'default' => $wgLang->timeanddate( $user->getRegistration() ),
 69+ 'section' => 'user',
 70+ );
 71+ }
 72+
 73+ // Actually changeable stuff
 74+ $defaultPreferences['realname'] =
 75+ array(
 76+ 'type' => 'text',
 77+ 'default' => $user->getRealName(),
 78+ 'section' => 'user',
 79+ 'label-message' => 'yourrealname',
 80+ 'help-message' => 'prefs-help-realname',
 81+ );
 82+
 83+ global $wgEmailConfirmToEdit;
 84+
 85+ $defaultPreferences['emailaddress'] =
 86+ array(
 87+ 'type' => 'text',
 88+ 'default' => $user->getEmail(),
 89+ 'section' => 'user',
 90+ 'label-message' => 'youremail',
 91+ 'help-message' => $wgEmailConfirmToEdit
 92+ ? 'prefs-help-email-required'
 93+ : 'prefs-help-email',
 94+ );
 95+
1696 $defaultPreferences['gender'] =
1797 array(
1898 'type' => 'select',
@@ -22,8 +102,30 @@
23103 'unknown' => wfMsg('gender-unknown'),
24104 ),
25105 'label-message' => 'yourgender',
 106+ 'help-message' => 'prefs-help-gender',
26107 );
27108
 109+ // Language
 110+ global $wgContLanguageCode;
 111+ $languages = Language::getLanguageNames( false );
 112+ if( !array_key_exists( $wgContLanguageCode, $languages ) ) {
 113+ $languages[$wgContLanguageCode] = $wgContLanguageCode;
 114+ }
 115+ ksort( $languages );
 116+
 117+ $options = array();
 118+ foreach( $languages as $code => $name ) {
 119+ $options[$code] = "$code - $name";
 120+ }
 121+ $defaultPreferences['language'] =
 122+ array(
 123+ 'type' => 'select',
 124+ 'section' => 'user',
 125+ 'options' => $options,
 126+ 'default' => $wgContLanguageCode,
 127+ 'label-message' => 'yourlanguage',
 128+ );
 129+
28130 global $wgContLang, $wgDisableLangConversion;
29131 /* see if there are multiple language variants to choose from*/
30132 $variantArray = array();
@@ -70,9 +172,10 @@
71173 'type' => 'text',
72174 'maxlength' => $wgMaxSigChars,
73175 'label-message' => 'yournick',
74 - 'validation' =>
75 - array( 'DefaultPreferences', 'validateSignature' ),
 176+ 'validation-callback' =>
 177+ array( 'Preferences', 'validateSignature' ),
76178 'section' => 'user',
 179+ 'filter-callback' => array( 'Preferences', 'cleanSignature' ),
77180 );
78181 $defaultPreferences['fancysig'] =
79182 array(
@@ -80,8 +183,6 @@
81184 'label-message' => 'tog-fancysig',
82185 'section' => 'user'
83186 );
84 -
85 - ## TODO STUFF STORED IN USER ROW
86187
87188
88189 ## Skin #####################################
@@ -348,12 +449,12 @@
349450 'delete' => 'watchdeletion' );
350451
351452 // Kinda hacky
352 - if( $wgUser->isAllowed( 'createpage' ) || $wgUser->isAllowed( 'createtalk' ) ) {
 453+ if( $user->isAllowed( 'createpage' ) || $user->isAllowed( 'createtalk' ) ) {
353454 $watchTypes['read'] = 'watchcreations';
354455 }
355456
356457 foreach( $watchTypes as $action => $pref ) {
357 - if ( $wgUser->isAllowed( $action ) ) {
 458+ if ( $user->isAllowed( $action ) ) {
358459 $defaultPreferences[$pref] = array(
359460 'type' => 'toggle',
360461 'section' => 'watchlist',
@@ -384,9 +485,25 @@
385486 'section' => 'search',
386487 'min' => 0,
387488 );
 489+
 490+ $nsOptions = array();
 491+ foreach( $wgContLang->getNamespaces() as $ns => $name ) {
 492+ if ($ns < 0) continue;
 493+ $displayNs = str_replace( '_', ' ', $name );
 494+
 495+ if (!$displayNs) $displayNs = wfMsg( 'blanknamespace' );
 496+
 497+ $nsOptions[$ns] = $displayNs;
 498+ }
 499+
 500+ $defaultPreferences['searchNs'] =
 501+ array(
 502+ 'type' => 'multiselect',
 503+ 'label-message' => 'defaultns',
 504+ 'options' => $nsOptions,
 505+ 'section' => 'search',
 506+ );
388507
389 - ## TODO Searchable namespaces.
390 -
391508 global $wgEnableMWSuggest;
392509 if ($wgEnableMWSuggest) {
393510 $defaultPreferences['disablesuggest'] =
@@ -530,7 +647,26 @@
531648 );
532649 }
533650
534 - ## Unsorted --------------------------------------------------------------
 651+ ## Prod in defaults from the user
 652+ global $wgDefaultUserOptions;
 653+ foreach( $defaultPreferences as $name => &$info ) {
 654+ $prefFromUser = $user->getOption( $name );
 655+ $field = HTMLForm::loadInputFromParameters( $info ); // For validation
 656+ $globalDefault = isset($wgDefaultUserOptions[$name])
 657+ ? $wgDefaultUserOptions[$name]
 658+ : null;
 659+
 660+ // If it validates, set it as the default
 661+ if ( isset( $user->mOptions[$name] ) && // Make sure we're not just pulling nothing
 662+ $field->validate( $prefFromUser, $user->mOptions ) ) {
 663+ $info['default'] = $prefFromUser;
 664+ } elseif ( isset($info['default']) ) {
 665+ // Already set, no problem
 666+ continue;
 667+ } elseif( $field->validate( $globalDefault, $user->mOptions ) ) {
 668+ $info['default'] = $globalDefault;
 669+ }
 670+ }
535671
536672 wfRunHooks( 'GetPreferences', array( &$defaultPreferences ) );
537673
@@ -539,6 +675,10 @@
540676 return $defaultPreferences;
541677 }
542678
 679+ static function savePreferencesFromForm( $data, $user ) {
 680+
 681+ }
 682+
543683 static function generateSkinOptions() {
544684 global $wgDefaultSkin;
545685 $ret = array();
@@ -565,12 +705,12 @@
566706 $extraLinks = '';
567707 global $wgAllowUserCss, $wgAllowUserJs;
568708 if( $wgAllowUserCss ) {
569 - $cssPage = Title::makeTitleSafe( NS_USER, $wgUser->getName().'/'.$skinkey.'.css' );
 709+ $cssPage = Title::makeTitleSafe( NS_USER, $user->getName().'/'.$skinkey.'.css' );
570710 $customCSS = $sk->makeLinkObj( $cssPage, wfMsgExt('prefs-custom-css', array() ) );
571711 $extraLinks .= " ($customCSS)";
572712 }
573713 if( $wgAllowUserJs ) {
574 - $jsPage = Title::makeTitleSafe( NS_USER, $wgUser->getName().'/'.$skinkey.'.js' );
 714+ $jsPage = Title::makeTitleSafe( NS_USER, $user->getName().'/'.$skinkey.'.js' );
575715 $customJS = $sk->makeLinkObj( $jsPage, wfMsgHtml('prefs-custom-js') );
576716 $extraLinks .= " ($customJS)";
577717 }
@@ -643,4 +783,16 @@
644784 return true;
645785 }
646786 }
 787+
 788+ static function cleanSignature( $signature, $alldata ) {
 789+ global $wgParser;
 790+ if( $alldata['fancysig'] ) {
 791+ $signature = $wgParser->cleanSig( $signature );
 792+ } else {
 793+ // When no fancy sig used, make sure ~{3,5} get removed.
 794+ $signature = $wgParser->cleanSigInSig( $signature );
 795+ }
 796+
 797+ return $signature;
 798+ }
647799 }
Index: branches/preferences-work/phase3/languages/messages/MessagesEn.php
@@ -907,6 +907,7 @@
908908 'username' => 'Username:',
909909 'uid' => 'User ID:',
910910 'prefs-memberingroups' => 'Member of {{PLURAL:$1|group|groups}}:',
 911+'prefs-registration' => 'Registration time:',
911912 'yourrealname' => 'Real name:',
912913 'yourlanguage' => 'Language:',
913914 'yourvariant' => 'Variant:', # only translate this message to other languages if you have to change it

Status & tagging log