<?php
+/**
+ * We're now using the HTMLForm object with some customisation to generate the
+ * Preferences form. This object handles generic submission, CSRF protection,
+ * layout and other logic in a reusable manner. We subclass it as a PreferencesForm
+ * to make some minor customisations.
+ *
+ * In order to generate the form, the HTMLForm object needs an array structure
+ * detailing the form fields available, and that's what this class is for. Each
+ * element of the array is a basic property-list, including the type of field,
+ * the label it is to be given in the form, callbacks for validation and
+ * 'filtering', and other pertinent information. Note that the 'default' field
+ * is named for generic forms, and does not represent the preference's default
+ * (which is stored in $wgDefaultUserOptions), but the default for the form
+ * field, which should be whatever the user has set for that preference. There
+ * is no need to override it unless you have some special storage logic (for
+ * instance, those not presently stored as options, but which are best set from
+ * the user preferences view).
+ *
+ * Field types are implemented as subclasses of the generic HTMLFormField
+ * object, and typically implement at least getInputHTML, which generates the
+ * HTML for the input field to be placed in the table.
+ *
+ * Once fields have been retrieved and validated, submission logic is handed
+ * over to the tryUISubmit static method of this class.
+ */
class Preferences {
static $defaultPreferences = null;
static $saveFilters =
}
static function profilePreferences( $user, &$defaultPreferences ) {
- global $wgLang;
+ global $wgLang, $wgUser;
## User info #####################################
// Information panel
$defaultPreferences['username'] =
# Get groups to which the user belongs
$userEffectiveGroups = $user->getEffectiveGroups();
- $userEffectiveGroupsArray = array();
+ $userGroups = $userMembers = array();
foreach( $userEffectiveGroups as $ueg ) {
if( $ueg == '*' ) {
// Skip the default * group, seems useless here
continue;
}
- $userEffectiveGroupsArray[] = User::makeGroupLinkHTML( $ueg );
+ $groupName = User::getGroupName( $ueg );
+ $userGroups[] = User::makeGroupLinkHTML( $ueg, $groupName );
+
+ $memberName = User::getGroupMember( $ueg );
+ $userMembers[] = User::makeGroupLinkHTML( $ueg, $memberName );
}
- asort( $userEffectiveGroupsArray );
+ asort( $userGroups );
+ asort( $userMembers );
$defaultPreferences['usergroups'] =
array(
'type' => 'info',
'label' => wfMsgExt( 'prefs-memberingroups', 'parseinline',
- count( $userEffectiveGroupsArray ) ),
- 'default' => $wgLang->commaList( $userEffectiveGroupsArray ),
+ $wgLang->formatNum( count($userGroups) ) ),
+ 'default' => wfMsgExt( 'prefs-memberingroups-type', array(),
+ $wgLang->commaList( $userGroups ),
+ $wgLang->commaList( $userMembers )
+ ),
'raw' => true,
'section' => 'personal/info',
);
);
if( $wgAuth->allowPasswordChange() ) {
- global $wgUser; // For skin.
$link = $wgUser->getSkin()->link( SpecialPage::getTitleFor( 'Resetpass' ),
wfMsgHtml( 'prefs-resetpass' ), array(),
array( 'returnto' => SpecialPage::getTitleFor( 'Preferences' ) ) );
$options = array();
foreach( $languages as $code => $name ) {
- $display = "$code - $name";
+ $display = wfBCP47( $code ) . ' - ' . $name;
$options[$display] = $code;
}
$defaultPreferences['language'] =
$options = array();
foreach( $variantArray as $code => $name ) {
- $display = "$code - $name";
+ $display = wfBCP47( $code ) . ' - ' . $name;
$options[$display] = $code;
}
);
}
- global $wgMaxSigChars;
+ global $wgMaxSigChars, $wgOut, $wgParser;
+
+ // show a preview of the old signature first
+ $oldsigWikiText = $wgParser->preSaveTransform( "~~~", new Title , $user, new ParserOptions );
+ $oldsigHTML = $wgOut->parseInline( $oldsigWikiText );
+ $defaultPreferences['oldsig'] =
+ array(
+ 'type' => 'info',
+ 'raw' => true,
+ 'label-message' => 'tog-oldsig',
+ 'default' => $oldsigHTML,
+ 'section' => 'personal/signature',
+ );
$defaultPreferences['nickname'] =
array(
'type' => $wgAuth->allowPropChange( 'nickname' ) ? 'text' : 'info',
array(
'type' => 'toggle',
'label-message' => 'tog-fancysig',
+ 'help-message' => 'prefs-help-signature', // show general help about signature at the bottom of the section
'section' => 'personal/signature'
);
-
+
## Email stuff
global $wgEnableEmail;
$defaultPreferences['emailaddress'] =
array(
- 'type' => $wgAuth->allowPropChange( 'emailaddress' ) ? 'text' : 'info',
+ 'type' => $wgAuth->allowPropChange( 'emailaddress' ) ? 'email' : 'info',
'default' => $user->getEmail(),
'section' => 'personal/email',
'label-message' => 'youremail',
$time = $wgLang->timeAndDate( $user->getEmailAuthenticationTimestamp(), true );
$d = $wgLang->date( $user->getEmailAuthenticationTimestamp(), true );
$t = $wgLang->time( $user->getEmailAuthenticationTimestamp(), true );
- $emailauthenticated = htmlspecialchars( wfMsg( 'emailauthenticated', $time, $d, $t ) ) . '<br />';
+ $emailauthenticated = wfMsgExt( 'emailauthenticated', 'parseinline',
+ array($time, $d, $t ) ) . '<br />';
$disableEmailPrefs = false;
} else {
$disableEmailPrefs = true;
- global $wgUser; // wgUser is okay here, it's for display
$skin = $wgUser->getSkin();
- $emailauthenticated = wfMsgHtml( 'emailnotauthenticated' ) . '<br />' .
+ $emailauthenticated = wfMsgExt( 'emailnotauthenticated', 'parseinline' ) . '<br />' .
$skin->link(
SpecialPage::getTitleFor( 'Confirmemail' ),
wfMsg( 'emailconfirmlink' ),
}
- if( $wgEnableUserEmail ) {
+ if( $wgEnableUserEmail && $user->isAllowed( 'sendemail' ) ) {
$defaultPreferences['disablemail'] =
array(
'type' => 'toggle',
'label-message' => 'tog-enotifminoredits',
'disabled' => $disableEmailPrefs,
);
+ global $wgEnotifRevealEditorAddress;
+ if ( $wgEnotifRevealEditorAddress ) {
+ $defaultPreferences['enotifrevealaddr'] =
+ array(
+ 'type' => 'toggle',
+ 'section' => 'personal/email',
+ 'label-message' => 'tog-enotifrevealaddr',
+ 'disabled' => $disableEmailPrefs,
+ );
+ }
}
- $defaultPreferences['enotifrevealaddr'] =
- array(
- 'type' => 'toggle',
- 'section' => 'personal/email',
- 'label-message' => 'tog-enotifrevealaddr',
- 'disabled' => $disableEmailPrefs,
- );
}
}
static function skinPreferences( $user, &$defaultPreferences ) {
## Skin #####################################
+ global $wgLang, $wgAllowUserCss, $wgAllowUserJs;
+
$defaultPreferences['skin'] =
array(
'type' => 'radio',
'section' => 'rendering/skin',
);
+ # Create links to user CSS/JS pages for all skins
+ # This code is basically copied from generateSkinOptions(). It'd
+ # be nice to somehow merge this back in there to avoid redundancy.
+ if( $wgAllowUserCss || $wgAllowUserJs ) {
+ $sk = $user->getSkin();
+ $linkTools = array();
+ if( $wgAllowUserCss ) {
+ $cssPage = Title::makeTitleSafe( NS_USER, $user->getName() . '/common.css' );
+ $linkTools[] = $sk->link( $cssPage, wfMsgHtml( 'prefs-custom-css' ) );
+ }
+ if( $wgAllowUserJs ) {
+ $jsPage = Title::makeTitleSafe( NS_USER, $user->getName() . '/common.js' );
+ $linkTools[] = $sk->link( $jsPage, wfMsgHtml( 'prefs-custom-js' ) );
+ }
+ $defaultPreferences['commoncssjs'] =
+ array(
+ 'type' => 'info',
+ 'raw' => true,
+ 'default' => $wgLang->pipeList( $linkTools ),
+ 'label-message' => 'prefs-common-css-js',
+ 'section' => 'rendering/skin',
+ );
+ }
+
$selectedSkin = $user->getOption( 'skin' );
if ( in_array( $selectedSkin, array( 'cologneblue', 'standard' ) ) ) {
global $wgLang;
'label-message' => 'timezonelegend',
'options' => self::getTimezoneOptions(),
'default' => $tzSetting,
+ 'size' => 20,
'section' => 'datetime/timeoffset',
);
}
static function renderingPreferences( $user, &$defaultPreferences ) {
## Page Rendering ##############################
- $defaultPreferences['underline'] =
- array(
- 'type' => 'select',
- 'options' => array(
- wfMsg( 'underline-never' ) => 0,
- wfMsg( 'underline-always' ) => 1,
- wfMsg( 'underline-default' ) => 2,
- ),
- 'label-message' => 'tog-underline',
- 'section' => 'rendering/advancedrendering',
- );
+ global $wgAllowUserCssPrefs;
+ if( $wgAllowUserCssPrefs ){
+ $defaultPreferences['underline'] =
+ array(
+ 'type' => 'select',
+ 'options' => array(
+ wfMsg( 'underline-never' ) => 0,
+ wfMsg( 'underline-always' ) => 1,
+ wfMsg( 'underline-default' ) => 2,
+ ),
+ 'label-message' => 'tog-underline',
+ 'section' => 'rendering/advancedrendering',
+ );
+ }
$stubThresholdValues = array( 0, 50, 100, 500, 1000, 2000, 5000, 10000 );
$stubThresholdOptions = array();
'type' => 'selectorother',
'section' => 'rendering/advancedrendering',
'options' => $stubThresholdOptions,
+ 'size' => 20,
'label' => wfMsg( 'stub-threshold' ), // Raw HTML message. Yay?
);
- $defaultPreferences['highlightbroken'] =
- array(
- 'type' => 'toggle',
- 'section' => 'rendering/advancedrendering',
- 'label' => wfMsg( 'tog-highlightbroken' ), // Raw HTML
- );
- $defaultPreferences['showtoc'] =
- array(
- 'type' => 'toggle',
- 'section' => 'rendering/advancedrendering',
- 'label-message' => 'tog-showtoc',
- );
+ if( $wgAllowUserCssPrefs ){
+ $defaultPreferences['highlightbroken'] =
+ array(
+ 'type' => 'toggle',
+ 'section' => 'rendering/advancedrendering',
+ 'label' => wfMsg( 'tog-highlightbroken' ), // Raw HTML
+ );
+ $defaultPreferences['showtoc'] =
+ array(
+ 'type' => 'toggle',
+ 'section' => 'rendering/advancedrendering',
+ 'label-message' => 'tog-showtoc',
+ );
+ }
$defaultPreferences['nocache'] =
array(
'type' => 'toggle',
'section' => 'rendering/advancedrendering',
'label-message' => 'tog-showjumplinks',
);
- $defaultPreferences['justify'] =
- array(
- 'type' => 'toggle',
- 'section' => 'rendering/advancedrendering',
- 'label-message' => 'tog-justify',
- );
+ if( $wgAllowUserCssPrefs ){
+ $defaultPreferences['justify'] =
+ array(
+ 'type' => 'toggle',
+ 'section' => 'rendering/advancedrendering',
+ 'label-message' => 'tog-justify',
+ );
+ }
$defaultPreferences['numberheadings'] =
array(
'type' => 'toggle',
}
static function editingPreferences( $user, &$defaultPreferences ) {
- global $wgUseExternalEditor, $wgLivePreview;
+ global $wgUseExternalEditor, $wgLivePreview, $wgAllowUserCssPrefs;
## Editing #####################################
$defaultPreferences['cols'] =
'min' => 4,
'max' => 1000,
);
+ if( $wgAllowUserCssPrefs ){
+ $defaultPreferences['editfont'] =
+ array(
+ 'type' => 'select',
+ 'section' => 'editing/advancedediting',
+ 'label-message' => 'editfont-style',
+ 'options' => array(
+ wfMsg( 'editfont-default' ) => 'default',
+ wfMsg( 'editfont-monospace' ) => 'monospace',
+ wfMsg( 'editfont-sansserif' ) => 'sans-serif',
+ wfMsg( 'editfont-serif' ) => 'serif',
+ )
+ );
+ }
$defaultPreferences['previewontop'] =
array(
'type' => 'toggle',
'section' => 'editing/advancedediting',
'label-message' => 'tog-previewonfirst',
);
- $defaultPreferences['editsection'] =
- array(
- 'type' => 'toggle',
- 'section' => 'editing/advancedediting',
- 'label-message' => 'tog-editsection',
- );
+ if( $wgAllowUserCssPrefs ){
+ $defaultPreferences['editsection'] =
+ array(
+ 'type' => 'toggle',
+ 'section' => 'editing/advancedediting',
+ 'label-message' => 'tog-editsection',
+ );
+ }
$defaultPreferences['editsectiononrightclick'] =
array(
'type' => 'toggle',
}
static function rcPreferences( $user, &$defaultPreferences ) {
- global $wgRCMaxAge, $wgUseRCPatrol;
+ global $wgRCMaxAge, $wgUseRCPatrol, $wgLang;
## RecentChanges #####################################
$defaultPreferences['rcdays'] =
array(
'section' => 'rc/display',
'min' => 1,
'max' => ceil( $wgRCMaxAge / ( 3600*24 ) ),
+ 'help' => wfMsgExt( 'recentchangesdays-max', array( 'parsemag' ), $wgLang->formatNum( ceil( $wgRCMaxAge / ( 3600*24 ) ) ) ),
);
$defaultPreferences['rclimit'] =
array(
'section' => 'rc/advancedrc',
);
- global $wgUseRCPatrol;
if( $wgUseRCPatrol ) {
$defaultPreferences['hidepatrolled'] =
array(
'min' => 0,
'max' => 7,
'section' => 'watchlist/display',
+ 'help' => wfMsgHtml( 'prefs-watchlist-days-max' ),
'label-message' => 'prefs-watchlist-days',
);
$defaultPreferences['wllimit'] =
'min' => 0,
'max' => 1000,
'label-message' => 'prefs-watchlist-edits',
- 'section' => 'watchlist/display'
+ 'help' => wfMsgHtml( 'prefs-watchlist-edits-max' ),
+ 'section' => 'watchlist/display',
);
$defaultPreferences['extendwatchlist'] =
array(
}
}
+ /**
+ * @param object $user The user object
+ * @return array Text/links to display as key; $skinkey as value
+ */
static function generateSkinOptions( $user ) {
- global $wgDefaultSkin;
+ global $wgDefaultSkin, $wgLang, $wgAllowUserCss, $wgAllowUserJs;
$ret = array();
$mptitle = Title::newMainPage();
$sk = $user->getSkin();
foreach( $validSkinNames as $skinkey => $sn ) {
+ $linkTools = array();
+
+ # Mark the default skin
+ if( $skinkey == $wgDefaultSkin ) {
+ $linkTools[] = wfMsgHtml( 'default' );
+ }
+
+ # Create preview link
$mplink = htmlspecialchars( $mptitle->getLocalURL( "useskin=$skinkey" ) );
- $previewlink = "(<a target='_blank' href=\"$mplink\">$previewtext</a>)";
- $extraLinks = '';
- global $wgAllowUserCss, $wgAllowUserJs;
+ $linkTools[] = "<a target='_blank' href=\"$mplink\">$previewtext</a>";
+
+ # Create links to user CSS/JS pages
if( $wgAllowUserCss ) {
$cssPage = Title::makeTitleSafe( NS_USER, $user->getName() . '/' . $skinkey . '.css' );
- $customCSS = $sk->link( $cssPage, wfMsgHtml( 'prefs-custom-css' ) );
- $extraLinks .= " ($customCSS)";
+ $linkTools[] = $sk->link( $cssPage, wfMsgHtml( 'prefs-custom-css' ) );
}
if( $wgAllowUserJs ) {
$jsPage = Title::makeTitleSafe( NS_USER, $user->getName() . '/' . $skinkey . '.js' );
- $customJS = $sk->link( $jsPage, wfMsgHtml( 'prefs-custom-js' ) );
- $extraLinks .= " ($customJS)";
+ $linkTools[] = $sk->link( $jsPage, wfMsgHtml( 'prefs-custom-js' ) );
}
- if( $skinkey == $wgDefaultSkin )
- $sn .= ' (' . wfMsgHtml( 'default' ) . ')';
- $display = "$sn $previewlink{$extraLinks}";
+
+ $display = $sn . ' ' . wfMsg( 'parentheses', $wgLang->pipeList( $linkTools ) );
$ret[$display] = $skinkey;
}
}
$idCnt = 0;
- $epoch = '20010115161234'; # Wikipedia day
+ $epoch = wfTimestampNow();
foreach( $dateopts as $key ) {
if( $key == 'default' ) {
$formatted = wfMsgHtml( 'datedefault' );
);
if( $wgEnableEmail ) {
- $newadr = $formData['emailaddress'];
- $oldadr = $wgUser->getEmail();
- if( ( $newadr != '' ) && ( $newadr != $oldadr ) ) {
+ $newaddr = $formData['emailaddress'];
+ $oldaddr = $wgUser->getEmail();
+ if( ( $newaddr != '' ) && ( $newaddr != $oldaddr ) ) {
# the user has supplied a new email address on the login page
# new behaviour: set this new emailaddr from login-page into user database record
- $wgUser->setEmail( $newadr );
+ $wgUser->setEmail( $newaddr );
# but flag as "dirty" = unauthenticated
$wgUser->invalidateEmail();
if( $wgEmailAuthentication ) {
# Mail a temporary password to the dirty address.
# User can come back through the confirmation URL to re-enable email.
- $result = $wgUser->sendConfirmationMail();
+ $result = $wgUser->sendConfirmationMail( $oldaddr != '' );
if( WikiError::isError( $result ) ) {
return wfMsg( 'mailerror', htmlspecialchars( $result->getMessage() ) );
} elseif( $entryPoint == 'ui' ) {
}
}
} else {
- $wgUser->setEmail( $newadr );
+ $wgUser->setEmail( $newaddr );
}
- if( $oldadr != $newadr ) {
- wfRunHooks( 'PrefsEmailAudit', array( $wgUser, $oldadr, $newadr ) );
+ if( $oldaddr != $newaddr ) {
+ wfRunHooks( 'PrefsEmailAudit', array( $wgUser, $oldaddr, $newaddr ) );
}
}