Kill "* @return void"
[lhc/web/wiklou.git] / includes / media / MediaTransformOutput.php
1 <?php
2 /**
3 * Base class for the output of file transformation methods.
4 *
5 * @file
6 * @ingroup Media
7 */
8
9 /**
10 * Base class for the output of MediaHandler::doTransform() and File::transform().
11 *
12 * @ingroup Media
13 */
14 abstract class MediaTransformOutput {
15 /**
16 * @var File
17 */
18 var $file;
19
20 var $width, $height, $url, $page, $path;
21 protected $storagePath = false;
22
23 /**
24 * Get the width of the output box
25 */
26 public function getWidth() {
27 return $this->width;
28 }
29
30 /**
31 * Get the height of the output box
32 */
33 public function getHeight() {
34 return $this->height;
35 }
36
37 /**
38 * @return string The thumbnail URL
39 */
40 public function getUrl() {
41 return $this->url;
42 }
43
44 /**
45 * @return string|false The permanent thumbnail storage path
46 */
47 public function getStoragePath() {
48 return $this->storagePath;
49 }
50
51 /**
52 * @param $storagePath string The permanent storage path
53 */
54 public function setStoragePath( $storagePath ) {
55 $this->storagePath = $storagePath;
56 }
57
58 /**
59 * Fetch HTML for this transform output
60 *
61 * @param $options array Associative array of options. Boolean options
62 * should be indicated with a value of true for true, and false or
63 * absent for false.
64 *
65 * alt Alternate text or caption
66 * desc-link Boolean, show a description link
67 * file-link Boolean, show a file download link
68 * custom-url-link Custom URL to link to
69 * custom-title-link Custom Title object to link to
70 * valign vertical-align property, if the output is an inline element
71 * img-class Class applied to the <img> tag, if there is such a tag
72 *
73 * For images, desc-link and file-link are implemented as a click-through. For
74 * sounds and videos, they may be displayed in other ways.
75 *
76 * @return string
77 */
78 abstract public function toHtml( $options = array() );
79
80 /**
81 * This will be overridden to return true in error classes
82 */
83 public function isError() {
84 return false;
85 }
86
87 /**
88 * Check if an output thumbnail file was actually made.
89 * This will return false if there was an error, the
90 * thumnail is to be handled client-side only, or if
91 * transformation was deferred via TRANSFORM_LATER.
92 *
93 * @return Bool
94 */
95 public function hasFile() {
96 // If TRANSFORM_LATER, $this->path will be false
97 return ( !$this->isError() && $this->path );
98 }
99
100 /**
101 * Check if the output thumbnail file is the same as the source.
102 * This can occur if the requested width was bigger than the source.
103 *
104 * @return Bool
105 */
106 public function fileIsSource() {
107 return ( !$this->isError() && $this->path === $this->file->getLocalRefPath() );
108 }
109
110 /**
111 * Get the path of a file system copy of the thumbnail
112 *
113 * @return string|false Returns false if there isn't one
114 */
115 public function getLocalCopyPath() {
116 return $this->path;
117 }
118
119 /**
120 * Stream the file if there were no errors
121 *
122 * @param $headers Array Additional HTTP headers to send on success
123 * @return Bool success
124 */
125 public function streamFile( $headers = array() ) {
126 return $this->path && StreamFile::stream( $this->path, $headers );
127 }
128
129 /**
130 * Wrap some XHTML text in an anchor tag with the given attributes
131 *
132 * @param $linkAttribs array
133 * @param $contents string
134 *
135 * @return string
136 */
137 protected function linkWrap( $linkAttribs, $contents ) {
138 if ( $linkAttribs ) {
139 return Xml::tags( 'a', $linkAttribs, $contents );
140 } else {
141 return $contents;
142 }
143 }
144
145 /**
146 * @param $title string
147 * @param $params array
148 * @return array
149 */
150 public function getDescLinkAttribs( $title = null, $params = '' ) {
151 $query = $this->page ? ( 'page=' . urlencode( $this->page ) ) : '';
152 if( $params ) {
153 $query .= $query ? '&'.$params : $params;
154 }
155 $attribs = array(
156 'href' => $this->file->getTitle()->getLocalURL( $query ),
157 'class' => 'image',
158 );
159 if ( $title ) {
160 $attribs['title'] = $title;
161 }
162 return $attribs;
163 }
164 }
165
166 /**
167 * Media transform output for images
168 *
169 * @ingroup Media
170 */
171 class ThumbnailImage extends MediaTransformOutput {
172
173 /**
174 * @param $file File object
175 * @param $url String: URL path to the thumb
176 * @param $width Integer: file's width
177 * @param $height Integer: file's height
178 * @param $path String: filesystem path to the thumb
179 * @param $page Integer: page number, for multipage files
180 * @private
181 */
182 function __construct( $file, $url, $width, $height, $path = false, $page = false ) {
183 $this->file = $file;
184 $this->url = $url;
185 # These should be integers when they get here.
186 # If not, there's a bug somewhere. But let's at
187 # least produce valid HTML code regardless.
188 $this->width = round( $width );
189 $this->height = round( $height );
190 $this->path = $path;
191 $this->page = $page;
192 }
193
194 /**
195 * Return HTML <img ... /> tag for the thumbnail, will include
196 * width and height attributes and a blank alt text (as required).
197 *
198 * @param $options array Associative array of options. Boolean options
199 * should be indicated with a value of true for true, and false or
200 * absent for false.
201 *
202 * alt HTML alt attribute
203 * title HTML title attribute
204 * desc-link Boolean, show a description link
205 * file-link Boolean, show a file download link
206 * valign vertical-align property, if the output is an inline element
207 * img-class Class applied to the \<img\> tag, if there is such a tag
208 * desc-query String, description link query params
209 * custom-url-link Custom URL to link to
210 * custom-title-link Custom Title object to link to
211 * custom target-link Value of the target attribute, for custom-target-link
212 *
213 * For images, desc-link and file-link are implemented as a click-through. For
214 * sounds and videos, they may be displayed in other ways.
215 *
216 * @return string
217 */
218 function toHtml( $options = array() ) {
219 if ( count( func_get_args() ) == 2 ) {
220 throw new MWException( __METHOD__ .' called in the old style' );
221 }
222
223 $alt = empty( $options['alt'] ) ? '' : $options['alt'];
224
225 $query = empty( $options['desc-query'] ) ? '' : $options['desc-query'];
226
227 if ( !empty( $options['custom-url-link'] ) ) {
228 $linkAttribs = array( 'href' => $options['custom-url-link'] );
229 if ( !empty( $options['title'] ) ) {
230 $linkAttribs['title'] = $options['title'];
231 }
232 if ( !empty( $options['custom-target-link'] ) ) {
233 $linkAttribs['target'] = $options['custom-target-link'];
234 }
235 } elseif ( !empty( $options['custom-title-link'] ) ) {
236 $title = $options['custom-title-link'];
237 $linkAttribs = array(
238 'href' => $title->getLinkURL(),
239 'title' => empty( $options['title'] ) ? $title->getFullText() : $options['title']
240 );
241 } elseif ( !empty( $options['desc-link'] ) ) {
242 $linkAttribs = $this->getDescLinkAttribs( empty( $options['title'] ) ? null : $options['title'], $query );
243 } elseif ( !empty( $options['file-link'] ) ) {
244 $linkAttribs = array( 'href' => $this->file->getURL() );
245 } else {
246 $linkAttribs = false;
247 }
248
249 $attribs = array(
250 'alt' => $alt,
251 'src' => $this->url,
252 'width' => $this->width,
253 'height' => $this->height,
254 );
255 if ( !empty( $options['valign'] ) ) {
256 $attribs['style'] = "vertical-align: {$options['valign']}";
257 }
258 if ( !empty( $options['img-class'] ) ) {
259 $attribs['class'] = $options['img-class'];
260 }
261 return $this->linkWrap( $linkAttribs, Xml::element( 'img', $attribs ) );
262 }
263
264 }
265
266 /**
267 * Basic media transform error class
268 *
269 * @ingroup Media
270 */
271 class MediaTransformError extends MediaTransformOutput {
272 var $htmlMsg, $textMsg, $width, $height, $url, $path;
273
274 function __construct( $msg, $width, $height /*, ... */ ) {
275 $args = array_slice( func_get_args(), 3 );
276 $htmlArgs = array_map( 'htmlspecialchars', $args );
277 $htmlArgs = array_map( 'nl2br', $htmlArgs );
278
279 $this->htmlMsg = wfMessage( $msg )->rawParams( $htmlArgs )->escaped();
280 $this->textMsg = wfMessage( $msg )->rawParams( $htmlArgs )->text();
281 $this->width = intval( $width );
282 $this->height = intval( $height );
283 $this->url = false;
284 $this->path = false;
285 }
286
287 function toHtml( $options = array() ) {
288 return "<div class=\"MediaTransformError\" style=\"" .
289 "width: {$this->width}px; height: {$this->height}px; display:inline-block;\">" .
290 $this->htmlMsg .
291 "</div>";
292 }
293
294 function toText() {
295 return $this->textMsg;
296 }
297
298 function getHtmlMsg() {
299 return $this->htmlMsg;
300 }
301
302 function isError() {
303 return true;
304 }
305 }
306
307 /**
308 * Shortcut class for parameter validation errors
309 *
310 * @ingroup Media
311 */
312 class TransformParameterError extends MediaTransformError {
313 function __construct( $params ) {
314 parent::__construct( 'thumbnail_error',
315 max( isset( $params['width'] ) ? $params['width'] : 0, 120 ),
316 max( isset( $params['height'] ) ? $params['height'] : 0, 120 ),
317 wfMsg( 'thumbnail_invalid_params' ) );
318 }
319 }