134 $status = Status::newGood();
136 $bitPars = $params[
'value'];
137 $comment = $params[
'comment'];
138 $perItemStatus = $params[
'perItemStatus'] ??
false;
142 $dbw = $this->lbFactory->getMainLB()->getConnectionRef(
DB_PRIMARY );
143 $this->res = $this->
doQuery( $dbw );
146 if ( !$status->isGood() ) {
150 $dbw->startAtomic( __METHOD__ );
151 $dbw->onTransactionResolution(
159 $missing = array_fill_keys( $this->ids,
true );
164 if ( $perItemStatus ) {
165 $status->itemStatuses = [];
177 $visibilityChangeMap = [];
180 foreach ( $this as $item ) {
181 unset( $missing[$item->getId()] );
183 if ( $perItemStatus ) {
184 $itemStatus = Status::newGood();
185 $status->itemStatuses[$item->getId()] = $itemStatus;
187 $itemStatus = $status;
190 $oldBits = $item->getBits();
194 if ( $oldBits == $newBits ) {
195 $itemStatus->warning(
196 'revdelete-no-change', $item->formatDate(), $item->formatTime() );
197 $status->failCount++;
199 } elseif ( $oldBits == 0 && $newBits != 0 ) {
201 } elseif ( $oldBits != 0 && $newBits == 0 ) {
207 if ( $item->isHideCurrentOp( $newBits ) ) {
210 'revdelete-hide-current', $item->formatDate(), $item->formatTime() );
211 $status->failCount++;
213 } elseif ( !$item->canView() ) {
215 $msg = ( $opType ==
'show' ) ?
216 'revdelete-show-no-access' :
'revdelete-modify-no-access';
217 $itemStatus->error( $msg, $item->formatDate(), $item->formatTime() );
218 $status->failCount++;
221 } elseif ( $newBits == RevisionRecord::DELETED_RESTRICTED ) {
222 $itemStatus->warning(
223 'revdelete-only-restricted', $item->formatDate(), $item->formatTime() );
224 $status->failCount++;
229 $ok = $item->setBits( $newBits );
232 $idsForLog[] = $item->getId();
235 $logType =
'suppress';
238 $addedBits = ( $oldBits ^ $newBits ) & $newBits;
239 $removedBits = ( $oldBits ^ $newBits ) & $oldBits;
240 $virtualNewBits |= $addedBits;
241 $virtualOldBits |= $removedBits;
243 $status->successCount++;
244 $authorActors[] = $item->getAuthorActor();
248 $visibilityChangeMap[$item->getId()] = [
249 'oldBits' => $oldBits,
250 'newBits' => $newBits,
254 'revdelete-concurrent-change', $item->formatDate(), $item->formatTime() );
255 $status->failCount++;
260 foreach ( $missing as $id => $unused ) {
261 if ( $perItemStatus ) {
262 $status->itemStatuses[$id] = Status::newFatal(
'revdelete-modify-missing', $id );
264 $status->error(
'revdelete-modify-missing', $id );
266 $status->failCount++;
269 if ( $status->successCount == 0 ) {
270 $dbw->endAtomic( __METHOD__ );
275 $successCount = $status->successCount;
279 if ( !$status->isOK() ) {
281 $this->lbFactory->rollbackPrimaryChanges( __METHOD__ );
287 $authorFields[
'authorActors'] = $authorActors;
291 'title' => $this->title,
292 'count' => $successCount,
293 'newBits' => $virtualNewBits,
294 'oldBits' => $virtualOldBits,
295 'comment' => $comment,
297 'tags' => $params[
'tags'] ?? [],
302 DeferredUpdates::addCallableUpdate(
303 function () use ( $visibilityChangeMap ) {
306 DeferredUpdates::PRESEND,
310 $dbw->endAtomic( __METHOD__ );
370 throw new MWException(
"Bad log URL param type!" );
376 $logEntry->setTarget( $params[
'title'] );
377 $logEntry->setComment( $params[
'comment'] );
378 $logEntry->setParameters( $logParams );
379 $logEntry->setPerformer( $this->
getUser() );
382 $field => $params[
'ids'],
384 if ( isset( $params[
'authorActors'] ) ) {
386 'target_author_actor' => $params[
'authorActors'],
389 $logEntry->setRelations( $relations );
391 $logEntry->addTags( $params[
'tags'] );
392 $logId = $logEntry->insert();
393 $logEntry->publish( $logId );