From: This, that and the other Date: Thu, 12 Jan 2017 07:14:55 +0000 (+1100) Subject: Add parameter to API modules to apply change tags to log entries X-Git-Tag: 1.31.0-rc.0~4325^2 X-Git-Url: http://git.cyclocoop.org/%24action?a=commitdiff_plain;h=f3f2df07ec1da00d78cb88250abb50d28dc17459;p=lhc%2Fweb%2Fwiklou.git Add parameter to API modules to apply change tags to log entries Adds support for tagging log entries for the block, import, managetags, and move API modules, using a 'tags' parameter. Bug: T97720 Change-Id: I9d75d2cece317a7704c4bc6d734ad3cafe24544e --- diff --git a/includes/MovePage.php b/includes/MovePage.php index cbb4651240..ae12ba5e7d 100644 --- a/includes/MovePage.php +++ b/includes/MovePage.php @@ -233,9 +233,11 @@ class MovePage { * @param User $user * @param string $reason * @param bool $createRedirect + * @param string[] $changeTags Change tags to apply to the entry in the move log. Caller + * should perform permission checks with ChangeTags::canAddTagsAccompanyingChange * @return Status */ - public function move( User $user, $reason, $createRedirect ) { + public function move( User $user, $reason, $createRedirect, array $changeTags = [] ) { global $wgCategoryCollation; Hooks::run( 'TitleMove', [ $this->oldTitle, $this->newTitle, $user ] ); @@ -265,7 +267,8 @@ class MovePage { $protected = $this->oldTitle->isProtected(); // Do the actual move; if this fails, it will throw an MWException(!) - $nullRevision = $this->moveToInternal( $user, $this->newTitle, $reason, $createRedirect ); + $nullRevision = $this->moveToInternal( $user, $this->newTitle, $reason, $createRedirect, + $changeTags ); // Refresh the sortkey for this row. Be careful to avoid resetting // cl_timestamp, which may disturb time-based lists on some sites. @@ -356,6 +359,7 @@ class MovePage { '4::oldtitle' => $this->oldTitle->getPrefixedText(), ] ); $logEntry->setRelations( [ 'pr_id' => $logRelationsValues ] ); + $logEntry->setTags( $changeTags ); $logId = $logEntry->insert(); $logEntry->publish( $logId ); } @@ -424,18 +428,21 @@ class MovePage { * Move page to a title which is either a redirect to the * source page or nonexistent * - * @fixme This was basically directly moved from Title, it should be split into smaller functions + * @todo This was basically directly moved from Title, it should be split into + * smaller functions * @param User $user the User doing the move * @param Title $nt The page to move to, which should be a redirect or non-existent * @param string $reason The reason for the move * @param bool $createRedirect Whether to leave a redirect at the old title. Does not check * if the user has the suppressredirect right + * @param string[] $changeTags Change tags to apply to the entry in the move log * @return Revision the revision created by the move * @throws MWException */ - private function moveToInternal( User $user, &$nt, $reason = '', $createRedirect = true ) { - global $wgContLang; + private function moveToInternal( User $user, &$nt, $reason = '', $createRedirect = true, + array $changeTags = [] ) { + global $wgContLang; if ( $nt->exists() ) { $moveOverRedirect = true; $logType = 'move_redir'; @@ -458,7 +465,7 @@ class MovePage { /* $commit */ false, $errs, $user, - [], + $changeTags, 'delete_redir' ); @@ -529,7 +536,8 @@ class MovePage { throw new MWException( 'No valid null revision produced in ' . __METHOD__ ); } - $nullRevision->insertOn( $dbw ); + $nullRevId = $nullRevision->insertOn( $dbw ); + $logEntry->setAssociatedRevId( $nullRevId ); # Change the name of the target page: $dbw->update( 'page', @@ -584,18 +592,22 @@ class MovePage { 'user' => $user->getId(), 'comment' => $comment, 'content' => $redirectContent ] ); - $redirectRevision->insertOn( $dbw ); + $redirectRevId = $redirectRevision->insertOn( $dbw ); $redirectArticle->updateRevisionOn( $dbw, $redirectRevision, 0 ); Hooks::run( 'NewRevisionFromEditComplete', [ $redirectArticle, $redirectRevision, false, $user ] ); $redirectArticle->doEditUpdates( $redirectRevision, $user, [ 'created' => true ] ); + + ChangeTags::addTags( $changeTags, null, $redirectRevId, null ); } } # Log the move $logid = $logEntry->insert(); + + $logEntry->setTags( $changeTags ); $logEntry->publish( $logid ); return $nullRevision; diff --git a/includes/Title.php b/includes/Title.php index c4584bd38f..a67bf86e7c 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -3670,9 +3670,12 @@ class Title implements LinkTarget { * @param string $reason The reason for the move * @param bool $createRedirect Whether to create a redirect from the old title to the new title. * Ignored if the user doesn't have the suppressredirect right. + * @param array $changeTags Applied to the entry in the move log and redirect page revision * @return array|bool True on success, getUserPermissionsErrors()-like array on failure */ - public function moveTo( &$nt, $auth = true, $reason = '', $createRedirect = true ) { + public function moveTo( &$nt, $auth = true, $reason = '', $createRedirect = true, + array $changeTags = [] ) { + global $wgUser; $err = $this->isValidMoveOperation( $nt, $auth, $reason ); if ( is_array( $err ) ) { @@ -3686,7 +3689,7 @@ class Title implements LinkTarget { } $mp = new MovePage( $this, $nt ); - $status = $mp->move( $wgUser, $reason, $createRedirect ); + $status = $mp->move( $wgUser, $reason, $createRedirect, $changeTags ); if ( $status->isOK() ) { return true; } else { @@ -3702,12 +3705,15 @@ class Title implements LinkTarget { * @param string $reason The reason for the move * @param bool $createRedirect Whether to create redirects from the old subpages to * the new ones Ignored if the user doesn't have the 'suppressredirect' right + * @param array $changeTags Applied to the entry in the move log and redirect page revision * @return array Array with old page titles as keys, and strings (new page titles) or * getUserPermissionsErrors()-like arrays (errors) as values, or a * getUserPermissionsErrors()-like error array with numeric indices if * no pages were moved */ - public function moveSubpages( $nt, $auth = true, $reason = '', $createRedirect = true ) { + public function moveSubpages( $nt, $auth = true, $reason = '', $createRedirect = true, + array $changeTags = [] ) { + global $wgMaximumMovedPages; // Check permissions if ( !$this->userCan( 'move-subpages' ) ) { @@ -3762,7 +3768,7 @@ class Title implements LinkTarget { # be longer than 255 characters. $newSubpage = Title::makeTitleSafe( $newNs, $newPageName ); - $success = $oldSubpage->moveTo( $newSubpage, $auth, $reason, $createRedirect ); + $success = $oldSubpage->moveTo( $newSubpage, $auth, $reason, $createRedirect, $changeTags ); if ( $success === true ) { $retval[$oldSubpage->getPrefixedText()] = $newSubpage->getPrefixedText(); } else { diff --git a/includes/api/ApiBlock.php b/includes/api/ApiBlock.php index 3774f099a7..e2b27cbf5c 100644 --- a/includes/api/ApiBlock.php +++ b/includes/api/ApiBlock.php @@ -80,6 +80,13 @@ class ApiBlock extends ApiBase { } } + if ( $params['tags'] ) { + $ableToTag = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $user ); + if ( !$ableToTag->isOK() ) { + $this->dieStatus( $ableToTag ); + } + } + if ( $params['hidename'] && !$user->isAllowed( 'hideuser' ) ) { $this->dieWithError( 'apierror-canthide' ); } @@ -105,6 +112,7 @@ class ApiBlock extends ApiBase { 'Reblock' => $params['reblock'], 'Watch' => $params['watchuser'], 'Confirm' => true, + 'Tags' => $params['tags'], ]; $retval = SpecialBlock::processForm( $data, $this->getContext() ); @@ -164,6 +172,10 @@ class ApiBlock extends ApiBase { 'allowusertalk' => false, 'reblock' => false, 'watchuser' => false, + 'tags' => [ + ApiBase::PARAM_TYPE => 'tags', + ApiBase::PARAM_ISMULTI => true, + ], ]; } diff --git a/includes/api/ApiImport.php b/includes/api/ApiImport.php index dffd6b253f..bf5e4ce3b2 100644 --- a/includes/api/ApiImport.php +++ b/includes/api/ApiImport.php @@ -64,6 +64,14 @@ class ApiImport extends ApiBase { $this->dieStatus( $source ); } + // Check if user can add the log entry tags which were requested + if ( $params['tags'] ) { + $ableToTag = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $user ); + if ( !$ableToTag->isOK() ) { + $this->dieStatus( $ableToTag ); + } + } + $importer = new WikiImporter( $source->value, $this->getConfig() ); if ( isset( $params['namespace'] ) ) { $importer->setTargetNamespace( $params['namespace'] ); @@ -79,6 +87,9 @@ class ApiImport extends ApiBase { $params['interwikisource'], $params['summary'] ); + if ( $params['tags'] ) { + $reporter->setChangeTags( $params['tags'] ); + } try { $importer->doImport(); @@ -140,6 +151,10 @@ class ApiImport extends ApiBase { ApiBase::PARAM_TYPE => 'namespace' ], 'rootpage' => null, + 'tags' => [ + ApiBase::PARAM_TYPE => 'tags', + ApiBase::PARAM_ISMULTI => true, + ], ]; } diff --git a/includes/api/ApiManageTags.php b/includes/api/ApiManageTags.php index 3299f73b5b..3c080939c0 100644 --- a/includes/api/ApiManageTags.php +++ b/includes/api/ApiManageTags.php @@ -27,6 +27,7 @@ class ApiManageTags extends ApiBase { public function execute() { $params = $this->extractRequestParams(); + $user = $this->getUser(); // make sure the user is allowed if ( $params['operation'] !== 'delete' @@ -37,10 +38,23 @@ class ApiManageTags extends ApiBase { $this->dieWithError( 'tags-delete-no-permission', 'permissiondenied' ); } + // Check if user can add the log entry tags which were requested + if ( $params['tags'] ) { + $ableToTag = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $user ); + if ( !$ableToTag->isOK() ) { + $this->dieStatus( $ableToTag ); + } + } + $result = $this->getResult(); $funcName = "{$params['operation']}TagWithChecks"; - $status = ChangeTags::$funcName( $params['tag'], $params['reason'], - $this->getUser(), $params['ignorewarnings'] ); + $status = ChangeTags::$funcName( + $params['tag'], + $params['reason'], + $user, + $params['ignorewarnings'], + $params['tags'] ?: [] + ); if ( !$status->isOK() ) { $this->dieStatus( $status ); @@ -57,6 +71,7 @@ class ApiManageTags extends ApiBase { if ( $ret['success'] ) { $ret['logid'] = $status->value; } + $result->addValue( null, $this->getModuleName(), $ret ); } @@ -85,6 +100,10 @@ class ApiManageTags extends ApiBase { ApiBase::PARAM_TYPE => 'boolean', ApiBase::PARAM_DFLT => false, ], + 'tags' => [ + ApiBase::PARAM_TYPE => 'tags', + ApiBase::PARAM_ISMULTI => true, + ], ]; } diff --git a/includes/api/ApiMove.php b/includes/api/ApiMove.php index 18e582d637..ab7199f6a5 100644 --- a/includes/api/ApiMove.php +++ b/includes/api/ApiMove.php @@ -77,9 +77,18 @@ class ApiMove extends ApiBase { $this->dieWithError( 'apierror-ratelimited' ); } + // Check if the user is allowed to add the specified changetags + if ( $params['tags'] ) { + $ableToTag = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $user ); + if ( !$ableToTag->isOK() ) { + $this->dieStatus( $ableToTag ); + } + } + // Move the page $toTitleExists = $toTitle->exists(); - $status = $this->movePage( $fromTitle, $toTitle, $params['reason'], !$params['noredirect'] ); + $status = $this->movePage( $fromTitle, $toTitle, $params['reason'], !$params['noredirect'], + $params['tags'] ?: [] ); if ( !$status->isOK() ) { $this->dieStatus( $status ); } @@ -102,7 +111,13 @@ class ApiMove extends ApiBase { // Move the talk page if ( $params['movetalk'] && $toTalk && $fromTalk->exists() && !$fromTitle->isTalkPage() ) { $toTalkExists = $toTalk->exists(); - $status = $this->movePage( $fromTalk, $toTalk, $params['reason'], !$params['noredirect'] ); + $status = $this->movePage( + $fromTalk, + $toTalk, + $params['reason'], + !$params['noredirect'], + $params['tags'] ?: [] + ); if ( $status->isOK() ) { $r['talkfrom'] = $fromTalk->getPrefixedText(); $r['talkto'] = $toTalk->getPrefixedText(); @@ -117,13 +132,23 @@ class ApiMove extends ApiBase { // Move subpages if ( $params['movesubpages'] ) { - $r['subpages'] = $this->moveSubpages( $fromTitle, $toTitle, - $params['reason'], $params['noredirect'] ); + $r['subpages'] = $this->moveSubpages( + $fromTitle, + $toTitle, + $params['reason'], + $params['noredirect'], + $params['tags'] ?: [] + ); ApiResult::setIndexedTagName( $r['subpages'], 'subpage' ); if ( $params['movetalk'] ) { - $r['subpages-talk'] = $this->moveSubpages( $fromTalk, $toTalk, - $params['reason'], $params['noredirect'] ); + $r['subpages-talk'] = $this->moveSubpages( + $fromTalk, + $toTalk, + $params['reason'], + $params['noredirect'], + $params['tags'] ?: [] + ); ApiResult::setIndexedTagName( $r['subpages-talk'], 'subpage' ); } } @@ -149,26 +174,28 @@ class ApiMove extends ApiBase { * @param Title $to * @param string $reason * @param bool $createRedirect + * @param array $changeTags Applied to the entry in the move log and redirect page revision * @return Status */ - protected function movePage( Title $from, Title $to, $reason, $createRedirect ) { + protected function movePage( Title $from, Title $to, $reason, $createRedirect, $changeTags ) { $mp = new MovePage( $from, $to ); $valid = $mp->isValidMove(); if ( !$valid->isOK() ) { return $valid; } - $permStatus = $mp->checkPermissions( $this->getUser(), $reason ); + $user = $this->getUser(); + $permStatus = $mp->checkPermissions( $user, $reason ); if ( !$permStatus->isOK() ) { return $permStatus; } // Check suppressredirect permission - if ( !$this->getUser()->isAllowed( 'suppressredirect' ) ) { + if ( !$user->isAllowed( 'suppressredirect' ) ) { $createRedirect = true; } - return $mp->move( $this->getUser(), $reason, $createRedirect ); + return $mp->move( $user, $reason, $createRedirect, $changeTags ); } /** @@ -176,11 +203,13 @@ class ApiMove extends ApiBase { * @param Title $toTitle * @param string $reason * @param bool $noredirect + * @param array $changeTags Applied to the entry in the move log and redirect page revisions * @return array */ - public function moveSubpages( $fromTitle, $toTitle, $reason, $noredirect ) { + public function moveSubpages( $fromTitle, $toTitle, $reason, $noredirect, $changeTags = [] ) { $retval = []; - $success = $fromTitle->moveSubpages( $toTitle, true, $reason, !$noredirect ); + + $success = $fromTitle->moveSubpages( $toTitle, true, $reason, !$noredirect, $changeTags ); if ( isset( $success[0] ) ) { $status = $this->errorArrayToStatus( $success ); return [ 'errors' => $this->getErrorFormatter()->arrayFromStatus( $status ) ]; @@ -242,7 +271,11 @@ class ApiMove extends ApiBase { 'nochange' ], ], - 'ignorewarnings' => false + 'ignorewarnings' => false, + 'tags' => [ + ApiBase::PARAM_TYPE => 'tags', + ApiBase::PARAM_ISMULTI => true, + ], ]; } diff --git a/includes/api/i18n/en.json b/includes/api/i18n/en.json index f6eeffe880..cecf810747 100644 --- a/includes/api/i18n/en.json +++ b/includes/api/i18n/en.json @@ -37,6 +37,7 @@ "apihelp-block-param-allowusertalk": "Allow the user to edit their own talk page (depends on [[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]).", "apihelp-block-param-reblock": "If the user is already blocked, overwrite the existing block.", "apihelp-block-param-watchuser": "Watch the user's or IP address's user and talk pages.", + "apihelp-block-param-tags": "Change tags to apply to the entry in the block log.", "apihelp-block-example-ip-simple": "Block IP address 192.0.2.5 for three days with reason First strike.", "apihelp-block-example-user-complex": "Block user Vandal indefinitely with reason Vandalism, and prevent new account creation and email sending.", @@ -230,6 +231,7 @@ "apihelp-import-param-templates": "For interwiki imports: import all included templates as well.", "apihelp-import-param-namespace": "Import to this namespace. Cannot be used together with $1rootpage.", "apihelp-import-param-rootpage": "Import as subpage of this page. Cannot be used together with $1namespace.", + "apihelp-import-param-tags": "Change tags to apply to the entry in the import log and to the null revision on the imported pages.", "apihelp-import-example-import": "Import [[meta:Help:ParserFunctions]] to namespace 100 with full history.", "apihelp-linkaccount-description": "Link an account from a third-party provider to the current user.", @@ -252,6 +254,7 @@ "apihelp-managetags-param-tag": "Tag to create, delete, activate or deactivate. For tag creation, the tag must not exist. For tag deletion, the tag must exist. For tag activation, the tag must exist and not be in use by an extension. For tag deactivation, the tag must be currently active and manually defined.", "apihelp-managetags-param-reason": "An optional reason for creating, deleting, activating or deactivating the tag.", "apihelp-managetags-param-ignorewarnings": "Whether to ignore any warnings that are issued during the operation.", + "apihelp-managetags-param-tags": "Change tags to apply to the entry in the tag management log.", "apihelp-managetags-example-create": "Create a tag named spam with the reason For use in edit patrolling", "apihelp-managetags-example-delete": "Delete the vandlaism tag with the reason Misspelt", "apihelp-managetags-example-activate": "Activate a tag named spam with the reason For use in edit patrolling", @@ -279,6 +282,7 @@ "apihelp-move-param-unwatch": "Remove the page and the redirect from the current user's watchlist.", "apihelp-move-param-watchlist": "Unconditionally add or remove the page from the current user's watchlist, use preferences or do not change watch.", "apihelp-move-param-ignorewarnings": "Ignore any warnings.", + "apihelp-move-param-tags": "Change tags to apply to the entry in the move log and to the null revision on the destination page.", "apihelp-move-example-move": "Move Badtitle to Goodtitle without leaving a redirect.", "apihelp-opensearch-description": "Search the wiki using the OpenSearch protocol.", diff --git a/includes/api/i18n/qqq.json b/includes/api/i18n/qqq.json index 2c6637c4d2..ea925e4a1c 100644 --- a/includes/api/i18n/qqq.json +++ b/includes/api/i18n/qqq.json @@ -46,6 +46,7 @@ "apihelp-block-param-allowusertalk": "{{doc-apihelp-param|block|allowusertalk}}\n* See also {{msg-mw|ipb-disableusertalk}}", "apihelp-block-param-reblock": "{{doc-apihelp-param|block|reblock}}", "apihelp-block-param-watchuser": "{{doc-apihelp-param|block|watchuser}}", + "apihelp-block-param-tags": "{{doc-apihelp-param|block|tags}}", "apihelp-block-example-ip-simple": "{{doc-apihelp-example|block}}", "apihelp-block-example-user-complex": "{{doc-apihelp-example|block}}", "apihelp-changeauthenticationdata-description": "{{doc-apihelp-description|changeauthenticationdata}}", @@ -222,6 +223,7 @@ "apihelp-import-param-templates": "{{doc-apihelp-param|import|templates}}", "apihelp-import-param-namespace": "{{doc-apihelp-param|import|namespace}}", "apihelp-import-param-rootpage": "{{doc-apihelp-param|import|rootpage}}", + "apihelp-import-param-tags": "{{doc-apihelp-param|import|tags}}", "apihelp-import-example-import": "{{doc-apihelp-example|import}}", "apihelp-linkaccount-description": "{{doc-apihelp-description|linkaccount}}", "apihelp-linkaccount-example-link": "{{doc-apihelp-example|linkaccount}}", @@ -240,6 +242,7 @@ "apihelp-managetags-param-tag": "{{doc-apihelp-param|managetags|tag}}", "apihelp-managetags-param-reason": "{{doc-apihelp-param|managetags|reason}}", "apihelp-managetags-param-ignorewarnings": "{{doc-apihelp-param|managetags|ignorewarnings}}", + "apihelp-managetags-param-tags": "{{doc-apihelp-param|managetags|tags}}", "apihelp-managetags-example-create": "{{doc-apihelp-example|managetags}}", "apihelp-managetags-example-delete": "{{doc-apihelp-example|managetags|info={{doc-important|The text \"vandlaism\" in this message is intentionally misspelled; the example being documented by this message is the deletion of a misspelled tag.}}}}", "apihelp-managetags-example-activate": "{{doc-apihelp-example|managetags}}", @@ -265,6 +268,7 @@ "apihelp-move-param-unwatch": "{{doc-apihelp-param|move|unwatch}}", "apihelp-move-param-watchlist": "{{doc-apihelp-param|move|watchlist}}", "apihelp-move-param-ignorewarnings": "{{doc-apihelp-param|move|ignorewarnings}}", + "apihelp-move-param-tags": "{{doc-apihelp-param|move|tags}}", "apihelp-move-example-move": "{{doc-apihelp-example|move}}", "apihelp-opensearch-description": "{{doc-apihelp-description|opensearch}}", "apihelp-opensearch-param-search": "{{doc-apihelp-param|opensearch|search}}", diff --git a/includes/changetags/ChangeTags.php b/includes/changetags/ChangeTags.php index bfabd51bcc..d2239eb0be 100644 --- a/includes/changetags/ChangeTags.php +++ b/includes/changetags/ChangeTags.php @@ -757,11 +757,13 @@ class ChangeTags { * @param User $user Who to attribute the action to * @param int $tagCount For deletion only, how many usages the tag had before * it was deleted. + * @param array $logEntryTags Change tags to apply to the entry + * that will be created in the tag management log * @return int ID of the inserted log entry * @since 1.25 */ protected static function logTagManagementAction( $action, $tag, $reason, - User $user, $tagCount = null ) { + User $user, $tagCount = null, array $logEntryTags = [] ) { $dbw = wfGetDB( DB_MASTER ); @@ -778,6 +780,7 @@ class ChangeTags { } $logEntry->setParameters( $params ); $logEntry->setRelations( [ 'Tag' => $tag ] ); + $logEntry->setTags( $logEntryTags ); $logId = $logEntry->insert( $dbw ); $logEntry->publish( $logId ); @@ -830,12 +833,14 @@ class ChangeTags { * @param string $reason * @param User $user Who to give credit for the action * @param bool $ignoreWarnings Can be used for API interaction, default false + * @param array $logEntryTags Change tags to apply to the entry + * that will be created in the tag management log * @return Status If successful, the Status contains the ID of the added log * entry as its value * @since 1.25 */ public static function activateTagWithChecks( $tag, $reason, User $user, - $ignoreWarnings = false ) { + $ignoreWarnings = false, array $logEntryTags = [] ) { // are we allowed to do this? $result = self::canActivateTag( $tag, $user ); @@ -848,7 +853,9 @@ class ChangeTags { self::defineTag( $tag ); // log it - $logId = self::logTagManagementAction( 'activate', $tag, $reason, $user ); + $logId = self::logTagManagementAction( 'activate', $tag, $reason, $user, + null, $logEntryTags ); + return Status::newGood( $logId ); } @@ -889,12 +896,14 @@ class ChangeTags { * @param string $reason * @param User $user Who to give credit for the action * @param bool $ignoreWarnings Can be used for API interaction, default false + * @param array $logEntryTags Change tags to apply to the entry + * that will be created in the tag management log * @return Status If successful, the Status contains the ID of the added log * entry as its value * @since 1.25 */ public static function deactivateTagWithChecks( $tag, $reason, User $user, - $ignoreWarnings = false ) { + $ignoreWarnings = false, array $logEntryTags = [] ) { // are we allowed to do this? $result = self::canDeactivateTag( $tag, $user ); @@ -907,7 +916,9 @@ class ChangeTags { self::undefineTag( $tag ); // log it - $logId = self::logTagManagementAction( 'deactivate', $tag, $reason, $user ); + $logId = self::logTagManagementAction( 'deactivate', $tag, $reason, $user, + null, $logEntryTags ); + return Status::newGood( $logId ); } @@ -968,12 +979,14 @@ class ChangeTags { * @param string $reason * @param User $user Who to give credit for the action * @param bool $ignoreWarnings Can be used for API interaction, default false + * @param array $logEntryTags Change tags to apply to the entry + * that will be created in the tag management log * @return Status If successful, the Status contains the ID of the added log * entry as its value * @since 1.25 */ public static function createTagWithChecks( $tag, $reason, User $user, - $ignoreWarnings = false ) { + $ignoreWarnings = false, array $logEntryTags = [] ) { // are we allowed to do this? $result = self::canCreateTag( $tag, $user ); @@ -986,7 +999,9 @@ class ChangeTags { self::defineTag( $tag ); // log it - $logId = self::logTagManagementAction( 'create', $tag, $reason, $user ); + $logId = self::logTagManagementAction( 'create', $tag, $reason, $user, + null, $logEntryTags ); + return Status::newGood( $logId ); } @@ -1095,12 +1110,14 @@ class ChangeTags { * @param string $reason * @param User $user Who to give credit for the action * @param bool $ignoreWarnings Can be used for API interaction, default false + * @param array $logEntryTags Change tags to apply to the entry + * that will be created in the tag management log * @return Status If successful, the Status contains the ID of the added log * entry as its value * @since 1.25 */ public static function deleteTagWithChecks( $tag, $reason, User $user, - $ignoreWarnings = false ) { + $ignoreWarnings = false, array $logEntryTags = [] ) { // are we allowed to do this? $result = self::canDeleteTag( $tag, $user ); @@ -1120,7 +1137,9 @@ class ChangeTags { } // log it - $logId = self::logTagManagementAction( 'delete', $tag, $reason, $user, $hitcount ); + $logId = self::logTagManagementAction( 'delete', $tag, $reason, $user, + $hitcount, $logEntryTags ); + $deleteResult->value = $logId; return $deleteResult; } diff --git a/includes/specials/SpecialBlock.php b/includes/specials/SpecialBlock.php index 585f70b86b..93cb3773bd 100644 --- a/includes/specials/SpecialBlock.php +++ b/includes/specials/SpecialBlock.php @@ -828,9 +828,13 @@ class SpecialBlock extends FormSpecialPage { $blockIds = array_merge( [ $status['id'] ], $status['autoIds'] ); $logEntry->setRelations( [ 'ipb_id' => $blockIds ] ); $logId = $logEntry->insert(); + + if ( count( $data['Tags'] ) ) { + $logEntry->setTags( $data['Tags'] ); + } + $logEntry->publish( $logId ); - # Report to the user return true; } diff --git a/includes/specials/SpecialImport.php b/includes/specials/SpecialImport.php index ce886247a9..a2930fcebe 100644 --- a/includes/specials/SpecialImport.php +++ b/includes/specials/SpecialImport.php @@ -536,6 +536,7 @@ class SpecialImport extends SpecialPage { */ class ImportReporter extends ContextSource { private $reason = false; + private $logTags = []; private $mOriginalLogCallback = null; private $mOriginalPageOutCallback = null; private $mLogItemCount = 0; @@ -558,6 +559,16 @@ class ImportReporter extends ContextSource { $this->reason = $reason; } + /** + * Sets change tags to apply to the import log entry and null revision. + * + * @param array $tags + * @since 1.29 + */ + public function setChangeTags( array $tags ) { + $this->logTags = $tags; + } + function open() { $this->getOutput()->addHTML( "