116 $status = Status::newGood();
118 $bitPars = $params[
'value'];
119 $comment = $params[
'comment'];
120 $perItemStatus = $params[
'perItemStatus'] ??
false;
125 $this->res = $this->
doQuery( $dbw );
128 if ( !$status->isGood() ) {
132 $dbw->startAtomic( __METHOD__ );
133 $dbw->onTransactionResolution(
141 $missing = array_flip( $this->ids );
146 if ( $perItemStatus ) {
147 $status->itemStatuses = [];
159 $visibilityChangeMap = [];
162 foreach ( $this as $item ) {
163 unset( $missing[$item->getId()] );
165 if ( $perItemStatus ) {
166 $itemStatus = Status::newGood();
167 $status->itemStatuses[$item->getId()] = $itemStatus;
169 $itemStatus = $status;
172 $oldBits = $item->getBits();
176 if ( $oldBits == $newBits ) {
177 $itemStatus->warning(
178 'revdelete-no-change', $item->formatDate(), $item->formatTime() );
179 $status->failCount++;
181 } elseif ( $oldBits == 0 && $newBits != 0 ) {
183 } elseif ( $oldBits != 0 && $newBits == 0 ) {
189 if ( $item->isHideCurrentOp( $newBits ) ) {
192 'revdelete-hide-current', $item->formatDate(), $item->formatTime() );
193 $status->failCount++;
195 } elseif ( !$item->canView() ) {
197 $msg = ( $opType ==
'show' ) ?
198 'revdelete-show-no-access' :
'revdelete-modify-no-access';
199 $itemStatus->error( $msg, $item->formatDate(), $item->formatTime() );
200 $status->failCount++;
203 } elseif ( $newBits == RevisionRecord::DELETED_RESTRICTED ) {
204 $itemStatus->warning(
205 'revdelete-only-restricted', $item->formatDate(), $item->formatTime() );
206 $status->failCount++;
211 $ok = $item->setBits( $newBits );
214 $idsForLog[] = $item->getId();
217 $logType =
'suppress';
220 $addedBits = ( $oldBits ^ $newBits ) & $newBits;
221 $removedBits = ( $oldBits ^ $newBits ) & $oldBits;
222 $virtualNewBits |= $addedBits;
223 $virtualOldBits |= $removedBits;
225 $status->successCount++;
226 $authorActors[] = $item->getAuthorActor();
230 $visibilityChangeMap[$item->getId()] = [
231 'oldBits' => $oldBits,
232 'newBits' => $newBits,
236 'revdelete-concurrent-change', $item->formatDate(), $item->formatTime() );
237 $status->failCount++;
242 foreach ( $missing as $id => $unused ) {
243 if ( $perItemStatus ) {
244 $status->itemStatuses[$id] = Status::newFatal(
'revdelete-modify-missing', $id );
246 $status->error(
'revdelete-modify-missing', $id );
248 $status->failCount++;
251 if ( $status->successCount == 0 ) {
252 $dbw->endAtomic( __METHOD__ );
257 $successCount = $status->successCount;
261 if ( !$status->isOK() ) {
263 $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
264 $lbFactory->rollbackMasterChanges( __METHOD__ );
270 $authorFields[
'authorActors'] = $authorActors;
274 'title' => $this->title,
275 'count' => $successCount,
276 'newBits' => $virtualNewBits,
277 'oldBits' => $virtualOldBits,
278 'comment' => $comment,
280 'tags' => $params[
'tags'] ?? [],
285 DeferredUpdates::addCallableUpdate(
286 function () use ( $visibilityChangeMap ) {
289 DeferredUpdates::PRESEND,
293 $dbw->endAtomic( __METHOD__ );
344 throw new MWException(
"Bad log URL param type!" );
350 $logEntry->setTarget( $params[
'title'] );
351 $logEntry->setComment( $params[
'comment'] );
352 $logEntry->setParameters( $logParams );
353 $logEntry->setPerformer( $this->
getUser() );
356 $field => $params[
'ids'],
358 if ( isset( $params[
'authorActors'] ) ) {
360 'target_author_actor' => $params[
'authorActors'],
363 $logEntry->setRelations( $relations );
365 $logEntry->addTags( $params[
'tags'] );
366 $logId = $logEntry->insert();
367 $logEntry->publish( $logId );