X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;ds=sidebyside;f=includes%2FProtectionForm.php;h=51c29233852f7ae97e181ffe4027d19ae67b27ec;hb=c35b81bda40abd7f8a1bb022f9d4a2ae9b3e7afb;hp=1443d1ca69d1a315b1aeae9d28958d30c4ff0be2;hpb=8f27a3208e465e52a54533515853f1210d44fd9d;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/ProtectionForm.php b/includes/ProtectionForm.php index 1443d1ca69..51c2923385 100644 --- a/includes/ProtectionForm.php +++ b/includes/ProtectionForm.php @@ -22,13 +22,14 @@ * * @file */ +use MediaWiki\MediaWikiServices; /** * Handles the page protection UI and backend */ class ProtectionForm { /** @var array A map of action to restriction level, from request or default */ - protected $mRestrictions = array(); + protected $mRestrictions = []; /** @var string The custom/additional protection reason */ protected $mReason = ''; @@ -40,22 +41,22 @@ class ProtectionForm { protected $mCascade = false; /** @var array Map of action to "other" expiry time. Used in preference to mExpirySelection. */ - protected $mExpiry = array(); + protected $mExpiry = []; /** * @var array Map of action to value selected in expiry drop-down list. * Will be set to 'othertime' whenever mExpiry is set. */ - protected $mExpirySelection = array(); + protected $mExpirySelection = []; /** @var array Permissions errors for the protect action */ - protected $mPermErrors = array(); + protected $mPermErrors = []; /** @var array Types (i.e. actions) for which levels can be selected */ - protected $mApplicableTypes = array(); + protected $mApplicableTypes = []; /** @var array Map of action to the expiry time of the existing protection */ - protected $mExistingExpiry = array(); + protected $mExistingExpiry = []; /** @var IContextSource */ private $mContext; @@ -70,15 +71,17 @@ class ProtectionForm { // Check if the form should be disabled. // If it is, the form will be available in read-only to show levels. $this->mPermErrors = $this->mTitle->getUserPermissionsErrors( - 'protect', $this->mContext->getUser() + 'protect', + $this->mContext->getUser(), + $this->mContext->getRequest()->wasPosted() ? 'secure' : 'full' // T92357 ); if ( wfReadOnly() ) { - $this->mPermErrors[] = array( 'readonlytext', wfReadOnlyReason() ); + $this->mPermErrors[] = [ 'readonlytext', wfReadOnlyReason() ]; } - $this->disabled = $this->mPermErrors != array(); + $this->disabled = $this->mPermErrors != []; $this->disabledAttrib = $this->disabled - ? array( 'disabled' => 'disabled' ) - : array(); + ? [ 'disabled' => 'disabled' ] + : []; $this->loadData(); } @@ -146,7 +149,7 @@ class ProtectionForm { * * @param string $action * - * @return string 14-char timestamp or "infinity", or false if the input was invalid + * @return string|false 14-char timestamp or "infinity", or false if the input was invalid */ function getExpiry( $action ) { if ( $this->mExpirySelection[$action] == 'existing' ) { @@ -176,7 +179,7 @@ class ProtectionForm { * Main entry point for action=protect and action=unprotect */ function execute() { - if ( MWNamespace::getRestrictionLevels( $this->mTitle->getNamespace() ) === array( '' ) ) { + if ( MWNamespace::getRestrictionLevels( $this->mTitle->getNamespace() ) === [ '' ] ) { throw new ErrorPageError( 'protect-badnamespace-title', 'protect-badnamespace-text' ); } @@ -206,7 +209,7 @@ class ProtectionForm { $out->addHTML( "

{$err}

\n" ); } - if ( $this->mTitle->getRestrictionTypes() === array() ) { + if ( $this->mTitle->getRestrictionTypes() === [] ) { // No restriction types available for the current title // this might happen if an extension alters the available types $out->setPageTitle( $this->mContext->msg( @@ -232,7 +235,7 @@ class ProtectionForm { /** @todo FIXME: i18n issue, should use formatted number. */ $out->wrapWikiMsg( "
\n$1\n" . $titles . "
", - array( 'protect-cascadeon', count( $cascadeSources ) ) + [ 'protect-cascadeon', count( $cascadeSources ) ] ); } @@ -270,8 +273,8 @@ class ProtectionForm { $user = $this->mContext->getUser(); $out = $this->mContext->getOutput(); $token = $request->getVal( 'wpEditToken' ); - if ( !$user->matchEditToken( $token, array( 'protect', $this->mTitle->getPrefixedDBkey() ) ) ) { - $this->show( array( 'sessionfailure' ) ); + if ( !$user->matchEditToken( $token, [ 'protect', $this->mTitle->getPrefixedDBkey() ] ) ) { + $this->show( [ 'sessionfailure' ] ); return false; } @@ -283,18 +286,18 @@ class ProtectionForm { } elseif ( $reasonstr == 'other' ) { $reasonstr = $this->mReason; } - $expiry = array(); + $expiry = []; foreach ( $this->mApplicableTypes as $action ) { $expiry[$action] = $this->getExpiry( $action ); if ( empty( $this->mRestrictions[$action] ) ) { continue; // unprotected } if ( !$expiry[$action] ) { - $this->show( array( 'protect_expiry_invalid' ) ); + $this->show( [ 'protect_expiry_invalid' ] ); return false; } if ( $expiry[$action] < wfTimestampNow() ) { - $this->show( array( 'protect_expiry_old' ) ); + $this->show( [ 'protect_expiry_old' ] ); return false; } } @@ -321,9 +324,9 @@ class ProtectionForm { * you can also return an array of message name and its parameters */ $errorMsg = ''; - if ( !Hooks::run( 'ProtectionForm::save', array( $this->mArticle, &$errorMsg, $reasonstr ) ) ) { + if ( !Hooks::run( 'ProtectionForm::save', [ $this->mArticle, &$errorMsg, $reasonstr ] ) ) { if ( $errorMsg == '' ) { - $errorMsg = array( 'hookaborted' ); + $errorMsg = [ 'hookaborted' ]; } } if ( $errorMsg != '' ) { @@ -346,19 +349,21 @@ class ProtectionForm { $user = $context->getUser(); $output = $context->getOutput(); $lang = $context->getLanguage(); - $cascadingRestrictionLevels = $context->getConfig()->get( 'CascadingRestrictionLevels' ); + $conf = $context->getConfig(); + $cascadingRestrictionLevels = $conf->get( 'CascadingRestrictionLevels' ); + $oldCommentSchema = $conf->get( 'CommentTableSchemaMigrationStage' ) === MIGRATION_OLD; $out = ''; if ( !$this->disabled ) { $output->addModules( 'mediawiki.legacy.protect' ); $output->addJsConfigVars( 'wgCascadeableLevels', $cascadingRestrictionLevels ); - $out .= Xml::openElement( 'form', array( 'method' => 'post', + $out .= Xml::openElement( 'form', [ 'method' => 'post', 'action' => $this->mTitle->getLocalURL( 'action=protect' ), - 'id' => 'mw-Protect-Form' ) ); + 'id' => 'mw-Protect-Form' ] ); } $out .= Xml::openElement( 'fieldset' ) . Xml::element( 'legend', null, $context->msg( 'protect-legend' )->text() ) . - Xml::openElement( 'table', array( 'id' => 'mwProtectSet' ) ) . + Xml::openElement( 'table', [ 'id' => 'mwProtectSet' ] ) . Xml::openElement( 'tbody' ); $scExpiryOptions = wfMessage( 'protect-expiry-options' )->inContentLanguage()->text(); @@ -372,7 +377,7 @@ class ProtectionForm { $out .= "" . Xml::openElement( 'fieldset' ) . Xml::element( 'legend', null, $msg->exists() ? $msg->text() : $action ) . - Xml::openElement( 'table', array( 'id' => "mw-protect-table-$action" ) ) . + Xml::openElement( 'table', [ 'id' => "mw-protect-table-$action" ] ) . "" . $this->buildSelector( $action, $selected ) . ""; $mProtectexpiry = Xml::label( @@ -384,7 +389,16 @@ class ProtectionForm { "mwProtect-$action-expires" ); - $expiryFormOptions = ''; + $expiryFormOptions = new XmlSelect( + "wpProtectExpirySelection-$action", + "mwProtectExpirySelection-$action", + $this->mExpirySelection[$action] + ); + $expiryFormOptions->setAttribute( 'tabindex', '2' ); + if ( $this->disabled ) { + $expiryFormOptions->setAttribute( 'disabled', 'disabled' ); + } + if ( $this->mExistingExpiry[$action] ) { if ( $this->mExistingExpiry[$action] == 'infinity' ) { $existingExpiryMessage = $context->msg( 'protect-existing-expiry-infinity' ); @@ -392,31 +406,27 @@ class ProtectionForm { $timestamp = $lang->userTimeAndDate( $this->mExistingExpiry[$action], $user ); $d = $lang->userDate( $this->mExistingExpiry[$action], $user ); $t = $lang->userTime( $this->mExistingExpiry[$action], $user ); - $existingExpiryMessage = $context->msg( 'protect-existing-expiry', $timestamp, $d, $t ); + $existingExpiryMessage = $context->msg( + 'protect-existing-expiry', + $timestamp, + $d, + $t + ); } - $expiryFormOptions .= - Xml::option( - $existingExpiryMessage->text(), - 'existing', - $this->mExpirySelection[$action] == 'existing' - ) . "\n"; + $expiryFormOptions->addOption( $existingExpiryMessage->text(), 'existing' ); } - $expiryFormOptions .= Xml::option( + $expiryFormOptions->addOption( $context->msg( 'protect-othertime-op' )->text(), - "othertime" - ) . "\n"; + 'othertime' + ); foreach ( explode( ',', $scExpiryOptions ) as $option ) { if ( strpos( $option, ":" ) === false ) { $show = $value = $option; } else { list( $show, $value ) = explode( ":", $option ); } - $expiryFormOptions .= Xml::option( - $show, - htmlspecialchars( $value ), - $this->mExpirySelection[$action] === $value - ) . "\n"; + $expiryFormOptions->addOption( $show, htmlspecialchars( $value ) ); } # Add expiry dropdown if ( $showProtectOptions && !$this->disabled ) { @@ -426,17 +436,12 @@ class ProtectionForm { {$mProtectexpiry} " . - Xml::tags( 'select', - array( - 'id' => "mwProtectExpirySelection-$action", - 'name' => "wpProtectExpirySelection-$action", - 'tabindex' => '2' ) + $this->disabledAttrib, - $expiryFormOptions ) . + $expiryFormOptions->getHTML() . " "; } # Add custom expiry field - $attribs = array( 'id' => "mwProtect-$action-expires" ) + $this->disabledAttrib; + $attribs = [ 'id' => "mwProtect-$action-expires" ] + $this->disabledAttrib; $out .= ""; } # Give extensions a chance to add items to the form - Hooks::run( 'ProtectionForm::buildForm', array( $this->mArticle, &$out ) ); + Hooks::run( 'ProtectionForm::buildForm', [ $this->mArticle, &$out ] ); $out .= Xml::closeElement( 'tbody' ) . Xml::closeElement( 'table' ); // JavaScript will add another row with a value-chaining checkbox if ( $this->mTitle->exists() ) { - $out .= Xml::openElement( 'table', array( 'id' => 'mw-protect-table2' ) ) . + $out .= Xml::openElement( 'table', [ 'id' => 'mw-protect-table2' ] ) . Xml::openElement( 'tbody' ); $out .= ' @@ -491,7 +496,14 @@ class ProtectionForm { $this->mReasonSelection, 'mwProtect-reason', 4 ); - $out .= Xml::openElement( 'table', array( 'id' => 'mw-protect-table3' ) ) . + // HTML maxlength uses "UTF-16 code units", which means that characters outside BMP + // (e.g. emojis) count for two each. This limit is overridden in JS to instead count + // Unicode codepoints (or 180 UTF-8 bytes for old schema). + // Subtract arbitrary 75 to leave some space for the autogenerated null edit's summary + // and other texts chosen by dropdown menus on this page. + $maxlength = $oldCommentSchema ? 180 : CommentStore::COMMENT_CHARACTER_LIMIT - 75; + + $out .= Xml::openElement( 'table', [ 'id' => 'mw-protect-table3' ] ) . Xml::openElement( 'tbody' ); $out .= " @@ -507,11 +519,8 @@ class ProtectionForm { {$mProtectreason} "; # Disallow watching is user is not logged in @@ -532,7 +541,7 @@ class ProtectionForm { \n"; @@ -541,11 +550,12 @@ class ProtectionForm { $out .= Xml::closeElement( 'fieldset' ); if ( $user->isAllowed( 'editinterface' ) ) { - $link = Linker::linkKnown( + $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer(); + $link = $linkRenderer->makeKnownLink( $context->msg( 'protect-dropdown' )->inContentLanguage()->getTitle(), - $context->msg( 'protect-edit-reasonlist' )->escaped(), - array(), - array( 'action' => 'edit' ) + $context->msg( 'protect-edit-reasonlist' )->text(), + [], + [ 'action' => 'edit' ] ); $out .= '

' . $link . '

'; } @@ -553,7 +563,7 @@ class ProtectionForm { if ( !$this->disabled ) { $out .= Html::hidden( 'wpEditToken', - $user->getEditToken( array( 'protect', $this->mTitle->getPrefixedDBkey() ) ) + $user->getEditToken( [ 'protect', $this->mTitle->getPrefixedDBkey() ] ) ); $out .= Xml::closeElement( 'form' ); } @@ -576,18 +586,18 @@ class ProtectionForm { ); $id = 'mwProtect-level-' . $action; - $attribs = array( - 'id' => $id, - 'name' => $id, - 'size' => count( $levels ), - ) + $this->disabledAttrib; - $out = Xml::openElement( 'select', $attribs ); + $select = new XmlSelect( $id, $id, $selected ); + $select->setAttribute( 'size', count( $levels ) ); + if ( $this->disabled ) { + $select->setAttribute( 'disabled', 'disabled' ); + } + foreach ( $levels as $key ) { - $out .= Xml::option( $this->getOptionLabel( $key ), $key, $key == $selected ); + $select->addOption( $this->getOptionLabel( $key ), $key ); } - $out .= Xml::closeElement( 'select' ); - return $out; + + return $select->getHTML(); } /** @@ -612,7 +622,7 @@ class ProtectionForm { /** * Show protection long extracts for this page * - * @param OutputPage $out + * @param OutputPage &$out * @access private */ function showLogExtract( &$out ) { @@ -621,6 +631,6 @@ class ProtectionForm { $out->addHTML( Xml::element( 'h2', null, $protectLogPage->getName()->text() ) ); LogEventsList::showLogExtract( $out, 'protect', $this->mTitle ); # Let extensions add other relevant log extracts - Hooks::run( 'ProtectionForm::showLogExtract', array( $this->mArticle, $out ) ); + Hooks::run( 'ProtectionForm::showLogExtract', [ $this->mArticle, $out ] ); } }
" . $mProtectother . @@ -451,13 +456,13 @@ class ProtectionForm { "
" . - Xml::input( 'mwProtect-reason', 60, $this->mReason, array( 'type' => 'text', - 'id' => 'mwProtect-reason', 'maxlength' => 180 ) ) . - // Limited maxlength as the database trims at 255 bytes and other texts - // chosen by dropdown menus on this page are also included in this database field. - // The byte limit of 180 bytes is enforced in javascript + Xml::input( 'mwProtect-reason', 60, $this->mReason, [ 'type' => 'text', + 'id' => 'mwProtect-reason', 'maxlength' => $maxlength ] ) . "
" . Xml::submitButton( $context->msg( 'confirm' )->text(), - array( 'id' => 'mw-Protect-submit' ) + [ 'id' => 'mw-Protect-submit' ] ) . "