wiki.techinc.nl/includes/Preferences.php

1398 lines
41 KiB
PHP
Raw Normal View History

<?php
/**
2009-08-23 20:09:59 +00:00
* 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 = array(
'timecorrection' => array( 'Preferences', 'filterTimezoneInput' ),
);
2009-06-21 14:16:11 +00:00
static function getPreferences( $user ) {
2009-06-21 14:16:11 +00:00
if ( self::$defaultPreferences )
return self::$defaultPreferences;
2009-06-21 14:16:11 +00:00
global $wgRCMaxAge;
$defaultPreferences = array();
self::profilePreferences( $user, $defaultPreferences );
self::skinPreferences( $user, $defaultPreferences );
self::filesPreferences( $user, $defaultPreferences );
self::mathPreferences( $user, $defaultPreferences );
self::datetimePreferences( $user, $defaultPreferences );
self::renderingPreferences( $user, $defaultPreferences );
self::editingPreferences( $user, $defaultPreferences );
self::rcPreferences( $user, $defaultPreferences );
self::watchlistPreferences( $user, $defaultPreferences );
self::searchPreferences( $user, $defaultPreferences );
self::miscPreferences( $user, $defaultPreferences );
wfRunHooks( 'GetPreferences', array( $user, &$defaultPreferences ) );
## Remove preferences that wikis don't want to use
global $wgHiddenPrefs;
foreach ( $wgHiddenPrefs as $pref ) {
if ( isset( $defaultPreferences[$pref] ) ) {
2009-06-21 14:16:11 +00:00
unset( $defaultPreferences[$pref] );
}
}
## Prod in defaults from the user
global $wgDefaultUserOptions;
foreach ( $defaultPreferences as $name => &$info ) {
$prefFromUser = self::getOptionFromUser( $name, $info, $user );
$field = HTMLForm::loadInputFromParameters( $info ); // For validation
2009-06-09 17:32:33 +00:00
$defaultOptions = User::getDefaultOptions();
2009-06-21 14:16:11 +00:00
$globalDefault = isset( $defaultOptions[$name] )
? $defaultOptions[$name]
: null;
2009-06-21 14:16:11 +00:00
// If it validates, set it as the default
2009-06-21 14:16:11 +00:00
if ( isset( $info['default'] ) ) {
// Already set, no problem
continue;
} elseif ( !is_null( $prefFromUser ) && // Make sure we're not just pulling nothing
$field->validate( $prefFromUser, $user->mOptions ) === true ) {
$info['default'] = $prefFromUser;
} elseif ( $field->validate( $globalDefault, $user->mOptions ) === true ) {
$info['default'] = $globalDefault;
} else {
throw new MWException( "Global default '$globalDefault' is invalid for field $name" );
}
}
2009-06-21 14:16:11 +00:00
self::$defaultPreferences = $defaultPreferences;
2009-06-21 14:16:11 +00:00
return $defaultPreferences;
}
2009-06-21 14:16:11 +00:00
// Pull option from a user account. Handles stuff like array-type preferences.
static function getOptionFromUser( $name, $info, $user ) {
$val = $user->getOption( $name );
2009-06-21 14:16:11 +00:00
// Handling for array-type preferences
2009-06-21 14:16:11 +00:00
if ( ( isset( $info['type'] ) && $info['type'] == 'multiselect' ) ||
( isset( $info['class'] ) && $info['class'] == 'HTMLMultiSelectField' ) ) {
$options = HTMLFormField::flattenOptions( $info['options'] );
$prefix = isset( $info['prefix'] ) ? $info['prefix'] : $name;
$val = array();
2009-06-21 14:16:11 +00:00
foreach ( $options as $label => $value ) {
if ( $user->getOption( "$prefix$value" ) ) {
$val[] = $value;
}
}
}
2009-06-21 14:16:11 +00:00
return $val;
}
2009-06-21 14:16:11 +00:00
static function profilePreferences( $user, &$defaultPreferences ) {
2010-02-22 10:48:30 +00:00
global $wgLang, $wgUser;
## User info #####################################
// Information panel
$defaultPreferences['username'] = array(
'type' => 'info',
'label-message' => 'username',
'default' => $user->getName(),
'section' => 'personal/info',
);
2009-06-21 14:16:11 +00:00
$defaultPreferences['userid'] = array(
'type' => 'info',
'label-message' => 'uid',
'default' => $user->getId(),
'section' => 'personal/info',
);
2009-06-21 14:16:11 +00:00
# Get groups to which the user belongs
$userEffectiveGroups = $user->getEffectiveGroups();
$userGroups = $userMembers = array();
foreach ( $userEffectiveGroups as $ueg ) {
if ( $ueg == '*' ) {
// Skip the default * group, seems useless here
continue;
}
$groupName = User::getGroupName( $ueg );
$userGroups[] = User::makeGroupLinkHTML( $ueg, $groupName );
$memberName = User::getGroupMember( $ueg );
$userMembers[] = User::makeGroupLinkHTML( $ueg, $memberName );
}
asort( $userGroups );
asort( $userMembers );
2009-06-21 14:16:11 +00:00
$defaultPreferences['usergroups'] = array(
'type' => 'info',
'label' => wfMsgExt(
'prefs-memberingroups', 'parseinline',
$wgLang->formatNum( count( $userGroups ) )
),
'default' => wfMsgExt(
'prefs-memberingroups-type', array(),
$wgLang->commaList( $userGroups ),
$wgLang->commaList( $userMembers )
),
'raw' => true,
'section' => 'personal/info',
);
2009-06-21 14:16:11 +00:00
$defaultPreferences['editcount'] = array(
'type' => 'info',
'label-message' => 'prefs-edits',
'default' => $wgLang->formatNum( $user->getEditCount() ),
'section' => 'personal/info',
);
2009-06-21 14:16:11 +00:00
if ( $user->getRegistration() ) {
$defaultPreferences['registrationdate'] = array(
'type' => 'info',
'label-message' => 'prefs-registration',
'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',
);
}
2009-06-21 14:16:11 +00:00
// Actually changeable stuff
global $wgAuth;
$defaultPreferences['realname'] = array(
'type' => $wgAuth->allowPropChange( 'realname' ) ? 'text' : 'info',
'default' => $user->getRealName(),
'section' => 'personal/info',
'label-message' => 'yourrealname',
'help-message' => 'prefs-help-realname',
);
$defaultPreferences['gender'] = array(
'type' => 'select',
'section' => 'personal/info',
'options' => array(
wfMsg( 'gender-male' ) => 'male',
wfMsg( 'gender-female' ) => 'female',
wfMsg( 'gender-unknown' ) => 'unknown',
),
'label-message' => 'yourgender',
'help-message' => 'prefs-help-gender',
);
if ( $wgAuth->allowPasswordChange() ) {
2009-05-24 09:23:40 +00:00
$link = $wgUser->getSkin()->link( SpecialPage::getTitleFor( 'Resetpass' ),
2009-06-21 14:16:11 +00:00
wfMsgHtml( 'prefs-resetpass' ), array(),
array( 'returnto' => SpecialPage::getTitleFor( 'Preferences' ) ) );
$defaultPreferences['password'] = array(
'type' => 'info',
'raw' => true,
'default' => $link,
'label-message' => 'yourpassword',
'section' => 'personal/info',
);
}
global $wgCookieExpiration;
if ( $wgCookieExpiration > 0 ) {
$defaultPreferences['rememberpassword'] = array(
'type' => 'toggle',
'label' => wfMsgExt(
'tog-rememberpassword',
array( 'parsemag' ),
$wgLang->formatNum( ceil( $wgCookieExpiration / ( 3600 * 24 ) ) )
),
'section' => 'personal/info',
);
}
2009-06-21 14:16:11 +00:00
// Language
global $wgContLanguageCode;
$languages = array_reverse( Language::getLanguageNames( false ) );
if ( !array_key_exists( $wgContLanguageCode, $languages ) ) {
$languages[$wgContLanguageCode] = $wgContLanguageCode;
}
ksort( $languages );
2009-06-21 14:16:11 +00:00
$options = array();
foreach ( $languages as $code => $name ) {
$display = wfBCP47( $code ) . ' - ' . $name;
$options[$display] = $code;
}
$defaultPreferences['language'] = array(
'type' => 'select',
'section' => 'personal/i18n',
'options' => $options,
'label-message' => 'yourlanguage',
);
2009-06-21 14:16:11 +00:00
global $wgContLang, $wgDisableLangConversion;
2009-07-08 17:07:39 +00:00
global $wgDisableTitleConversion;
/* see if there are multiple language variants to choose from*/
$variantArray = array();
if ( !$wgDisableLangConversion ) {
$variants = $wgContLang->getVariants();
$languages = Language::getLanguageNames( true );
foreach ( $variants as $v ) {
2009-06-21 14:16:11 +00:00
$v = str_replace( '_', '-', strtolower( $v ) );
if ( array_key_exists( $v, $languages ) ) {
// If it doesn't have a name, we'll pretend it doesn't exist
$variantArray[$v] = $languages[$v];
}
}
$options = array();
foreach ( $variantArray as $code => $name ) {
$display = wfBCP47( $code ) . ' - ' . $name;
$options[$display] = $code;
}
if ( count( $variantArray ) > 1 ) {
$defaultPreferences['variant'] = array(
'label-message' => 'yourvariant',
'type' => 'select',
'options' => $options,
'section' => 'personal/i18n',
);
}
}
2009-06-21 14:16:11 +00:00
if ( count( $variantArray ) > 1 && !$wgDisableLangConversion && !$wgDisableTitleConversion ) {
$defaultPreferences['noconvertlink'] =
array(
'type' => 'toggle',
'section' => 'personal/i18n',
'label-message' => 'tog-noconvertlink',
);
}
2009-06-21 14:16:11 +00:00
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',
'maxlength' => $wgMaxSigChars,
'label-message' => 'yournick',
'validation-callback' => array( 'Preferences', 'validateSignature' ),
'section' => 'personal/signature',
'filter-callback' => array( 'Preferences', 'cleanSignature' ),
);
$defaultPreferences['fancysig'] = 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;
if ( $wgEnableEmail ) {
global $wgEmailConfirmToEdit;
$defaultPreferences['emailaddress'] = array(
'type' => $wgAuth->allowPropChange( 'emailaddress' ) ? 'email' : 'info',
'default' => $user->getEmail(),
'section' => 'personal/email',
'label-message' => 'youremail',
'help-message' => $wgEmailConfirmToEdit
? 'prefs-help-email-required'
: 'prefs-help-email',
'validation-callback' => array( 'Preferences', 'validateEmail' ),
);
global $wgEnableUserEmail, $wgEmailAuthentication;
$disableEmailPrefs = false;
if ( $wgEmailAuthentication ) {
if ( $user->getEmail() ) {
if ( $user->getEmailAuthenticationTimestamp() ) {
// date and time are separate parameters to facilitate localisation.
// $time is kept for backward compat reasons.
// 'emailauthenticated' is also used in SpecialConfirmemail.php
$time = $wgLang->timeAndDate( $user->getEmailAuthenticationTimestamp(), true );
$d = $wgLang->date( $user->getEmailAuthenticationTimestamp(), true );
$t = $wgLang->time( $user->getEmailAuthenticationTimestamp(), true );
$emailauthenticated = wfMsgExt(
'emailauthenticated', 'parseinline',
array( $time, $d, $t )
) . '<br />';
$disableEmailPrefs = false;
} else {
$disableEmailPrefs = true;
$skin = $wgUser->getSkin();
$emailauthenticated = wfMsgExt( 'emailnotauthenticated', 'parseinline' ) . '<br />' .
$skin->link(
SpecialPage::getTitleFor( 'Confirmemail' ),
wfMsg( 'emailconfirmlink' ),
array(),
array(),
array( 'known', 'noclasses' )
) . '<br />';
}
} else {
$disableEmailPrefs = true;
$emailauthenticated = wfMsgHtml( 'noemailprefs' );
}
$defaultPreferences['emailauthentication'] = array(
'type' => 'info',
'raw' => true,
'section' => 'personal/email',
'label-message' => 'prefs-emailconfirm-label',
'default' => $emailauthenticated,
);
}
if ( $wgEnableUserEmail && $user->isAllowed( 'sendemail' ) ) {
$defaultPreferences['disablemail'] = array(
'type' => 'toggle',
'invert' => true,
'section' => 'personal/email',
'label-message' => 'allowemail',
'disabled' => $disableEmailPrefs,
);
$defaultPreferences['ccmeonemails'] = array(
'type' => 'toggle',
'section' => 'personal/email',
'label-message' => 'tog-ccmeonemails',
'disabled' => $disableEmailPrefs,
);
}
global $wgEnotifWatchlist;
if ( $wgEnotifWatchlist ) {
$defaultPreferences['enotifwatchlistpages'] = array(
'type' => 'toggle',
'section' => 'personal/email',
'label-message' => 'tog-enotifwatchlistpages',
'disabled' => $disableEmailPrefs,
);
}
global $wgEnotifUserTalk;
if ( $wgEnotifUserTalk ) {
$defaultPreferences['enotifusertalkpages'] = array(
'type' => 'toggle',
'section' => 'personal/email',
'label-message' => 'tog-enotifusertalkpages',
'disabled' => $disableEmailPrefs,
);
}
if ( $wgEnotifUserTalk || $wgEnotifWatchlist ) {
$defaultPreferences['enotifminoredits'] = array(
'type' => 'toggle',
'section' => 'personal/email',
'label-message' => 'tog-enotifminoredits',
'disabled' => $disableEmailPrefs,
);
global $wgEnotifRevealEditorAddress;
if ( $wgEnotifRevealEditorAddress ) {
$defaultPreferences['enotifrevealaddr'] = array(
'type' => 'toggle',
'section' => 'personal/email',
'label-message' => 'tog-enotifrevealaddr',
'disabled' => $disableEmailPrefs,
);
}
}
}
}
2009-06-21 14:16:11 +00:00
static function skinPreferences( $user, &$defaultPreferences ) {
## Skin #####################################
global $wgLang, $wgAllowUserCss, $wgAllowUserJs;
$defaultPreferences['skin'] = array(
'type' => 'radio',
'options' => self::generateSkinOptions( $user ),
Remove most named character references from output Recommit of r66254 to trunk. This was just find extensions phase3 -iname '*.php' \! -iname '*.i18n.php' \! -iname 'Messages*.php' \! -iname '*_Messages.php' -exec sed -i 's/&nbsp;/\&#160;/g;s/&mdash;/―/g;s/&bull;/•/g;s/&aacute;/á/g;s/&acute;/´/g;s/&agrave;/à/g;s/&alpha;/α/g;s/&auml;/ä/g;s/&ccedil;/ç/g;s/&copy;/©/g;s/&darr;/↓/g;s/&deg;/°/g;s/&eacute;/é/g;s/&ecirc;/ê/g;s/&euml;/ë/g;s/&egrave;/è/g;s/&euro;/€/g;s/&harr;//g;s/&hellip;/…/g;s/&iacute;/í/g;s/&igrave;/ì/g;s/&larr;/←/g;s/&ldquo;/“/g;s/&middot;/·/g;s/&minus;/−/g;s/&ndash;/–/g;s/&oacute;/ó/g;s/&ocirc;/ô/g;s/&oelig;/œ/g;s/&ograve;/ò/g;s/&otilde;/õ/g;s/&ouml;/ö/g;s/&pound;/£/g;s/&prime;/′/g;s/&Prime;/″/g;s/&raquo;/»/g;s/&rarr;/→/g;s/&rdquo;/”/g;s/&Sigma;/Σ/g;s/&times;/×/g;s/&uacute;/ú/g;s/&uarr;/↑/g;s/&uuml;/ü/g;s/&yen;/¥/g' {} + followed by reading over every single line of the resulting diff and fixing a whole bunch of false positives. The reason for this change is given in <http://lists.wikimedia.org/pipermail/wikitech-l/2010-April/047617.html>. I cleared it with Tim and Brion on IRC before committing. It might cause a few problems, but I tried to be careful; please report any issues. I skipped all messages files. I plan to make a follow-up commit that alters wfMsgExt() with 'escapenoentities' to sanitize all the entities. That way, the only messages that will be problems will be ones that output raw HTML, and we want to get rid of those anyway. This should get rid of all named entities everywhere except messages. I skipped a few things like &nbsp that I noticed in manual inspection, because they weren't well-formed XML anyway. Also, to everyone who uses non-breaking spaces when they could use a normal space, or nothing at all, or CSS padding: I still hate you. Die.
2010-05-30 17:33:59 +00:00
'label' => '&#160;',
'section' => 'rendering/skin',
);
2009-06-21 14:16:11 +00:00
# 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',
);
}
2009-04-27 01:49:09 +00:00
$selectedSkin = $user->getOption( 'skin' );
if ( in_array( $selectedSkin, array( 'cologneblue', 'standard' ) ) ) {
global $wgLang;
2009-06-21 14:16:11 +00:00
$settings = array_flip( $wgLang->getQuickbarSettings() );
$defaultPreferences['quickbar'] = array(
'type' => 'radio',
'options' => $settings,
'section' => 'rendering/skin',
'label-message' => 'qbsettings',
);
2009-04-27 01:49:09 +00:00
}
}
2009-06-21 14:16:11 +00:00
static function mathPreferences( $user, &$defaultPreferences ) {
## Math #####################################
global $wgUseTeX, $wgLang;
if ( $wgUseTeX ) {
$defaultPreferences['math'] = array(
'type' => 'radio',
'options' => array_flip( array_map( 'wfMsgHtml', $wgLang->getMathNames() ) ),
Remove most named character references from output Recommit of r66254 to trunk. This was just find extensions phase3 -iname '*.php' \! -iname '*.i18n.php' \! -iname 'Messages*.php' \! -iname '*_Messages.php' -exec sed -i 's/&nbsp;/\&#160;/g;s/&mdash;/―/g;s/&bull;/•/g;s/&aacute;/á/g;s/&acute;/´/g;s/&agrave;/à/g;s/&alpha;/α/g;s/&auml;/ä/g;s/&ccedil;/ç/g;s/&copy;/©/g;s/&darr;/↓/g;s/&deg;/°/g;s/&eacute;/é/g;s/&ecirc;/ê/g;s/&euml;/ë/g;s/&egrave;/è/g;s/&euro;/€/g;s/&harr;//g;s/&hellip;/…/g;s/&iacute;/í/g;s/&igrave;/ì/g;s/&larr;/←/g;s/&ldquo;/“/g;s/&middot;/·/g;s/&minus;/−/g;s/&ndash;/–/g;s/&oacute;/ó/g;s/&ocirc;/ô/g;s/&oelig;/œ/g;s/&ograve;/ò/g;s/&otilde;/õ/g;s/&ouml;/ö/g;s/&pound;/£/g;s/&prime;/′/g;s/&Prime;/″/g;s/&raquo;/»/g;s/&rarr;/→/g;s/&rdquo;/”/g;s/&Sigma;/Σ/g;s/&times;/×/g;s/&uacute;/ú/g;s/&uarr;/↑/g;s/&uuml;/ü/g;s/&yen;/¥/g' {} + followed by reading over every single line of the resulting diff and fixing a whole bunch of false positives. The reason for this change is given in <http://lists.wikimedia.org/pipermail/wikitech-l/2010-April/047617.html>. I cleared it with Tim and Brion on IRC before committing. It might cause a few problems, but I tried to be careful; please report any issues. I skipped all messages files. I plan to make a follow-up commit that alters wfMsgExt() with 'escapenoentities' to sanitize all the entities. That way, the only messages that will be problems will be ones that output raw HTML, and we want to get rid of those anyway. This should get rid of all named entities everywhere except messages. I skipped a few things like &nbsp that I noticed in manual inspection, because they weren't well-formed XML anyway. Also, to everyone who uses non-breaking spaces when they could use a normal space, or nothing at all, or CSS padding: I still hate you. Die.
2010-05-30 17:33:59 +00:00
'label' => '&#160;',
'section' => 'rendering/math',
);
}
}
2009-06-21 14:16:11 +00:00
static function filesPreferences( $user, &$defaultPreferences ) {
## Files #####################################
$defaultPreferences['imagesize'] = array(
'type' => 'select',
'options' => self::getImageSizes(),
'label-message' => 'imagemaxsize',
'section' => 'rendering/files',
);
$defaultPreferences['thumbsize'] = array(
'type' => 'select',
'options' => self::getThumbSizes(),
'label-message' => 'thumbsize',
'section' => 'rendering/files',
);
}
2009-06-21 14:16:11 +00:00
static function datetimePreferences( $user, &$defaultPreferences ) {
global $wgLang;
2009-06-21 14:16:11 +00:00
## Date and time #####################################
$dateOptions = self::getDateOptions();
if ( $dateOptions ) {
$defaultPreferences['date'] = array(
'type' => 'radio',
'options' => $dateOptions,
Remove most named character references from output Recommit of r66254 to trunk. This was just find extensions phase3 -iname '*.php' \! -iname '*.i18n.php' \! -iname 'Messages*.php' \! -iname '*_Messages.php' -exec sed -i 's/&nbsp;/\&#160;/g;s/&mdash;/―/g;s/&bull;/•/g;s/&aacute;/á/g;s/&acute;/´/g;s/&agrave;/à/g;s/&alpha;/α/g;s/&auml;/ä/g;s/&ccedil;/ç/g;s/&copy;/©/g;s/&darr;/↓/g;s/&deg;/°/g;s/&eacute;/é/g;s/&ecirc;/ê/g;s/&euml;/ë/g;s/&egrave;/è/g;s/&euro;/€/g;s/&harr;//g;s/&hellip;/…/g;s/&iacute;/í/g;s/&igrave;/ì/g;s/&larr;/←/g;s/&ldquo;/“/g;s/&middot;/·/g;s/&minus;/−/g;s/&ndash;/–/g;s/&oacute;/ó/g;s/&ocirc;/ô/g;s/&oelig;/œ/g;s/&ograve;/ò/g;s/&otilde;/õ/g;s/&ouml;/ö/g;s/&pound;/£/g;s/&prime;/′/g;s/&Prime;/″/g;s/&raquo;/»/g;s/&rarr;/→/g;s/&rdquo;/”/g;s/&Sigma;/Σ/g;s/&times;/×/g;s/&uacute;/ú/g;s/&uarr;/↑/g;s/&uuml;/ü/g;s/&yen;/¥/g' {} + followed by reading over every single line of the resulting diff and fixing a whole bunch of false positives. The reason for this change is given in <http://lists.wikimedia.org/pipermail/wikitech-l/2010-April/047617.html>. I cleared it with Tim and Brion on IRC before committing. It might cause a few problems, but I tried to be careful; please report any issues. I skipped all messages files. I plan to make a follow-up commit that alters wfMsgExt() with 'escapenoentities' to sanitize all the entities. That way, the only messages that will be problems will be ones that output raw HTML, and we want to get rid of those anyway. This should get rid of all named entities everywhere except messages. I skipped a few things like &nbsp that I noticed in manual inspection, because they weren't well-formed XML anyway. Also, to everyone who uses non-breaking spaces when they could use a normal space, or nothing at all, or CSS padding: I still hate you. Die.
2010-05-30 17:33:59 +00:00
'label' => '&#160;',
'section' => 'datetime/dateformat',
);
}
2009-06-21 14:16:11 +00:00
// Info
$nowlocal = Xml::element( 'span', array( 'id' => 'wpLocalTime' ),
$wgLang->time( $now = wfTimestampNow(), true ) );
$nowserver = $wgLang->time( $now, false ) .
Xml::hidden( 'wpServerTime', substr( $now, 8, 2 ) * 60 + substr( $now, 10, 2 ) );
2009-06-21 14:16:11 +00:00
$defaultPreferences['nowserver'] = array(
'type' => 'info',
'raw' => 1,
'label-message' => 'servertime',
'default' => $nowserver,
'section' => 'datetime/timeoffset',
);
2009-06-21 14:16:11 +00:00
$defaultPreferences['nowlocal'] = array(
'type' => 'info',
'raw' => 1,
'label-message' => 'localtime',
'default' => $nowlocal,
'section' => 'datetime/timeoffset',
);
2009-06-21 14:16:11 +00:00
// Grab existing pref.
$tzOffset = $user->getOption( 'timecorrection' );
$tz = explode( '|', $tzOffset, 2 );
2009-06-21 14:16:11 +00:00
$tzSetting = $tzOffset;
if ( count( $tz ) > 1 && $tz[0] == 'Offset' ) {
$minDiff = $tz[1];
$tzSetting = sprintf( '%+03d:%02d', floor( $minDiff / 60 ), abs( $minDiff ) % 60 );
}
2009-06-21 14:16:11 +00:00
$defaultPreferences['timecorrection'] = array(
'class' => 'HTMLSelectOrOtherField',
'label-message' => 'timezonelegend',
'options' => self::getTimezoneOptions(),
'default' => $tzSetting,
'size' => 20,
'section' => 'datetime/timeoffset',
);
}
2009-06-21 14:16:11 +00:00
static function renderingPreferences( $user, &$defaultPreferences ) {
## Page Rendering ##############################
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',
);
}
2009-06-21 14:16:11 +00:00
$stubThresholdValues = array( 0, 50, 100, 500, 1000, 2000, 5000, 10000 );
$stubThresholdOptions = array();
foreach ( $stubThresholdValues as $value ) {
$stubThresholdOptions[wfMsg( 'size-bytes', $value )] = $value;
}
2009-06-21 14:16:11 +00:00
$defaultPreferences['stubthreshold'] = array(
'type' => 'selectorother',
'section' => 'rendering/advancedrendering',
'options' => $stubThresholdOptions,
'size' => 20,
'label' => wfMsg( 'stub-threshold' ), // Raw HTML message. Yay?
);
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',
'label-message' => 'tog-nocache',
'section' => 'rendering/advancedrendering',
);
$defaultPreferences['showhiddencats'] = array(
'type' => 'toggle',
'section' => 'rendering/advancedrendering',
'label-message' => 'tog-showhiddencats'
);
$defaultPreferences['showjumplinks'] = array(
'type' => 'toggle',
'section' => 'rendering/advancedrendering',
'label-message' => 'tog-showjumplinks',
);
if ( $wgAllowUserCssPrefs ) {
$defaultPreferences['justify'] = array(
'type' => 'toggle',
'section' => 'rendering/advancedrendering',
'label-message' => 'tog-justify',
);
}
$defaultPreferences['numberheadings'] = array(
'type' => 'toggle',
'section' => 'rendering/advancedrendering',
'label-message' => 'tog-numberheadings',
);
}
2009-06-21 14:16:11 +00:00
static function editingPreferences( $user, &$defaultPreferences ) {
global $wgUseExternalEditor, $wgAllowUserCssPrefs;
## Editing #####################################
$defaultPreferences['cols'] = array(
'type' => 'int',
'label-message' => 'columns',
'section' => 'editing/textboxsize',
'min' => 4,
'max' => 1000,
);
$defaultPreferences['rows'] = array(
'type' => 'int',
'label-message' => 'rows',
'section' => 'editing/textboxsize',
'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-previewontop',
);
$defaultPreferences['previewonfirst'] = array(
'type' => 'toggle',
'section' => 'editing/advancedediting',
'label-message' => 'tog-previewonfirst',
);
if ( $wgAllowUserCssPrefs ) {
$defaultPreferences['editsection'] = array(
'type' => 'toggle',
'section' => 'editing/advancedediting',
'label-message' => 'tog-editsection',
);
}
$defaultPreferences['editsectiononrightclick'] = array(
'type' => 'toggle',
'section' => 'editing/advancedediting',
'label-message' => 'tog-editsectiononrightclick',
);
$defaultPreferences['editondblclick'] = array(
'type' => 'toggle',
'section' => 'editing/advancedediting',
'label-message' => 'tog-editondblclick',
);
$defaultPreferences['showtoolbar'] = array(
'type' => 'toggle',
'section' => 'editing/advancedediting',
'label-message' => 'tog-showtoolbar',
);
$defaultPreferences['minordefault'] = array(
'type' => 'toggle',
'section' => 'editing/advancedediting',
'label-message' => 'tog-minordefault',
);
if ( $wgUseExternalEditor ) {
$defaultPreferences['externaleditor'] = array(
'type' => 'toggle',
'section' => 'editing/advancedediting',
'label-message' => 'tog-externaleditor',
);
$defaultPreferences['externaldiff'] = array(
'type' => 'toggle',
'section' => 'editing/advancedediting',
'label-message' => 'tog-externaldiff',
);
}
$defaultPreferences['forceeditsummary'] = array(
'type' => 'toggle',
'section' => 'editing/advancedediting',
'label-message' => 'tog-forceeditsummary',
);
$defaultPreferences['uselivepreview'] = array(
'type' => 'toggle',
'section' => 'editing/advancedediting',
'label-message' => 'tog-uselivepreview',
);
}
2009-06-21 14:16:11 +00:00
static function rcPreferences( $user, &$defaultPreferences ) {
global $wgRCMaxAge, $wgUseRCPatrol, $wgLang;
## RecentChanges #####################################
$defaultPreferences['rcdays'] = array(
'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(
'type' => 'int',
'label-message' => 'recentchangescount',
'help-message' => 'prefs-help-recentchangescount',
'section' => 'rc/display',
);
$defaultPreferences['usenewrc'] = array(
'type' => 'toggle',
'label-message' => 'tog-usenewrc',
'section' => 'rc/advancedrc',
);
$defaultPreferences['hideminor'] = array(
'type' => 'toggle',
'label-message' => 'tog-hideminor',
'section' => 'rc/advancedrc',
);
2009-06-21 14:16:11 +00:00
if ( $wgUseRCPatrol ) {
$defaultPreferences['hidepatrolled'] = array(
'type' => 'toggle',
'section' => 'rc/advancedrc',
'label-message' => 'tog-hidepatrolled',
);
$defaultPreferences['newpageshidepatrolled'] = array(
'type' => 'toggle',
'section' => 'rc/advancedrc',
'label-message' => 'tog-newpageshidepatrolled',
);
}
2009-06-21 14:16:11 +00:00
global $wgRCShowWatchingUsers;
if ( $wgRCShowWatchingUsers ) {
$defaultPreferences['shownumberswatching'] = array(
'type' => 'toggle',
'section' => 'rc/advancedrc',
'label-message' => 'tog-shownumberswatching',
);
}
}
2009-06-21 14:16:11 +00:00
static function watchlistPreferences( $user, &$defaultPreferences ) {
global $wgUseRCPatrol, $wgEnableAPI;
## Watchlist #####################################
$defaultPreferences['watchlistdays'] = array(
'type' => 'float',
'min' => 0,
'max' => 7,
'section' => 'watchlist/display',
'help' => wfMsgHtml( 'prefs-watchlist-days-max' ),
'label-message' => 'prefs-watchlist-days',
);
$defaultPreferences['wllimit'] = array(
'type' => 'int',
'min' => 0,
'max' => 1000,
'label-message' => 'prefs-watchlist-edits',
'help' => wfMsgHtml( 'prefs-watchlist-edits-max' ),
'section' => 'watchlist/display',
);
$defaultPreferences['extendwatchlist'] = array(
'type' => 'toggle',
'section' => 'watchlist/advancedwatchlist',
'label-message' => 'tog-extendwatchlist',
);
$defaultPreferences['watchlisthideminor'] = array(
'type' => 'toggle',
'section' => 'watchlist/advancedwatchlist',
'label-message' => 'tog-watchlisthideminor',
);
$defaultPreferences['watchlisthidebots'] = array(
'type' => 'toggle',
'section' => 'watchlist/advancedwatchlist',
'label-message' => 'tog-watchlisthidebots',
);
$defaultPreferences['watchlisthideown'] = array(
'type' => 'toggle',
'section' => 'watchlist/advancedwatchlist',
'label-message' => 'tog-watchlisthideown',
);
$defaultPreferences['watchlisthideanons'] = array(
'type' => 'toggle',
'section' => 'watchlist/advancedwatchlist',
'label-message' => 'tog-watchlisthideanons',
);
$defaultPreferences['watchlisthideliu'] = array(
'type' => 'toggle',
'section' => 'watchlist/advancedwatchlist',
'label-message' => 'tog-watchlisthideliu',
);
if ( $wgUseRCPatrol ) {
$defaultPreferences['watchlisthidepatrolled'] = array(
'type' => 'toggle',
'section' => 'watchlist/advancedwatchlist',
'label-message' => 'tog-watchlisthidepatrolled',
);
}
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 )
);
}
2009-06-21 14:16:11 +00:00
$watchTypes = array(
'edit' => 'watchdefault',
'move' => 'watchmoves',
'delete' => 'watchdeletion'
);
// Kinda hacky
if ( $user->isAllowed( 'createpage' ) || $user->isAllowed( 'createtalk' ) ) {
$watchTypes['read'] = 'watchcreations';
}
2009-06-21 14:16:11 +00:00
foreach ( $watchTypes as $action => $pref ) {
if ( $user->isAllowed( $action ) ) {
$defaultPreferences[$pref] = array(
'type' => 'toggle',
'section' => 'watchlist/advancedwatchlist',
'label-message' => "tog-$pref",
);
}
}
}
2009-06-21 14:16:11 +00:00
static function searchPreferences( $user, &$defaultPreferences ) {
global $wgContLang;
2009-06-21 14:16:11 +00:00
## Search #####################################
$defaultPreferences['searchlimit'] = array(
'type' => 'int',
'label-message' => 'resultsperpage',
'section' => 'searchoptions/display',
'min' => 0,
);
$defaultPreferences['contextlines'] = array(
'type' => 'int',
'label-message' => 'contextlines',
'section' => 'searchoptions/display',
'min' => 0,
);
$defaultPreferences['contextchars'] = array(
'type' => 'int',
'label-message' => 'contextchars',
'section' => 'searchoptions/display',
'min' => 0,
);
global $wgEnableMWSuggest;
if ( $wgEnableMWSuggest ) {
$defaultPreferences['disablesuggest'] = array(
'type' => 'toggle',
'label-message' => 'mwsuggest-disable',
'section' => 'searchoptions/display',
);
}
global $wgVectorUseSimpleSearch;
if ( $wgVectorUseSimpleSearch ) {
$defaultPreferences['vector-simplesearch'] = array(
'type' => 'toggle',
'label-message' => 'vector-simplesearch-preference',
'section' => 'searchoptions/display'
);
}
2009-06-21 14:16:11 +00:00
$defaultPreferences['searcheverything'] = array(
'type' => 'toggle',
'label-message' => 'searcheverything-enable',
'section' => 'searchoptions/advancedsearchoptions',
);
2009-06-21 14:16:11 +00:00
// Searchable namespaces back-compat with old format
$searchableNamespaces = SearchEngine::searchableNamespaces();
2009-06-21 14:16:11 +00:00
$nsOptions = array();
foreach ( $wgContLang->getNamespaces() as $ns => $name ) {
if ( $ns < 0 ) {
continue;
}
$displayNs = str_replace( '_', ' ', $name );
2009-06-21 14:16:11 +00:00
if ( !$displayNs ) {
$displayNs = wfMsg( 'blanknamespace' );
}
2009-06-21 14:16:11 +00:00
2009-05-22 09:35:48 +00:00
$displayNs = htmlspecialchars( $displayNs );
$nsOptions[$displayNs] = $ns;
}
2009-06-21 14:16:11 +00:00
$defaultPreferences['searchnamespaces'] = array(
'type' => 'multiselect',
'label-message' => 'defaultns',
'options' => $nsOptions,
'section' => 'searchoptions/advancedsearchoptions',
'prefix' => 'searchNs',
);
}
2009-06-21 14:16:11 +00:00
static function miscPreferences( $user, &$defaultPreferences ) {
## Misc #####################################
$defaultPreferences['diffonly'] = array(
'type' => 'toggle',
'section' => 'misc/diffs',
'label-message' => 'tog-diffonly',
);
$defaultPreferences['norollbackdiff'] = array(
'type' => 'toggle',
'section' => 'misc/diffs',
'label-message' => 'tog-norollbackdiff',
);
2009-06-21 14:16:11 +00:00
// Stuff from Language::getExtraUserToggles()
global $wgContLang;
2009-06-21 14:16:11 +00:00
$toggles = $wgContLang->getExtraUserToggles();
2009-06-21 14:16:11 +00:00
foreach ( $toggles as $toggle ) {
$defaultPreferences[$toggle] = array(
'type' => 'toggle',
'section' => 'personal/i18n',
'label-message' => "tog-$toggle",
);
}
}
2009-06-21 14:16:11 +00:00
/**
* @param object $user The user object
* @return array Text/links to display as key; $skinkey as value
*/
static function generateSkinOptions( $user ) {
global $wgDefaultSkin, $wgLang, $wgAllowUserCss, $wgAllowUserJs;
$ret = array();
2009-06-21 14:16:11 +00:00
$mptitle = Title::newMainPage();
2009-05-22 09:35:48 +00:00
$previewtext = wfMsgHtml( 'skin-preview' );
# Only show members of Skin::getSkinNames() rather than
# $skinNames (skins is all skin names from Language.php)
$validSkinNames = Skin::getUsableSkins();
# Sort by UI skin name. First though need to update validSkinNames as sometimes
# the skinkey & UI skinname differ (e.g. "standard" skinkey is "Classic" in the UI).
foreach ( $validSkinNames as $skinkey => &$skinname ) {
$msgName = "skinname-{$skinkey}";
$localisedSkinName = wfMsg( $msgName );
2009-06-21 14:16:11 +00:00
if ( !wfEmptyMsg( $msgName, $localisedSkinName ) ) {
$skinname = htmlspecialchars( $localisedSkinName );
}
}
2009-06-21 14:16:11 +00:00
asort( $validSkinNames );
$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" ) );
$linkTools[] = "<a target='_blank' href=\"$mplink\">$previewtext</a>";
# Create links to user CSS/JS pages
if ( $wgAllowUserCss ) {
2009-06-21 14:16:11 +00:00
$cssPage = Title::makeTitleSafe( NS_USER, $user->getName() . '/' . $skinkey . '.css' );
$linkTools[] = $sk->link( $cssPage, wfMsgHtml( 'prefs-custom-css' ) );
}
if ( $wgAllowUserJs ) {
2009-06-21 14:16:11 +00:00
$jsPage = Title::makeTitleSafe( NS_USER, $user->getName() . '/' . $skinkey . '.js' );
$linkTools[] = $sk->link( $jsPage, wfMsgHtml( 'prefs-custom-js' ) );
}
$display = $sn . ' ' . wfMsg( 'parentheses', $wgLang->pipeList( $linkTools ) );
$ret[$display] = $skinkey;
}
2009-06-21 14:16:11 +00:00
return $ret;
}
2009-06-21 14:16:11 +00:00
static function getDateOptions() {
global $wgLang;
$dateopts = $wgLang->getDatePreferences();
2009-06-21 14:16:11 +00:00
$ret = array();
2009-06-21 14:16:11 +00:00
if ( $dateopts ) {
if ( !in_array( 'default', $dateopts ) ) {
$dateopts[] = 'default'; // Make sure default is always valid
2009-06-21 14:16:11 +00:00
// Bug 19237
}
// KLUGE: site default might not be valid for user language
global $wgDefaultUserOptions;
if ( !in_array( $wgDefaultUserOptions['date'], $dateopts ) ) {
$wgDefaultUserOptions['date'] = 'default';
}
2009-06-21 14:16:11 +00:00
$idCnt = 0;
$epoch = wfTimestampNow();
foreach ( $dateopts as $key ) {
if ( $key == 'default' ) {
2009-05-22 09:35:48 +00:00
$formatted = wfMsgHtml( 'datedefault' );
} else {
2009-06-21 14:16:11 +00:00
$formatted = htmlspecialchars( $wgLang->timeanddate( $epoch, false, $key ) );
}
$ret[$formatted] = $key;
}
}
return $ret;
}
2009-06-21 14:16:11 +00:00
static function getImageSizes() {
global $wgImageLimits;
2009-06-21 14:16:11 +00:00
$ret = array();
2009-06-21 14:16:11 +00:00
foreach ( $wgImageLimits as $index => $limits ) {
2010-03-13 20:49:34 +00:00
$display = "{$limits[0]}×{$limits[1]}" . wfMsg( 'unit-pixel' );
$ret[$display] = $index;
}
2009-06-21 14:16:11 +00:00
return $ret;
}
2009-06-21 14:16:11 +00:00
static function getThumbSizes() {
global $wgThumbLimits;
2009-06-21 14:16:11 +00:00
$ret = array();
2009-06-21 14:16:11 +00:00
foreach ( $wgThumbLimits as $index => $size ) {
2009-06-21 14:16:11 +00:00
$display = $size . wfMsg( 'unit-pixel' );
$ret[$display] = $index;
}
2009-06-21 14:16:11 +00:00
return $ret;
}
2009-06-21 14:16:11 +00:00
static function validateSignature( $signature, $alldata ) {
global $wgParser, $wgMaxSigChars, $wgLang;
if ( mb_strlen( $signature ) > $wgMaxSigChars ) {
return Xml::element( 'span', array( 'class' => 'error' ),
wfMsgExt( 'badsiglength', 'parsemag',
$wgLang->formatNum( $wgMaxSigChars )
)
);
} elseif ( !empty( $alldata['fancysig'] ) &&
false === $wgParser->validateSig( $signature ) ) {
return Xml::element( 'span', array( 'class' => 'error' ), wfMsg( 'badsig' ) );
} else {
return true;
}
}
2009-06-21 14:16:11 +00:00
static function cleanSignature( $signature, $alldata ) {
global $wgParser;
if ( $alldata['fancysig'] ) {
$signature = $wgParser->cleanSig( $signature );
} else {
// When no fancy sig used, make sure ~{3,5} get removed.
$signature = $wgParser->cleanSigInSig( $signature );
}
2009-06-21 14:16:11 +00:00
return $signature;
}
2009-06-21 14:16:11 +00:00
static function validateEmail( $email, $alldata ) {
if ( $email && !User::isValidEmailAddr( $email ) ) {
return wfMsgExt( 'invalidemailaddress', 'parseinline' );
}
2009-06-21 14:16:11 +00:00
global $wgEmailConfirmToEdit;
if ( $wgEmailConfirmToEdit && !$email ) {
return wfMsgExt( 'noemailtitle', 'parseinline' );
}
return true;
}
2009-06-21 14:16:11 +00:00
static function getFormObject( $user ) {
$formDescriptor = Preferences::getPreferences( $user );
$htmlForm = new PreferencesForm( $formDescriptor, 'prefs' );
2009-06-21 14:16:11 +00:00
$htmlForm->setSubmitText( wfMsg( 'saveprefs' ) );
# Used message keys: 'accesskey-preferences-save', 'tooltip-preferences-save'
$htmlForm->setSubmitTooltip( 'preferences-save' );
$htmlForm->setTitle( SpecialPage::getTitleFor( 'Preferences' ) );
$htmlForm->setSubmitID( 'prefsubmit' );
$htmlForm->setSubmitCallback( array( 'Preferences', 'tryFormSubmit' ) );
2009-06-21 14:16:11 +00:00
return $htmlForm;
}
2009-06-21 14:16:11 +00:00
static function getTimezoneOptions() {
$opt = array();
2009-06-21 14:16:11 +00:00
global $wgLocalTZoffset;
$opt[wfMsg( 'timezoneuseserverdefault' )] = "System|$wgLocalTZoffset";
$opt[wfMsg( 'timezoneuseoffset' )] = 'other';
$opt[wfMsg( 'guesstimezone' )] = 'guess';
if ( function_exists( 'timezone_identifiers_list' ) ) {
# Read timezone list
$tzs = timezone_identifiers_list();
sort( $tzs );
$tzRegions = array();
$tzRegions['Africa'] = wfMsg( 'timezoneregion-africa' );
$tzRegions['America'] = wfMsg( 'timezoneregion-america' );
$tzRegions['Antarctica'] = wfMsg( 'timezoneregion-antarctica' );
$tzRegions['Arctic'] = wfMsg( 'timezoneregion-arctic' );
$tzRegions['Asia'] = wfMsg( 'timezoneregion-asia' );
$tzRegions['Atlantic'] = wfMsg( 'timezoneregion-atlantic' );
$tzRegions['Australia'] = wfMsg( 'timezoneregion-australia' );
$tzRegions['Europe'] = wfMsg( 'timezoneregion-europe' );
$tzRegions['Indian'] = wfMsg( 'timezoneregion-indian' );
$tzRegions['Pacific'] = wfMsg( 'timezoneregion-pacific' );
asort( $tzRegions );
2009-06-21 14:16:11 +00:00
$prefill = array_fill_keys( array_values( $tzRegions ), array() );
$opt = array_merge( $opt, $prefill );
$now = date_create( 'now' );
foreach ( $tzs as $tz ) {
$z = explode( '/', $tz, 2 );
# timezone_identifiers_list() returns a number of
# backwards-compatibility entries. This filters them out of the
# list presented to the user.
if ( count( $z ) != 2 || !array_key_exists( $z[0], $tzRegions ) ) {
continue;
}
# Localize region
$z[0] = $tzRegions[$z[0]];
$minDiff = floor( timezone_offset_get( timezone_open( $tz ), $now ) / 60 );
$display = str_replace( '_', ' ', $z[0] . '/' . $z[1] );
$value = "ZoneInfo|$minDiff|$tz";
$opt[$z[0]][$display] = $value;
}
}
return $opt;
}
2009-06-21 14:16:11 +00:00
static function filterTimezoneInput( $tz, $alldata ) {
$data = explode( '|', $tz, 3 );
switch ( $data[0] ) {
case 'ZoneInfo':
case 'System':
return $tz;
default:
$data = explode( ':', $tz, 2 );
$minDiff = 0;
if ( count( $data ) == 2 ) {
$data[0] = intval( $data[0] );
$data[1] = intval( $data[1] );
$minDiff = abs( $data[0] ) * 60 + $data[1];
if ( $data[0] < 0 ) $minDiff = - $minDiff;
} else {
$minDiff = intval( $data[0] ) * 60;
}
# Max is +14:00 and min is -12:00, see:
# http://en.wikipedia.org/wiki/Timezone
$minDiff = min( $minDiff, 840 ); # 14:00
$minDiff = max( $minDiff, - 720 ); # -12:00
return 'Offset|' . $minDiff;
}
}
static function tryFormSubmit( $formData, $entryPoint = 'internal' ) {
global $wgUser, $wgEmailAuthentication, $wgEnableEmail;
2009-06-21 14:16:11 +00:00
$result = true;
2009-06-21 14:16:11 +00:00
// Filter input
foreach ( array_keys( $formData ) as $name ) {
2009-06-21 14:16:11 +00:00
if ( isset( self::$saveFilters[$name] ) ) {
$formData[$name] =
call_user_func( self::$saveFilters[$name], $formData[$name], $formData );
}
}
2009-06-21 14:16:11 +00:00
// Stuff that shouldn't be saved as a preference.
$saveBlacklist = array(
2009-06-21 14:16:11 +00:00
'realname',
'emailaddress',
);
if ( $wgEnableEmail ) {
2010-02-28 19:34:23 +00:00
$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
2010-02-28 19:34:23 +00:00
$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.
2010-02-28 19:34:23 +00:00
$result = $wgUser->sendConfirmationMail( $oldaddr != '' );
if ( WikiError::isError( $result ) ) {
return wfMsg( 'mailerror', htmlspecialchars( $result->getMessage() ) );
} elseif ( $entryPoint == 'ui' ) {
$result = 'eauth';
}
}
} else {
2010-02-28 19:34:23 +00:00
$wgUser->setEmail( $newaddr );
}
if ( $oldaddr != $newaddr ) {
2010-02-28 19:34:23 +00:00
wfRunHooks( 'PrefsEmailAudit', array( $wgUser, $oldaddr, $newaddr ) );
}
}
2009-06-21 14:16:11 +00:00
// Fortunately, the realname field is MUCH simpler
global $wgHiddenPrefs;
if ( !in_array( 'realname', $wgHiddenPrefs ) ) {
$realName = $formData['realname'];
$wgUser->setRealName( $realName );
}
2009-06-21 14:16:11 +00:00
foreach ( $saveBlacklist as $b ) {
unset( $formData[$b] );
}
2009-06-21 14:16:11 +00:00
// Keeps old preferences from interfering due to back-compat
// code, etc.
$wgUser->resetOptions();
2009-06-21 14:16:11 +00:00
foreach ( $formData as $key => $value ) {
$wgUser->setOption( $key, $value );
}
2009-06-21 14:16:11 +00:00
$wgUser->saveSettings();
2009-06-21 14:16:11 +00:00
return $result;
}
2009-06-21 14:16:11 +00:00
public static function tryUISubmit( $formData ) {
$res = self::tryFormSubmit( $formData, 'ui' );
2009-06-21 14:16:11 +00:00
if ( $res ) {
$urlOptions = array( 'success' );
if ( $res === 'eauth' ) {
$urlOptions[] = 'eauth';
}
2009-06-21 14:16:11 +00:00
$queryString = implode( '&', $urlOptions );
2009-06-21 14:16:11 +00:00
$url = SpecialPage::getTitleFor( 'Preferences' )->getFullURL( $queryString );
global $wgOut;
$wgOut->redirect( $url );
}
2009-06-21 14:16:11 +00:00
return true;
}
2009-06-21 14:16:11 +00:00
public static function loadOldSearchNs( $user ) {
$searchableNamespaces = SearchEngine::searchableNamespaces();
// Back compat with old format
$arr = array();
2009-06-21 14:16:11 +00:00
foreach ( $searchableNamespaces as $ns => $name ) {
if ( $user->getOption( 'searchNs' . $ns ) ) {
$arr[] = $ns;
}
}
2009-06-21 14:16:11 +00:00
return $arr;
}
}
/** Some tweaks to allow js prefs to work */
class PreferencesForm extends HTMLForm {
function wrapForm( $html ) {
$html = Xml::tags( 'div', array( 'id' => 'preferences' ), $html );
2009-06-21 14:16:11 +00:00
return parent::wrapForm( $html );
}
2009-06-21 14:16:11 +00:00
function getButtons() {
$html = parent::getButtons();
2009-06-21 14:16:11 +00:00
global $wgUser;
2009-06-21 14:16:11 +00:00
$sk = $wgUser->getSkin();
$t = SpecialPage::getTitleFor( 'Preferences', 'reset' );
2009-06-21 14:16:11 +00:00
2009-05-22 09:35:48 +00:00
$html .= "\n" . $sk->link( $t, wfMsgHtml( 'restoreprefs' ) );
2009-06-21 14:16:11 +00:00
$html = Xml::tags( 'div', array( 'class' => 'mw-prefs-buttons' ), $html );
2009-06-21 14:16:11 +00:00
return $html;
}
2009-06-21 14:16:11 +00:00
function filterDataForSubmit( $data ) {
// Support for separating MultiSelect preferences into multiple preferences
// Due to lack of array support.
foreach ( $this->mFlatFields as $fieldname => $field ) {
$info = $field->mParams;
if ( $field instanceof HTMLMultiSelectField ) {
$options = HTMLFormField::flattenOptions( $info['options'] );
2009-06-21 14:16:11 +00:00
$prefix = isset( $info['prefix'] ) ? $info['prefix'] : $fieldname;
foreach ( $options as $opt ) {
$data["$prefix$opt"] = in_array( $opt, $data[$fieldname] );
}
2009-06-21 14:16:11 +00:00
unset( $data[$fieldname] );
}
}
2009-06-21 14:16:11 +00:00
return $data;
}
}