]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/page/WikiFilePage.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / includes / page / WikiFilePage.php
1 <?php
2 /**
3  * Special handling for file pages.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  * http://www.gnu.org/copyleft/gpl.html
19  *
20  * @file
21  */
22
23 use Wikimedia\Rdbms\FakeResultWrapper;
24
25 /**
26  * Special handling for file pages
27  *
28  * @ingroup Media
29  */
30 class WikiFilePage extends WikiPage {
31         /** @var File */
32         protected $mFile = false;
33         /** @var LocalRepo */
34         protected $mRepo = null;
35         /** @var bool */
36         protected $mFileLoaded = false;
37         /** @var array */
38         protected $mDupes = null;
39
40         public function __construct( $title ) {
41                 parent::__construct( $title );
42                 $this->mDupes = null;
43                 $this->mRepo = null;
44         }
45
46         /**
47          * @param File $file
48          */
49         public function setFile( $file ) {
50                 $this->mFile = $file;
51                 $this->mFileLoaded = true;
52         }
53
54         /**
55          * @return bool
56          */
57         protected function loadFile() {
58                 if ( $this->mFileLoaded ) {
59                         return true;
60                 }
61                 $this->mFileLoaded = true;
62
63                 $this->mFile = wfFindFile( $this->mTitle );
64                 if ( !$this->mFile ) {
65                         $this->mFile = wfLocalFile( $this->mTitle ); // always a File
66                 }
67                 $this->mRepo = $this->mFile->getRepo();
68                 return true;
69         }
70
71         /**
72          * @return mixed|null|Title
73          */
74         public function getRedirectTarget() {
75                 $this->loadFile();
76                 if ( $this->mFile->isLocal() ) {
77                         return parent::getRedirectTarget();
78                 }
79                 // Foreign image page
80                 $from = $this->mFile->getRedirected();
81                 $to = $this->mFile->getName();
82                 if ( $from == $to ) {
83                         return null;
84                 }
85                 $this->mRedirectTarget = Title::makeTitle( NS_FILE, $to );
86                 return $this->mRedirectTarget;
87         }
88
89         /**
90          * @return bool|mixed|Title
91          */
92         public function followRedirect() {
93                 $this->loadFile();
94                 if ( $this->mFile->isLocal() ) {
95                         return parent::followRedirect();
96                 }
97                 $from = $this->mFile->getRedirected();
98                 $to = $this->mFile->getName();
99                 if ( $from == $to ) {
100                         return false;
101                 }
102                 return Title::makeTitle( NS_FILE, $to );
103         }
104
105         /**
106          * @return bool
107          */
108         public function isRedirect() {
109                 $this->loadFile();
110                 if ( $this->mFile->isLocal() ) {
111                         return parent::isRedirect();
112                 }
113
114                 return (bool)$this->mFile->getRedirected();
115         }
116
117         /**
118          * @return bool
119          */
120         public function isLocal() {
121                 $this->loadFile();
122                 return $this->mFile->isLocal();
123         }
124
125         /**
126          * @return bool|File
127          */
128         public function getFile() {
129                 $this->loadFile();
130                 return $this->mFile;
131         }
132
133         /**
134          * @return array|null
135          */
136         public function getDuplicates() {
137                 $this->loadFile();
138                 if ( !is_null( $this->mDupes ) ) {
139                         return $this->mDupes;
140                 }
141                 $hash = $this->mFile->getSha1();
142                 if ( !( $hash ) ) {
143                         $this->mDupes = [];
144                         return $this->mDupes;
145                 }
146                 $dupes = RepoGroup::singleton()->findBySha1( $hash );
147                 // Remove duplicates with self and non matching file sizes
148                 $self = $this->mFile->getRepoName() . ':' . $this->mFile->getName();
149                 $size = $this->mFile->getSize();
150
151                 /**
152                  * @var $file File
153                  */
154                 foreach ( $dupes as $index => $file ) {
155                         $key = $file->getRepoName() . ':' . $file->getName();
156                         if ( $key == $self ) {
157                                 unset( $dupes[$index] );
158                         }
159                         if ( $file->getSize() != $size ) {
160                                 unset( $dupes[$index] );
161                         }
162                 }
163                 $this->mDupes = $dupes;
164                 return $this->mDupes;
165         }
166
167         /**
168          * Override handling of action=purge
169          * @return bool
170          */
171         public function doPurge() {
172                 $this->loadFile();
173
174                 if ( $this->mFile->exists() ) {
175                         wfDebug( 'ImagePage::doPurge purging ' . $this->mFile->getName() . "\n" );
176                         DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this->mTitle, 'imagelinks' ) );
177                 } else {
178                         wfDebug( 'ImagePage::doPurge no image for '
179                                 . $this->mFile->getName() . "; limiting purge to cache only\n" );
180                 }
181
182                 // even if the file supposedly doesn't exist, force any cached information
183                 // to be updated (in case the cached information is wrong)
184
185                 // Purge current version and its thumbnails
186                 $this->mFile->purgeCache( [ 'forThumbRefresh' => true ] );
187
188                 // Purge the old versions and their thumbnails
189                 foreach ( $this->mFile->getHistory() as $oldFile ) {
190                         $oldFile->purgeCache( [ 'forThumbRefresh' => true ] );
191                 }
192
193                 if ( $this->mRepo ) {
194                         // Purge redirect cache
195                         $this->mRepo->invalidateImageRedirect( $this->mTitle );
196                 }
197
198                 return parent::doPurge();
199         }
200
201         /**
202          * Get the categories this file is a member of on the wiki where it was uploaded.
203          * For local files, this is the same as getCategories().
204          * For foreign API files (InstantCommons), this is not supported currently.
205          * Results will include hidden categories.
206          *
207          * @return TitleArray|Title[]
208          * @since 1.23
209          */
210         public function getForeignCategories() {
211                 $this->loadFile();
212                 $title = $this->mTitle;
213                 $file = $this->mFile;
214
215                 if ( !$file instanceof LocalFile ) {
216                         wfDebug( __CLASS__ . '::' . __METHOD__ . " is not supported for this file\n" );
217                         return TitleArray::newFromResult( new FakeResultWrapper( [] ) );
218                 }
219
220                 /** @var LocalRepo $repo */
221                 $repo = $file->getRepo();
222                 $dbr = $repo->getReplicaDB();
223
224                 $res = $dbr->select(
225                         [ 'page', 'categorylinks' ],
226                         [
227                                 'page_title' => 'cl_to',
228                                 'page_namespace' => NS_CATEGORY,
229                         ],
230                         [
231                                 'page_namespace' => $title->getNamespace(),
232                                 'page_title' => $title->getDBkey(),
233                         ],
234                         __METHOD__,
235                         [],
236                         [ 'categorylinks' => [ 'INNER JOIN', 'page_id = cl_from' ] ]
237                 );
238
239                 return TitleArray::newFromResult( $res );
240         }
241
242         /**
243          * @since 1.28
244          * @return string
245          */
246         public function getWikiDisplayName() {
247                 return $this->getFile()->getRepo()->getDisplayName();
248         }
249
250         /**
251          * @since 1.28
252          * @return string
253          */
254         public function getSourceURL() {
255                 return $this->getFile()->getDescriptionUrl();
256         }
257 }