]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blobdiff - maintenance/deleteArchivedFiles.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / maintenance / deleteArchivedFiles.php
index 6067c8077e65589fe0fc879b231630845cec8007..0f33a141501876313cd7a0b010c5460843b306db 100644 (file)
@@ -1,8 +1,9 @@
 <?php
-
 /**
  * Delete archived (non-current) files from the database
  *
+ * Based on deleteOldRevisions.php by Rob Church.
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  * http://www.gnu.org/copyleft/gpl.html
  *
+ * @file
  * @ingroup Maintenance
- * @author Aaron Schulz
- * Based on deleteOldRevisions.php by Rob Church
  */
 
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
-require_once( dirname( __FILE__ ) . '/deleteArchivedFiles.inc' );
+require_once __DIR__ . '/Maintenance.php';
 
+/**
+ * Maintenance script to delete archived (non-current) files from the database.
+ *
+ * @ingroup Maintenance
+ */
 class DeleteArchivedFiles extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Deletes all archived images.";
+               $this->addDescription( 'Deletes all archived images.' );
                $this->addOption( 'delete', 'Perform the deletion' );
                $this->addOption( 'force', 'Force deletion of rows from filearchive' );
        }
 
-       public function handleOutput( $str ) {
-               return $this->output( $str );
-       }
-
        public function execute() {
                if ( !$this->hasOption( 'delete' ) ) {
                        $this->output( "Use --delete to actually confirm this script\n" );
                        return;
                }
-               $force = $this->hasOption( 'force' );
-               DeleteArchivedFilesImplementation::doDelete( $this, $force );
+
+               # Data should come off the master, wrapped in a transaction
+               $dbw = $this->getDB( DB_MASTER );
+               $this->beginTransaction( $dbw, __METHOD__ );
+               $repo = RepoGroup::singleton()->getLocalRepo();
+
+               # Get "active" revisions from the filearchive table
+               $this->output( "Searching for and deleting archived files...\n" );
+               $res = $dbw->select(
+                       'filearchive',
+                       [ 'fa_id', 'fa_storage_group', 'fa_storage_key', 'fa_sha1', 'fa_name' ],
+                       '',
+                       __METHOD__
+               );
+
+               $count = 0;
+               foreach ( $res as $row ) {
+                       $key = $row->fa_storage_key;
+                       if ( !strlen( $key ) ) {
+                               $this->output( "Entry with ID {$row->fa_id} has empty key, skipping\n" );
+                               continue;
+                       }
+
+                       /** @var LocalFile $file */
+                       $file = $repo->newFile( $row->fa_name );
+                       try {
+                               $file->lock();
+                       } catch ( LocalFileLockError $e ) {
+                               $this->error( "Could not acquire lock on '{$row->fa_name}', skipping\n" );
+                               continue;
+                       }
+
+                       $group = $row->fa_storage_group;
+                       $id = $row->fa_id;
+                       $path = $repo->getZonePath( 'deleted' ) .
+                               '/' . $repo->getDeletedHashPath( $key ) . $key;
+                       if ( isset( $row->fa_sha1 ) ) {
+                               $sha1 = $row->fa_sha1;
+                       } else {
+                               // old row, populate from key
+                               $sha1 = LocalRepo::getHashFromKey( $key );
+                       }
+
+                       // Check if the file is used anywhere...
+                       $inuse = $dbw->selectField(
+                               'oldimage',
+                               '1',
+                               [
+                                       'oi_sha1' => $sha1,
+                                       $dbw->bitAnd( 'oi_deleted', File::DELETED_FILE ) => File::DELETED_FILE
+                               ],
+                               __METHOD__,
+                               [ 'FOR UPDATE' ]
+                       );
+
+                       $needForce = true;
+                       if ( !$repo->fileExists( $path ) ) {
+                               $this->output( "Notice - file '$key' not found in group '$group'\n" );
+                       } elseif ( $inuse ) {
+                               $this->output( "Notice - file '$key' is still in use\n" );
+                       } elseif ( !$repo->quickPurge( $path ) ) {
+                               $this->output( "Unable to remove file $path, skipping\n" );
+                               $file->unlock();
+                               continue; // don't delete even with --force
+                       } else {
+                               $needForce = false;
+                       }
+
+                       if ( $needForce ) {
+                               if ( $this->hasOption( 'force' ) ) {
+                                       $this->output( "Got --force, deleting DB entry\n" );
+                               } else {
+                                       $file->unlock();
+                                       continue;
+                               }
+                       }
+
+                       $count++;
+                       $dbw->delete( 'filearchive', [ 'fa_id' => $id ], __METHOD__ );
+                       $file->unlock();
+               }
+
+               $this->commitTransaction( $dbw, __METHOD__ );
+               $this->output( "Done! [$count file(s)]\n" );
        }
 }
 
 $maintClass = "DeleteArchivedFiles";
-require_once( RUN_MAINTENANCE_IF_MAIN );
+require_once RUN_MAINTENANCE_IF_MAIN;