mCallback = $callback; } /** * Overridden to ensure that we return a fresh value and not a cached one. * * @return int */ public function getVisibility() { if ( $this->mCallback ) { $this->loadFreshRow(); } return parent::getVisibility(); } /** * Overridden to ensure that we return a fresh value and not a cached one. * * @param int $audience * @param User|null $user * * @return UserIdentity The identity of the revision author, null if access is forbidden. */ public function getUser( $audience = self::FOR_PUBLIC, User $user = null ) { if ( $this->mCallback ) { $this->loadFreshRow(); } return parent::getUser( $audience, $user ); } /** * Load a fresh row from the database to ensure we return updated information * @throws RevisionAccessException if the row could not be loaded */ private function loadFreshRow() { $freshRow = call_user_func( $this->mCallback, $this->mId ); // Set to null to ensure we do not make unnecessary queries for subsequent getter calls, // and to allow the closure to be freed. $this->mCallback = null; if ( $freshRow ) { $this->mDeleted = intval( $freshRow->rev_deleted ); try { $this->mUser = User::newFromAnyId( $freshRow->rev_user ?? null, $freshRow->rev_user_text ?? null, $freshRow->rev_actor ?? null ); } catch ( InvalidArgumentException $ex ) { wfWarn( __METHOD__ . ': ' . $this->mTitle->getPrefixedDBkey() . ': ' . $ex->getMessage() ); $this->mUser = new UserIdentityValue( 0, 'Unknown user', 0 ); } } else { throw new RevisionAccessException( 'Unable to load fresh row for rev_id: ' . $this->mId ); } } }