MediaWiki master
WikiFilePage.php
Go to the documentation of this file.
1<?php
7namespace MediaWiki\Page;
8
18use RuntimeException;
20
26class WikiFilePage extends WikiPage {
28 protected $mFile = false;
30 protected $mRepo = null;
32 protected $mFileLoaded = false;
34 protected $mDupes = null;
35
39 public function __construct( $title ) {
40 parent::__construct( $title );
41 $this->mDupes = null;
42 $this->mRepo = null;
43 }
44
45 public function setFile( File $file ) {
46 $this->mFile = $file;
47 $this->mFileLoaded = true;
48 }
49
53 protected function loadFile() {
55 if ( $this->mFileLoaded ) {
56 return true;
57 }
58
59 $this->mFile = $services->getRepoGroup()->findFile( $this->mTitle );
60 if ( !$this->mFile ) {
61 $this->mFile = $services->getRepoGroup()->getLocalRepo()
62 ->newFile( $this->mTitle );
63 }
64
65 if ( !$this->mFile instanceof File ) {
66 throw new RuntimeException( 'Expected to find file. See T250767' );
67 }
68
69 $this->mRepo = $this->mFile->getRepo();
70 $this->mFileLoaded = true;
71 return true;
72 }
73
77 public function followRedirect() {
78 $this->loadFile();
79 if ( $this->mFile->isLocal() ) {
80 return parent::followRedirect();
81 }
82 $from = $this->mFile->getRedirected();
83 $to = $this->mFile->getName();
84 if ( $from === null || $from === $to ) {
85 return false;
86 }
87 return Title::makeTitle( NS_FILE, $to );
88 }
89
93 public function isRedirect() {
94 $this->loadFile();
95 if ( $this->mFile->isLocal() ) {
96 return parent::isRedirect();
97 }
98
99 return $this->mFile->getRedirected() !== null;
100 }
101
105 public function isLocal() {
106 $this->loadFile();
107 return $this->mFile->isLocal();
108 }
109
110 public function getFile(): File {
111 $this->loadFile();
112 return $this->mFile;
113 }
114
118 public function getDuplicates() {
119 $this->loadFile();
120 if ( $this->mDupes !== null ) {
121 return $this->mDupes;
122 }
123 $hash = $this->mFile->getSha1();
124 if ( !( $hash ) ) {
125 $this->mDupes = [];
126 return $this->mDupes;
127 }
128 $dupes = MediaWikiServices::getInstance()->getRepoGroup()->findBySha1( $hash );
129 // Remove duplicates with self and non matching file sizes
130 $self = $this->mFile->getRepoName() . ':' . $this->mFile->getName();
131 $size = $this->mFile->getSize();
132
136 foreach ( $dupes as $index => $file ) {
137 $key = $file->getRepoName() . ':' . $file->getName();
138 if ( $key === $self || $file->getSize() != $size ) {
139 unset( $dupes[$index] );
140 }
141 }
142 $this->mDupes = $dupes;
143 return $this->mDupes;
144 }
145
150 public function doPurge() {
151 $this->loadFile();
152
153 if ( $this->mFile->exists() ) {
154 wfDebug( 'ImagePage::doPurge purging ' . $this->mFile->getName() );
155 $job = HTMLCacheUpdateJob::newForBacklinks(
156 $this->mTitle,
157 'imagelinks',
158 [ 'causeAction' => 'file-purge' ]
159 );
160 MediaWikiServices::getInstance()->getJobQueueGroup()->lazyPush( $job );
161 } else {
162 wfDebug( 'ImagePage::doPurge no image for '
163 . $this->mFile->getName() . "; limiting purge to cache only" );
164 }
165
166 // even if the file supposedly doesn't exist, force any cached information
167 // to be updated (in case the cached information is wrong)
168
169 // Purge current version and its thumbnails
170 $this->mFile->purgeCache( [ 'forThumbRefresh' => true ] );
171
172 // Purge the old versions and their thumbnails
173 foreach ( $this->mFile->getHistory() as $oldFile ) {
174 $oldFile->purgeCache( [ 'forThumbRefresh' => true ] );
175 }
176
177 if ( $this->mRepo ) {
178 // Purge redirect cache
179 $this->mRepo->invalidateImageRedirect( $this->mTitle );
180 }
181
182 return parent::doPurge();
183 }
184
194 public function getForeignCategories() {
195 $this->loadFile();
196 $title = $this->mTitle;
197 $file = $this->mFile;
198
199 $services = MediaWikiServices::getInstance();
200 $titleFactory = $services->getTitleFactory();
201 $lbFactory = $services->getDBLoadBalancerFactory();
202
203 if ( !$file instanceof LocalFile ) {
204 wfDebug( __METHOD__ . " is not supported for this file" );
205 return $titleFactory->newTitleArrayFromResult( new FakeResultWrapper( [] ) );
206 }
207
209 $repo = $file->getRepo();
210 $wikiId = $repo->getDbDomain();
211 $dbr = $lbFactory->getRemoteReplicaDatabase( $wikiId, LinksTable::VIRTUAL_DOMAIN );
212 $res = $dbr->newSelectQueryBuilder()
213 ->select( [ 'page_title' => 'lt_title', 'page_namespace' => (string)NS_CATEGORY ] )
214 ->from( 'page' )
215 ->join( 'categorylinks', null, 'page_id = cl_from' )
216 ->join( 'linktarget', null, 'cl_target_id = lt_id' )
217 ->where( [ 'page_namespace' => $title->getNamespace(), 'page_title' => $title->getDBkey(), ] )
218 ->caller( __METHOD__ )
219 ->fetchResultSet();
220
221 return $titleFactory->newTitleArrayFromResult( $res );
222 }
223
228 public function getWikiDisplayName() {
229 return $this->getFile()->getRepo()->getDisplayName();
230 }
231
236 public function getSourceURL() {
237 return $this->getFile()->getDescriptionUrl();
238 }
239
243 public function getActionOverrides() {
244 $file = $this->getFile();
245 if ( $file->exists() && $file->isLocal() && !$file->getRedirected() ) {
246 // Would be an actual file deletion
247 return [ 'delete' => [
248 'class' => FileDeleteAction::class,
249 'services' => [
250 'RepoGroup',
251 'UrlUtils',
252 ],
253 ] ] + parent::getActionOverrides();
254 }
255 // It should use the normal article deletion interface
256 return parent::getActionOverrides();
257 }
258}
259
261class_alias( WikiFilePage::class, 'WikiFilePage' );
const NS_FILE
Definition Defines.php:57
const NS_CATEGORY
Definition Defines.php:65
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
makeTitle( $linkId)
Convert a link ID to a Title.to override Title
The base class for classes which update a single link table.
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition File.php:80
Local file in the wiki's own database.
Definition LocalFile.php:80
Local repository that stores files in the local filesystem and registers them in the wiki's own datab...
Definition LocalRepo.php:44
Job to purge the HTML/file cache for all pages that link to or use another page or file.
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
Special handling for representing file pages.
doPurge()
Override handling of action=purge.
getForeignCategories()
Get the categories this file is a member of on the wiki where it was uploaded.
getActionOverrides()
Move this UI stuff somewhere elseContentHandler::getActionOverrides array
Base representation for an editable wiki page.
Definition WikiPage.php:83
Represents a title within MediaWiki.
Definition Title.php:69
Overloads the relevant methods of the real ResultWrapper so it doesn't go anywhere near an actual dat...
if(count( $args)< 1) $job