X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FPreferences.php;h=b428e87be4d4831dddbe749604f42f282659a30c;hb=26ca77b85d3e6e54aea1418ffc196f0b6dc62e1c;hp=d86b19a5ce82af8756fc68199e97fc820e15c3e5;hpb=ea42d90053b36cef47f318a1d50c18dfafc6b7b8;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Preferences.php b/includes/Preferences.php index d86b19a5ce..b428e87be4 100644 --- a/includes/Preferences.php +++ b/includes/Preferences.php @@ -21,6 +21,7 @@ */ use MediaWiki\Auth\AuthManager; use MediaWiki\Auth\PasswordAuthenticationRequest; +use MediaWiki\MediaWikiServices; /** * We're now using the HTMLForm object with some customisation to generate the @@ -54,8 +55,6 @@ class Preferences { /** @var array */ protected static $saveFilters = [ 'timecorrection' => [ 'Preferences', 'filterTimezoneInput' ], - 'cols' => [ 'Preferences', 'filterIntval' ], - 'rows' => [ 'Preferences', 'filterIntval' ], 'rclimit' => [ 'Preferences', 'filterIntval' ], 'wllimit' => [ 'Preferences', 'filterIntval' ], 'searchlimit' => [ 'Preferences', 'filterIntval' ], @@ -121,7 +120,7 @@ class Preferences { } } - # # Make sure that form fields have their parent set. See bug 41337. + # # Make sure that form fields have their parent set. See T43337. $dummyForm = new HTMLForm( [], $context ); $disable = !$user->isAllowed( 'editmyoptions' ); @@ -223,24 +222,48 @@ class Preferences { 'section' => 'personal/info', ]; + $lang = $context->getLanguage(); + # Get groups to which the user belongs $userEffectiveGroups = $user->getEffectiveGroups(); - $userGroups = $userMembers = []; + $userGroupMemberships = $user->getGroupMemberships(); + $userGroups = $userMembers = $userTempGroups = $userTempMembers = []; 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, $userName ); - $userMembers[] = User::makeGroupLinkHTML( $ueg, $memberName ); - } - asort( $userGroups ); - asort( $userMembers ); + if ( isset( $userGroupMemberships[$ueg] ) ) { + $groupStringOrObject = $userGroupMemberships[$ueg]; + } else { + $groupStringOrObject = $ueg; + } - $lang = $context->getLanguage(); + $userG = UserGroupMembership::getLink( $groupStringOrObject, $context, 'html' ); + $userM = UserGroupMembership::getLink( $groupStringOrObject, $context, 'html', + $userName ); + + // Store expiring groups separately, so we can place them before non-expiring + // groups in the list. This is to avoid the ambiguity of something like + // "administrator, bureaucrat (until X date)" -- users might wonder whether the + // expiry date applies to both groups, or just the last one + if ( $groupStringOrObject instanceof UserGroupMembership && + $groupStringOrObject->getExpiry() + ) { + $userTempGroups[] = $userG; + $userTempMembers[] = $userM; + } else { + $userGroups[] = $userG; + $userMembers[] = $userM; + } + } + sort( $userGroups ); + sort( $userMembers ); + sort( $userTempGroups ); + sort( $userTempMembers ); + $userGroups = array_merge( $userTempGroups, $userGroups ); + $userMembers = array_merge( $userTempMembers, $userMembers ); $defaultPreferences['usergroups'] = [ 'type' => 'info', @@ -253,7 +276,9 @@ class Preferences { 'section' => 'personal/info', ]; - $editCount = Linker::link( SpecialPage::getTitleFor( "Contributions", $userName ), + $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer(); + + $editCount = $linkRenderer->makeLink( SpecialPage::getTitleFor( "Contributions", $userName ), $lang->formatNum( $user->getEditCount() ) ); $defaultPreferences['editcount'] = [ @@ -297,8 +322,8 @@ class Preferences { if ( $canEditPrivateInfo && $authManager->allowsAuthenticationDataChange( new PasswordAuthenticationRequest(), false )->isGood() ) { - $link = Linker::link( SpecialPage::getTitleFor( 'ChangePassword' ), - $context->msg( 'prefs-resetpass' )->escaped(), [], + $link = $linkRenderer->makeLink( SpecialPage::getTitleFor( 'ChangePassword' ), + $context->msg( 'prefs-resetpass' )->text(), [], [ 'returnto' => SpecialPage::getTitleFor( 'Preferences' )->getPrefixedText() ] ); $defaultPreferences['password'] = [ @@ -448,9 +473,9 @@ class Preferences { $emailAddress = $user->getEmail() ? htmlspecialchars( $user->getEmail() ) : ''; if ( $canEditPrivateInfo && $authManager->allowsPropertyChange( 'emailaddress' ) ) { - $link = Linker::link( + $link = $linkRenderer->makeLink( SpecialPage::getTitleFor( 'ChangeEmail' ), - $context->msg( $user->getEmail() ? 'prefs-changeemail' : 'prefs-setemail' )->escaped(), + $context->msg( $user->getEmail() ? 'prefs-changeemail' : 'prefs-setemail' )->text(), [], [ 'returnto' => SpecialPage::getTitleFor( 'Preferences' )->getPrefixedText() ] ); @@ -492,9 +517,9 @@ class Preferences { } else { $disableEmailPrefs = true; $emailauthenticated = $context->msg( 'emailnotauthenticated' )->parse() . '
' . - Linker::linkKnown( + $linkRenderer->makeKnownLink( SpecialPage::getTitleFor( 'Confirmemail' ), - $context->msg( 'emailconfirmlink' )->escaped() + $context->msg( 'emailconfirmlink' )->text() ) . '
'; $emailauthenticationclass = "mw-email-not-authenticated"; } @@ -601,14 +626,15 @@ class Preferences { $linkTools = []; $userName = $user->getName(); + $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer(); if ( $allowUserCss ) { $cssPage = Title::makeTitleSafe( NS_USER, $userName . '/common.css' ); - $linkTools[] = Linker::link( $cssPage, $context->msg( 'prefs-custom-css' )->escaped() ); + $linkTools[] = $linkRenderer->makeLink( $cssPage, $context->msg( 'prefs-custom-css' )->text() ); } if ( $allowUserJs ) { $jsPage = Title::makeTitleSafe( NS_USER, $userName . '/common.js' ); - $linkTools[] = Linker::link( $jsPage, $context->msg( 'prefs-custom-js' )->escaped() ); + $linkTools[] = $linkRenderer->makeLink( $jsPage, $context->msg( 'prefs-custom-js' )->text() ); } $defaultPreferences['commoncssjs'] = [ @@ -692,19 +718,23 @@ class Preferences { $tzOptions = self::getTimezoneOptions( $context ); $tzSetting = $tzOffset; - if ( count( $tz ) > 1 && $tz[0] == 'Offset' ) { - $minDiff = $tz[1]; - $tzSetting = sprintf( '%+03d:%02d', floor( $minDiff / 60 ), abs( $minDiff ) % 60 ); - } elseif ( count( $tz ) > 1 && $tz[0] == 'ZoneInfo' && + if ( count( $tz ) > 1 && $tz[0] == 'ZoneInfo' && !in_array( $tzOffset, HTMLFormField::flattenOptions( $tzOptions ) ) ) { - # Timezone offset can vary with DST - $userTZ = timezone_open( $tz[2] ); - if ( $userTZ !== false ) { - $minDiff = floor( timezone_offset_get( $userTZ, date_create( 'now' ) ) / 60 ); + // Timezone offset can vary with DST + try { + $userTZ = new DateTimeZone( $tz[2] ); + $minDiff = floor( $userTZ->getOffset( new DateTime( 'now' ) ) / 60 ); $tzSetting = "ZoneInfo|$minDiff|{$tz[2]}"; + } catch ( Exception $e ) { + // User has an invalid time zone set. Fall back to just using the offset + $tz[0] = 'Offset'; } } + if ( count( $tz ) > 1 && $tz[0] == 'Offset' ) { + $minDiff = $tz[1]; + $tzSetting = sprintf( '%+03d:%02d', floor( $minDiff / 60 ), abs( $minDiff ) % 60 ); + } $defaultPreferences['timecorrection'] = [ 'class' => 'HTMLSelectOrOtherField', @@ -809,20 +839,7 @@ class Preferences { ] ]; } - $defaultPreferences['cols'] = [ - 'type' => 'int', - 'label-message' => 'columns', - 'section' => 'editing/editor', - 'min' => 4, - 'max' => 1000, - ]; - $defaultPreferences['rows'] = [ - 'type' => 'int', - 'label-message' => 'rows', - 'section' => 'editing/editor', - 'min' => 4, - 'max' => 1000, - ]; + if ( $user->isAllowed( 'minoredit' ) ) { $defaultPreferences['minordefault'] = [ 'type' => 'toggle', @@ -830,6 +847,7 @@ class Preferences { 'label-message' => 'tog-minordefault', ]; } + $defaultPreferences['forceeditsummary'] = [ 'type' => 'toggle', 'section' => 'editing/editor', @@ -948,11 +966,12 @@ class Preferences { 'raw' => [ 'EditWatchlist', 'raw' ], 'clear' => [ 'EditWatchlist', 'clear' ], ]; + $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer(); foreach ( $editWatchlistModes as $editWatchlistMode => $mode ) { // Messages: prefs-editwatchlist-edit, prefs-editwatchlist-raw, prefs-editwatchlist-clear - $editWatchlistLinks[] = Linker::linkKnown( + $editWatchlistLinks[] = $linkRenderer->makeKnownLink( SpecialPage::getTitleFor( $mode[0], $mode[1] ), - $context->msg( "prefs-editwatchlist-{$editWatchlistMode}" )->parse() + new HtmlArmor( $context->msg( "prefs-editwatchlist-{$editWatchlistMode}" )->parse() ) ); } @@ -1110,6 +1129,8 @@ class Preferences { $mptitle = Title::newMainPage(); $previewtext = $context->msg( 'skin-preview' )->escaped(); + $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer(); + # Only show skins that aren't disabled in $wgSkipSkins $validSkinNames = Skin::getAllowedSkins(); @@ -1145,12 +1166,12 @@ class Preferences { # Create links to user CSS/JS pages if ( $allowUserCss ) { $cssPage = Title::makeTitleSafe( NS_USER, $user->getName() . '/' . $skinkey . '.css' ); - $linkTools[] = Linker::link( $cssPage, $context->msg( 'prefs-custom-css' )->escaped() ); + $linkTools[] = $linkRenderer->makeLink( $cssPage, $context->msg( 'prefs-custom-css' )->text() ); } if ( $allowUserJs ) { $jsPage = Title::makeTitleSafe( NS_USER, $user->getName() . '/' . $skinkey . '.js' ); - $linkTools[] = Linker::link( $jsPage, $context->msg( 'prefs-custom-js' )->escaped() ); + $linkTools[] = $linkRenderer->makeLink( $jsPage, $context->msg( 'prefs-custom-js' )->text() ); } $display = $sn . ' ' . $context->msg( 'parentheses' ) @@ -1180,8 +1201,7 @@ class Preferences { if ( $dateopts ) { if ( !in_array( 'default', $dateopts ) ) { - $dateopts[] = 'default'; // Make sure default is always valid - // Bug 19237 + $dateopts[] = 'default'; // Make sure default is always valid T21237 } // FIXME KLUGE: site default might not be valid for user language @@ -1212,7 +1232,8 @@ class Preferences { $pixels = $context->msg( 'unit-pixel' )->text(); foreach ( $context->getConfig()->get( 'ImageLimits' ) as $index => $limits ) { - $display = "{$limits[0]}×{$limits[1]}" . $pixels; + // Note: A left-to-right marker (\u200e) is inserted, see T144386 + $display = "{$limits[0]}" . json_decode( '"\u200e"' ) . "×{$limits[1]}" . $pixels; $ret[$display] = $index; } @@ -1384,6 +1405,24 @@ class Preferences { $data = explode( '|', $tz, 3 ); switch ( $data[0] ) { case 'ZoneInfo': + $valid = false; + + if ( count( $data ) === 3 ) { + // Make sure this timezone exists + try { + new DateTimeZone( $data[2] ); + // If the constructor didn't throw, we know it's valid + $valid = true; + } catch ( Exception $e ) { + // Not a valid timezone + } + } + + if ( !$valid ) { + // If the supplied timezone doesn't exist, fall back to the encoded offset + return 'Offset|' . intval( $tz[1] ); + } + return $tz; case 'System': return $tz; default: @@ -1402,7 +1441,7 @@ class Preferences { # Max is +14:00 and min is -12:00, see: # https://en.wikipedia.org/wiki/Timezone $minDiff = min( $minDiff, 840 ); # 14:00 - $minDiff = max( $minDiff, - 720 ); # -12:00 + $minDiff = max( $minDiff, -720 ); # -12:00 return 'Offset|' . $minDiff; } } @@ -1624,7 +1663,8 @@ class PreferencesForm extends HTMLForm { if ( $this->getModifiedUser()->isAllowed( 'editmyoptions' ) ) { $t = SpecialPage::getTitleFor( 'Preferences', 'reset' ); - $html .= "\n" . Linker::link( $t, $this->msg( 'restoreprefs' )->escaped(), + $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer(); + $html .= "\n" . $linkRenderer->makeLink( $t, $this->msg( 'restoreprefs' )->text(), Html::buttonAttributes( $attrs, [ 'mw-ui-quiet' ] ) ); $html = Xml::tags( 'div', [ 'class' => 'mw-prefs-buttons' ], $html );