26use Psr\Log\LoggerInterface;
79 $this->oldHash = $this->file->repo->getHashPath( $this->file->getName() );
80 $this->newHash = $this->file->repo->getHashPath( $this->target->getDBkey() );
81 $this->oldName = $this->file->getName();
82 $this->newName = $this->file->repo->getNameFromTitle( $this->target );
87 $this->logger = LoggerFactory::getInstance(
'imagemove' );
102 $archiveBase =
'archive';
107 $result = $this->db->select(
'oldimage',
108 [
'oi_archive_name',
'oi_deleted' ],
109 [
'oi_name' => $this->oldName ],
111 [
'LOCK IN SHARE MODE' ]
114 foreach ( $result as $row ) {
115 $archiveNames[] = $row->oi_archive_name;
117 $bits = explode(
'!',
$oldName, 2 );
119 if ( count( $bits ) != 2 ) {
120 $this->logger->debug(
121 'Old file name missing !: {oldName}',
127 list( $timestamp, $filename ) = $bits;
129 if ( $this->oldName != $filename ) {
130 $this->logger->debug(
131 'Old file name does not match: {oldName}',
140 if ( $row->oi_deleted & File::DELETED_FILE ) {
145 "{$archiveBase}/{$this->oldHash}{$oldName}",
146 "{$archiveBase}/{$this->newHash}{$timestamp}!{$this->newName}"
150 return $archiveNames;
158 $repo = $this->file->repo;
159 $status = $repo->newGood();
160 $destFile = MediaWikiServices::getInstance()->getRepoGroup()->getLocalRepo()
161 ->newFile( $this->target );
168 if ( !$checkStatus->isGood() ) {
170 $this->file->unlock();
171 $status->merge( $checkStatus );
174 $triplets = $checkStatus->value;
178 if ( !$statusDb->isGood() ) {
180 $this->file->unlock();
181 $statusDb->setOK(
false );
186 if ( !$repo->hasSha1Storage() ) {
192 $this->logger->debug(
193 'Moved files for {fileName}: {successCount} successes, {failCount} failures',
195 'fileName' => $this->file->getName(),
196 'successCount' => $statusMove->successCount,
197 'failCount' => $statusMove->failCount,
201 if ( !$statusMove->isGood() ) {
205 $this->file->unlock();
207 $this->logger->debug(
208 'Error in moving files: {error}',
209 [
'error' => $statusMove->getWikiText(
false,
false,
'en' ) ]
212 $statusMove->setOK(
false );
216 $status->merge( $statusMove );
222 $this->logger->debug(
223 'Renamed {fileName} in database: {successCount} successes, {failCount} failures',
225 'fileName' => $this->file->getName(),
226 'successCount' => $statusDb->successCount,
227 'failCount' => $statusDb->failCount,
232 $this->file->unlock();
237 $status->merge( $statusDb );
249 $repo = $this->file->repo;
250 $status = $repo->newGood();
255 [
'img_name' => $this->oldName ],
258 $oldRowCount = $dbw->lockForUpdate(
260 [
'oi_name' => $this->oldName ],
265 $status->successCount++;
267 $status->failCount++;
269 $status->successCount += $oldRowCount;
273 $status->failCount += max( 0, $this->oldCount - $oldRowCount );
274 if ( $status->failCount ) {
275 $status->error(
'imageinvalidfilename' );
291 [
'img_name' => $this->newName ],
292 [
'img_name' => $this->oldName ],
300 'oi_name' => $this->newName,
301 'oi_archive_name = ' . $dbw->strreplace(
'oi_archive_name',
302 $dbw->addQuotes( $this->oldName ), $dbw->addQuotes( $this->newName ) ),
304 [
'oi_name' => $this->oldName ],
314 $moves = array_merge( [ $this->cur ], $this->olds );
317 foreach ( $moves as $move ) {
319 $srcUrl = $this->file->repo->getVirtualUrl() .
'/public/' . rawurlencode( $move[0] );
320 $triplets[] = [ $srcUrl,
'public', $move[1] ];
322 $this->logger->debug(
323 'Generated move triplet for {fileName}: {srcUrl} :: public :: {move1}',
325 'fileName' => $this->file->getName(),
343 foreach ( $triplets as
$file ) {
347 $result = $this->file->repo->fileExistsBatch( $files );
348 if ( in_array(
null, $result,
true ) ) {
349 return Status::newFatal(
'backend-fail-internal',
350 $this->file->repo->getBackend()->getName() );
353 $filteredTriplets = [];
354 foreach ( $triplets as
$file ) {
355 if ( $result[
$file[0]] ) {
356 $filteredTriplets[] =
$file;
358 $this->logger->debug(
359 'File {file} does not exist',
360 [
'file' =>
$file[0] ]
365 return Status::newGood( $filteredTriplets );
376 foreach ( $triplets as $triplet ) {
378 $pairs[] = [ $triplet[1], $triplet[2] ];
381 $this->file->repo->cleanupBatch( $pairs );
392 foreach ( $triplets as $triplet ) {
393 $files[] = $triplet[0];
396 $this->file->repo->cleanupBatch( $files );
Helper class for file movement.
cleanupTarget( $triplets)
Cleanup a partially moved array of triplets by deleting the target files.
addOlds()
Add the old versions of the image to the batch.
doDBUpdates()
Do the database updates and return a new Status indicating how many rows where updated.
getMoveTriplets()
Generate triplets for FileRepo::storeBatch().
execute()
Perform the move.
verifyDBUpdates()
Verify the database updates and return a new Status indicating how many rows would be updated.
removeNonexistentFiles( $triplets)
Removes non-existent files from move batch.
__construct(LocalFile $file, Title $target)
addCurrent()
Add the current image to the batch.
cleanupSource( $triplets)
Cleanup a fully moved array of triplets by deleting the source files.
Class to represent a local file in the wiki's own database.
Represents a title within MediaWiki.