Merge "Parse huge XML metadata from DjVu images"
[mediawiki.git] / includes / page / WikiFilePage.php
blobc508abe3892f7202932583d2b76431c4e3f64a48
1 <?php
2 /**
3 * Special handling for file pages.
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.
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.
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
20 * @file
23 /**
24 * Special handling for file pages
26 * @ingroup Media
28 class WikiFilePage extends WikiPage {
29 /**
30 * @var File
32 protected $mFile = false; // !< File object
33 protected $mRepo = null; // !<
34 protected $mFileLoaded = false; // !<
35 protected $mDupes = null; // !<
37 public function __construct( $title ) {
38 parent::__construct( $title );
39 $this->mDupes = null;
40 $this->mRepo = null;
43 /**
44 * @param File $file
46 public function setFile( $file ) {
47 $this->mFile = $file;
48 $this->mFileLoaded = true;
51 /**
52 * @return bool
54 protected function loadFile() {
55 if ( $this->mFileLoaded ) {
56 return true;
58 $this->mFileLoaded = true;
60 $this->mFile = wfFindFile( $this->mTitle );
61 if ( !$this->mFile ) {
62 $this->mFile = wfLocalFile( $this->mTitle ); // always a File
64 $this->mRepo = $this->mFile->getRepo();
65 return true;
68 /**
69 * @return mixed|null|Title
71 public function getRedirectTarget() {
72 $this->loadFile();
73 if ( $this->mFile->isLocal() ) {
74 return parent::getRedirectTarget();
76 // Foreign image page
77 $from = $this->mFile->getRedirected();
78 $to = $this->mFile->getName();
79 if ( $from == $to ) {
80 return null;
82 $this->mRedirectTarget = Title::makeTitle( NS_FILE, $to );
83 return $this->mRedirectTarget;
86 /**
87 * @return bool|mixed|Title
89 public function followRedirect() {
90 $this->loadFile();
91 if ( $this->mFile->isLocal() ) {
92 return parent::followRedirect();
94 $from = $this->mFile->getRedirected();
95 $to = $this->mFile->getName();
96 if ( $from == $to ) {
97 return false;
99 return Title::makeTitle( NS_FILE, $to );
103 * @return bool
105 public function isRedirect() {
106 $this->loadFile();
107 if ( $this->mFile->isLocal() ) {
108 return parent::isRedirect();
111 return (bool)$this->mFile->getRedirected();
115 * @return bool
117 public function isLocal() {
118 $this->loadFile();
119 return $this->mFile->isLocal();
123 * @return bool|File
125 public function getFile() {
126 $this->loadFile();
127 return $this->mFile;
131 * @return array|null
133 public function getDuplicates() {
134 $this->loadFile();
135 if ( !is_null( $this->mDupes ) ) {
136 return $this->mDupes;
138 $hash = $this->mFile->getSha1();
139 if ( !( $hash ) ) {
140 $this->mDupes = array();
141 return $this->mDupes;
143 $dupes = RepoGroup::singleton()->findBySha1( $hash );
144 // Remove duplicates with self and non matching file sizes
145 $self = $this->mFile->getRepoName() . ':' . $this->mFile->getName();
146 $size = $this->mFile->getSize();
149 * @var $file File
151 foreach ( $dupes as $index => $file ) {
152 $key = $file->getRepoName() . ':' . $file->getName();
153 if ( $key == $self ) {
154 unset( $dupes[$index] );
156 if ( $file->getSize() != $size ) {
157 unset( $dupes[$index] );
160 $this->mDupes = $dupes;
161 return $this->mDupes;
165 * Override handling of action=purge
166 * @return bool
168 public function doPurge() {
169 $this->loadFile();
170 if ( $this->mFile->exists() ) {
171 wfDebug( 'ImagePage::doPurge purging ' . $this->mFile->getName() . "\n" );
172 DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this->mTitle, 'imagelinks' ) );
173 $this->mFile->upgradeRow();
174 $this->mFile->purgeCache( array( 'forThumbRefresh' => true ) );
175 } else {
176 wfDebug( 'ImagePage::doPurge no image for '
177 . $this->mFile->getName() . "; limiting purge to cache only\n" );
178 // even if the file supposedly doesn't exist, force any cached information
179 // to be updated (in case the cached information is wrong)
180 $this->mFile->purgeCache( array( 'forThumbRefresh' => true ) );
182 if ( $this->mRepo ) {
183 // Purge redirect cache
184 $this->mRepo->invalidateImageRedirect( $this->mTitle );
186 return parent::doPurge();
190 * Get the categories this file is a member of on the wiki where it was uploaded.
191 * For local files, this is the same as getCategories().
192 * For foreign API files (InstantCommons), this is not supported currently.
193 * Results will include hidden categories.
195 * @return TitleArray|Title[]
196 * @since 1.23
198 public function getForeignCategories() {
199 $this->loadFile();
200 $title = $this->mTitle;
201 $file = $this->mFile;
203 if ( !$file instanceof LocalFile ) {
204 wfDebug( __CLASS__ . '::' . __METHOD__ . " is not supported for this file\n" );
205 return TitleArray::newFromResult( new FakeResultWrapper( array() ) );
208 /** @var LocalRepo $repo */
209 $repo = $file->getRepo();
210 $dbr = $repo->getSlaveDB();
212 $res = $dbr->select(
213 array( 'page', 'categorylinks' ),
214 array(
215 'page_title' => 'cl_to',
216 'page_namespace' => NS_CATEGORY,
218 array(
219 'page_namespace' => $title->getNamespace(),
220 'page_title' => $title->getDBkey(),
222 __METHOD__,
223 array(),
224 array( 'categorylinks' => array( 'INNER JOIN', 'page_id = cl_from' ) )
227 return TitleArray::newFromResult( $res );