131 $status = Status::newGood();
133 $bitPars = $params[
'value'];
134 $comment = $params[
'comment'];
135 $perItemStatus = $params[
'perItemStatus'] ??
false;
138 if ( $perItemStatus ) {
139 $status->value[
'itemStatuses'] = [];
144 $dbw = $this->lbFactory->getPrimaryDatabase();
145 $this->res = $this->
doQuery( $dbw );
148 if ( !$status->isGood() ) {
152 $dbw->startAtomic( __METHOD__, $dbw::ATOMIC_CANCELABLE );
153 $dbw->onTransactionResolution(
161 $missing = array_fill_keys( $this->ids,
true );
172 $useSuppressLog =
false;
176 $visibilityChangeMap = [];
179 foreach ( $this as $item ) {
180 unset( $missing[$item->getId()] );
182 if ( $perItemStatus ) {
183 $itemStatus = Status::newGood();
184 $status->value[
'itemStatuses'][$item->getId()] = $itemStatus;
186 $itemStatus = $status;
189 $oldBits = $item->getBits();
193 if ( $oldBits == $newBits ) {
194 $itemStatus->warning(
195 'revdelete-no-change', $item->formatDate(), $item->formatTime() );
196 $status->failCount++;
198 } elseif ( $oldBits == 0 && $newBits != 0 ) {
200 } elseif ( $oldBits != 0 && $newBits == 0 ) {
206 if ( $item->isHideCurrentOp( $newBits ) ) {
209 'revdelete-hide-current', $item->formatDate(), $item->formatTime() );
210 $status->failCount++;
212 } elseif ( !$item->canView() ) {
214 $msg = ( $opType ==
'show' ) ?
215 'revdelete-show-no-access' :
'revdelete-modify-no-access';
216 $itemStatus->error( $msg, $item->formatDate(), $item->formatTime() );
217 $status->failCount++;
220 } elseif ( $newBits == self::SUPPRESS_BIT ) {
221 $itemStatus->warning(
222 'revdelete-only-restricted', $item->formatDate(), $item->formatTime() );
223 $status->failCount++;
228 $ok = $item->setBits( $newBits );
231 $idsForLog[] = $item->getId();
233 if ( ( $oldBits | $newBits ) & self::SUPPRESS_BIT ) {
234 $logType =
'suppress';
235 $useSuppressLog =
true;
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->value[
'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 $dbw->cancelAtomic( __METHOD__ );
286 $tags = $params[
'tags'] ?? [];
288 $logEntry = $this->updateLog(
291 'page' => $this->page,
292 'count' => $successCount,
293 'newBits' => $virtualNewBits,
294 'oldBits' => $virtualOldBits,
295 'comment' => $comment,
298 'authorActors' => $authorActors,
302 $this->
emitEvents( $bitPars, $visibilityChangeMap, $tags, $logEntry, $useSuppressLog );
305 DeferredUpdates::addCallableUpdate(
306 function () use ( $visibilityChangeMap ) {
309 DeferredUpdates::PRESEND,
313 $dbw->endAtomic( __METHOD__ );