<?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 =
} elseif( $field->validate( $globalDefault, $user->mOptions ) === true ) {
$info['default'] = $globalDefault;
} else {
- throw new MWException( "Global default $globalDefault is invalid for field $name" );
+ throw new MWException( "Global default '$globalDefault' is invalid for field $name" );
}
}
# 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',
);
array(
'type' => 'info',
'label-message' => 'prefs-registration',
- 'default' => $wgLang->timeanddate( $user->getRegistration(), true ),
+ 'default' => wfMsgExt( 'prefs-registration-date-time', 'parsemag',
+ $wgLang->timeanddate( $user->getRegistration(), true ),
+ $wgLang->date( $user->getRegistration(), true ),
+ $wgLang->time( $user->getRegistration(), true ) ),
'section' => 'personal/info',
);
}
$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' => 'timezonelegend',
'options' => self::getTimezoneOptions(),
'default' => $tzSetting,
+ 'size' => 20,
'section' => 'datetime/timeoffset',
);
}
'type' => 'selectorother',
'section' => 'rendering/advancedrendering',
'options' => $stubThresholdOptions,
+ 'size' => 20,
'label' => wfMsg( 'stub-threshold' ), // Raw HTML message. Yay?
);
$defaultPreferences['highlightbroken'] =
'min' => 4,
'max' => 1000,
);
+
+ $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',
}
static function rcPreferences( $user, &$defaultPreferences ) {
- global $wgRCMaxAge, $wgUseRCPatrol;
+ global $wgRCMaxAge, $wgUseRCPatrol, $wgLang;
## RecentChanges #####################################
$defaultPreferences['rcdays'] =
array(
- 'type' => 'int',
+ 'type' => 'float',
'label-message' => 'recentchangesdays',
'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(
}
static function watchlistPreferences( $user, &$defaultPreferences ) {
- global $wgUseRCPatrol;
+ global $wgUseRCPatrol, $wgEnableAPI;
## Watchlist #####################################
$defaultPreferences['watchlistdays'] =
array(
- 'type' => 'int',
+ 'type' => 'float',
'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(
'section' => 'watchlist/advancedwatchlist',
'label-message' => 'tog-watchlisthideliu',
);
+ if ( $wgEnableAPI ) {
+ # Some random gibberish as a proposed default
+ $hash = sha1( mt_rand() . microtime( true ) );
+ $defaultPreferences['watchlisttoken'] =
+ array(
+ 'type' => 'text',
+ 'section' => 'watchlist/advancedwatchlist',
+ 'label-message' => 'prefs-watchlist-token',
+ 'help' => wfMsgHtml( 'prefs-help-watchlist-token', $hash )
+ );
+ }
if ( $wgUseRCPatrol ) {
$defaultPreferences['watchlisthidepatrolled'] =
}
}
+ /**
+ * @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' );