115 $status = Status::newGood();
117 $bitPars = $params[
'value'];
118 $comment = $params[
'comment'];
119 $perItemStatus = $params[
'perItemStatus'] ??
false;
124 $this->res = $this->
doQuery( $dbw );
127 if ( !$status->isGood() ) {
131 $dbw->startAtomic( __METHOD__ );
132 $dbw->onTransactionResolution(
140 $missing = array_flip( $this->ids );
145 if ( $perItemStatus ) {
146 $status->itemStatuses = [];
158 $visibilityChangeMap = [];
161 foreach ( $this as $item ) {
162 unset( $missing[$item->getId()] );
164 if ( $perItemStatus ) {
165 $itemStatus = Status::newGood();
166 $status->itemStatuses[$item->getId()] = $itemStatus;
168 $itemStatus = $status;
171 $oldBits = $item->getBits();
175 if ( $oldBits == $newBits ) {
176 $itemStatus->warning(
177 'revdelete-no-change', $item->formatDate(), $item->formatTime() );
178 $status->failCount++;
180 } elseif ( $oldBits == 0 && $newBits != 0 ) {
182 } elseif ( $oldBits != 0 && $newBits == 0 ) {
188 if ( $item->isHideCurrentOp( $newBits ) ) {
191 'revdelete-hide-current', $item->formatDate(), $item->formatTime() );
192 $status->failCount++;
194 } elseif ( !$item->canView() ) {
196 $msg = ( $opType ==
'show' ) ?
197 'revdelete-show-no-access' :
'revdelete-modify-no-access';
198 $itemStatus->error( $msg, $item->formatDate(), $item->formatTime() );
199 $status->failCount++;
202 } elseif ( $newBits == RevisionRecord::DELETED_RESTRICTED ) {
203 $itemStatus->warning(
204 'revdelete-only-restricted', $item->formatDate(), $item->formatTime() );
205 $status->failCount++;
210 $ok = $item->setBits( $newBits );
213 $idsForLog[] = $item->getId();
216 $logType =
'suppress';
219 $addedBits = ( $oldBits ^ $newBits ) & $newBits;
220 $removedBits = ( $oldBits ^ $newBits ) & $oldBits;
221 $virtualNewBits |= $addedBits;
222 $virtualOldBits |= $removedBits;
224 $status->successCount++;
225 $authorActors[] = $item->getAuthorActor();
229 $visibilityChangeMap[$item->getId()] = [
230 'oldBits' => $oldBits,
231 'newBits' => $newBits,
235 'revdelete-concurrent-change', $item->formatDate(), $item->formatTime() );
236 $status->failCount++;
241 foreach ( $missing as $id => $unused ) {
242 if ( $perItemStatus ) {
243 $status->itemStatuses[$id] = Status::newFatal(
'revdelete-modify-missing', $id );
245 $status->error(
'revdelete-modify-missing', $id );
247 $status->failCount++;
250 if ( $status->successCount == 0 ) {
251 $dbw->endAtomic( __METHOD__ );
256 $successCount = $status->successCount;
260 if ( !$status->isOK() ) {
262 $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
263 $lbFactory->rollbackMasterChanges( __METHOD__ );
269 $authorFields[
'authorActors'] = $authorActors;
273 'title' => $this->title,
274 'count' => $successCount,
275 'newBits' => $virtualNewBits,
276 'oldBits' => $virtualOldBits,
277 'comment' => $comment,
279 'tags' => $params[
'tags'] ?? [],
284 DeferredUpdates::addCallableUpdate(
285 function () use ( $visibilityChangeMap ) {
288 DeferredUpdates::PRESEND,
292 $dbw->endAtomic( __METHOD__ );
343 throw new MWException(
"Bad log URL param type!" );
349 $logEntry->setTarget( $params[
'title'] );
350 $logEntry->setComment( $params[
'comment'] );
351 $logEntry->setParameters( $logParams );
352 $logEntry->setPerformer( $this->
getUser() );
355 $field => $params[
'ids'],
357 if ( isset( $params[
'authorActors'] ) ) {
359 'target_author_actor' => $params[
'authorActors'],
362 $logEntry->setRelations( $relations );
364 $logEntry->addTags( $params[
'tags'] );
365 $logId = $logEntry->insert();
366 $logEntry->publish( $logId );