Move UploadStashFile to its own file
[lhc/web/wiklou.git] / includes / upload / UploadStashFile.php
1 <?php
2 /**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 */
20
21 /**
22 * @ingroup Upload
23 */
24 class UploadStashFile extends UnregisteredLocalFile {
25 private $fileKey;
26 private $urlName;
27 protected $url;
28
29 /**
30 * A LocalFile wrapper around a file that has been temporarily stashed,
31 * so we can do things like create thumbnails for it. Arguably
32 * UnregisteredLocalFile should be handling its own file repo but that
33 * class is a bit retarded currently.
34 *
35 * @param FileRepo $repo Repository where we should find the path
36 * @param string $path Path to file
37 * @param string $key Key to store the path and any stashed data under
38 * @throws UploadStashBadPathException
39 * @throws UploadStashFileNotFoundException
40 */
41 public function __construct( $repo, $path, $key ) {
42 $this->fileKey = $key;
43
44 // resolve mwrepo:// urls
45 if ( FileRepo::isVirtualUrl( $path ) ) {
46 $path = $repo->resolveVirtualUrl( $path );
47 } else {
48 // check if path appears to be sane, no parent traversals,
49 // and is in this repo's temp zone.
50 $repoTempPath = $repo->getZonePath( 'temp' );
51 if ( ( !$repo->validateFilename( $path ) ) ||
52 ( strpos( $path, $repoTempPath ) !== 0 )
53 ) {
54 wfDebug( "UploadStash: tried to construct an UploadStashFile "
55 . "from a file that should already exist at '$path', but path is not valid\n" );
56 throw new UploadStashBadPathException(
57 wfMessage( 'uploadstash-bad-path-invalid' )
58 );
59 }
60
61 // check if path exists! and is a plain file.
62 if ( !$repo->fileExists( $path ) ) {
63 wfDebug( "UploadStash: tried to construct an UploadStashFile from "
64 . "a file that should already exist at '$path', but path is not found\n" );
65 throw new UploadStashFileNotFoundException(
66 wfMessage( 'uploadstash-file-not-found-not-exists' )
67 );
68 }
69 }
70
71 parent::__construct( false, $repo, $path, false );
72
73 $this->name = basename( $this->path );
74 }
75
76 /**
77 * A method needed by the file transforming and scaling routines in File.php
78 * We do not necessarily care about doing the description at this point
79 * However, we also can't return the empty string, as the rest of MediaWiki
80 * demands this (and calls to imagemagick convert require it to be there)
81 *
82 * @return string Dummy value
83 */
84 public function getDescriptionUrl() {
85 return $this->getUrl();
86 }
87
88 /**
89 * Get the path for the thumbnail (actually any transformation of this file)
90 * The actual argument is the result of thumbName although we seem to have
91 * buggy code elsewhere that expects a boolean 'suffix'
92 *
93 * @param string $thumbName Name of thumbnail (e.g. "120px-123456.jpg" ),
94 * or false to just get the path
95 * @return string Path thumbnail should take on filesystem, or containing
96 * directory if thumbname is false
97 */
98 public function getThumbPath( $thumbName = false ) {
99 $path = dirname( $this->path );
100 if ( $thumbName !== false ) {
101 $path .= "/$thumbName";
102 }
103
104 return $path;
105 }
106
107 /**
108 * Return the file/url base name of a thumbnail with the specified parameters.
109 * We override this because we want to use the pretty url name instead of the
110 * ugly file name.
111 *
112 * @param array $params Handler-specific parameters
113 * @param int $flags Bitfield that supports THUMB_* constants
114 * @return string|null Base name for URL, like '120px-12345.jpg', or null if there is no handler
115 */
116 function thumbName( $params, $flags = 0 ) {
117 return $this->generateThumbName( $this->getUrlName(), $params );
118 }
119
120 /**
121 * Helper function -- given a 'subpage', return the local URL,
122 * e.g. /wiki/Special:UploadStash/subpage
123 * @param string $subPage
124 * @return string Local URL for this subpage in the Special:UploadStash space.
125 */
126 private function getSpecialUrl( $subPage ) {
127 return SpecialPage::getTitleFor( 'UploadStash', $subPage )->getLocalURL();
128 }
129
130 /**
131 * Get a URL to access the thumbnail
132 * This is required because the model of how files work requires that
133 * the thumbnail urls be predictable. However, in our model the URL is
134 * not based on the filename (that's hidden in the db)
135 *
136 * @param string $thumbName Basename of thumbnail file -- however, we don't
137 * want to use the file exactly
138 * @return string URL to access thumbnail, or URL with partial path
139 */
140 public function getThumbUrl( $thumbName = false ) {
141 wfDebug( __METHOD__ . " getting for $thumbName \n" );
142
143 return $this->getSpecialUrl( 'thumb/' . $this->getUrlName() . '/' . $thumbName );
144 }
145
146 /**
147 * The basename for the URL, which we want to not be related to the filename.
148 * Will also be used as the lookup key for a thumbnail file.
149 *
150 * @return string Base url name, like '120px-123456.jpg'
151 */
152 public function getUrlName() {
153 if ( !$this->urlName ) {
154 $this->urlName = $this->fileKey;
155 }
156
157 return $this->urlName;
158 }
159
160 /**
161 * Return the URL of the file, if for some reason we wanted to download it
162 * We tend not to do this for the original file, but we do want thumb icons
163 *
164 * @return string Url
165 */
166 public function getUrl() {
167 if ( !isset( $this->url ) ) {
168 $this->url = $this->getSpecialUrl( 'file/' . $this->getUrlName() );
169 }
170
171 return $this->url;
172 }
173
174 /**
175 * Parent classes use this method, for no obvious reason, to return the path
176 * (relative to wiki root, I assume). But with this class, the URL is
177 * unrelated to the path.
178 *
179 * @return string Url
180 */
181 public function getFullUrl() {
182 return $this->getUrl();
183 }
184
185 /**
186 * Getter for file key (the unique id by which this file's location &
187 * metadata is stored in the db)
188 *
189 * @return string File key
190 */
191 public function getFileKey() {
192 return $this->fileKey;
193 }
194
195 /**
196 * Remove the associated temporary file
197 * @return bool Success
198 */
199 public function remove() {
200 if ( !$this->repo->fileExists( $this->path ) ) {
201 // Maybe the file's already been removed? This could totally happen in UploadBase.
202 return true;
203 }
204
205 return $this->repo->freeTemp( $this->path );
206 }
207
208 public function exists() {
209 return $this->repo->fileExists( $this->path );
210 }
211 }