MediaWiki master
eraseArchivedFile.php
Go to the documentation of this file.
1<?php
25
26// @codeCoverageIgnoreStart
27require_once __DIR__ . '/Maintenance.php';
28// @codeCoverageIgnoreEnd
29
39 public function __construct() {
40 parent::__construct();
41 $this->addDescription( 'Erases traces of deleted files.' );
42 $this->addOption( 'delete', 'Perform the deletion' );
43 $this->addOption( 'filename', 'File name', false, true );
44 $this->addOption( 'filekey', 'File storage key (with extension) or "*"', true, true );
45 }
46
47 public function execute() {
48 if ( !$this->hasOption( 'delete' ) ) {
49 $this->output( "Use --delete to actually confirm this script\n" );
50 }
51
52 $filekey = $this->getOption( 'filekey' );
53 $filename = $this->getOption( 'filename' );
54
55 if ( $filekey === '*' ) {
56 // all versions by name
57 if ( !strlen( $filename ) ) {
58 $this->fatalError( "Missing --filename parameter." );
59 }
60 $afile = false;
61 } else {
62 // specified version
63 $dbw = $this->getPrimaryDB();
64 $queryBuilder = FileSelectQueryBuilder::newForArchivedFile( $dbw );
65 $queryBuilder->where( [ 'fa_storage_group' => 'deleted', 'fa_storage_key' => $filekey ] );
66 $row = $queryBuilder->caller( __METHOD__ )->fetchRow();
67
68 if ( !$row ) {
69 $this->fatalError( "No deleted file exists with key '$filekey'." );
70 }
71 $filename = $row->fa_name;
72 $afile = ArchivedFile::newFromRow( $row );
73 }
74
75 $file = $this->getServiceContainer()->getRepoGroup()->getLocalRepo()->newFile( $filename );
76 if ( $file->exists() ) {
77 $this->fatalError( "File '$filename' is still a public file, use the delete form.\n" );
78 }
79
80 $this->output( "Purging all thumbnails for file '$filename'..." );
81 $file->purgeCache();
82 $this->output( "done.\n" );
83
84 if ( $afile instanceof ArchivedFile ) {
85 $this->scrubVersion( $afile );
86 } else {
87 $this->output( "Finding deleted versions of file '$filename'...\n" );
88 $this->scrubAllVersions( $filename );
89 $this->output( "Done\n" );
90 }
91 }
92
93 protected function scrubAllVersions( $name ) {
94 $dbw = $this->getPrimaryDB();
95 $queryBuilder = FileSelectQueryBuilder::newForArchivedFile( $dbw );
96 $queryBuilder->where( [ 'fa_name' => $name, 'fa_storage_group' => 'deleted' ] );
97 $res = $queryBuilder->caller( __METHOD__ )->fetchResultSet();
98 foreach ( $res as $row ) {
99 $this->scrubVersion( ArchivedFile::newFromRow( $row ) );
100 }
101 }
102
103 protected function scrubVersion( ArchivedFile $archivedFile ) {
104 $key = $archivedFile->getStorageKey();
105 $name = $archivedFile->getName();
106 $ts = $archivedFile->getTimestamp();
107 $repo = $this->getServiceContainer()->getRepoGroup()->getLocalRepo();
108 $path = $repo->getZonePath( 'deleted' ) . '/' . $repo->getDeletedHashPath( $key ) . $key;
109 if ( $this->hasOption( 'delete' ) ) {
110 $status = $repo->getBackend()->delete( [ 'src' => $path ] );
111 if ( $status->isOK() ) {
112 $this->output( "Deleted version '$key' ($ts) of file '$name'\n" );
113 } else {
114 $this->output( "Failed to delete version '$key' ($ts) of file '$name'\n" );
115 $this->error( $status );
116 }
117 } else {
118 $this->output( "Would delete version '{$key}' ({$ts}) of file '$name'\n" );
119 }
120 }
121}
122
123// @codeCoverageIgnoreStart
124$maintClass = EraseArchivedFile::class;
125require_once RUN_MAINTENANCE_IF_MAIN;
126// @codeCoverageIgnoreEnd
Deleted file in the 'filearchive' table.
getTimestamp()
Return upload timestamp.
getStorageKey()
Return the FileStore key (overriding base File class)
getName()
Return the file name.
Maintenance script to delete archived (non-current) files from storage.
scrubVersion(ArchivedFile $archivedFile)
execute()
Do the actual work.
__construct()
Default constructor.
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
error( $err, $die=0)
Throw an error to the user.
output( $out, $channel=null)
Throw some output to the user.
hasOption( $name)
Checks to see if a particular option was set.
getServiceContainer()
Returns the main service container.
addDescription( $text)
Set the description text.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
getOption( $name, $default=null)
Get an option, or return the default.
fatalError( $msg, $exitCode=1)
Output a message and terminate the current script.