3 * Base class for the output of file transformation methods.
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
25 * Base class for the output of MediaHandler::doTransform() and File::transform().
29 abstract class MediaTransformOutput
{
30 /** @var array Associative array mapping optional supplementary image files
31 * from pixel density (eg 1.5 or 2) to additional URLs.
33 public $responsiveUrls = [];
38 /** @var int Image width */
41 /** @var int Image height */
44 /** @var string URL path to the thumb */
47 /** @var bool|string */
50 /** @var bool|string Filesystem path to the thumb */
53 /** @var bool|string Language code, false if not set */
56 /** @var bool|string Permanent storage path */
57 protected $storagePath = false;
60 * @return int Width of the output box
62 public function getWidth() {
67 * @return int Height of the output box
69 public function getHeight() {
76 public function getFile() {
81 * Get the final extension of the thumbnail.
82 * Returns false for scripted transformations.
85 public function getExtension() {
86 return $this->path ? FileBackend
::extensionFromPath( $this->path
) : false;
90 * @return string|bool The thumbnail URL
92 public function getUrl() {
97 * @return string|bool The permanent thumbnail storage path
99 public function getStoragePath() {
100 return $this->storagePath
;
104 * @param string $storagePath The permanent storage path
107 public function setStoragePath( $storagePath ) {
108 $this->storagePath
= $storagePath;
109 if ( $this->path
=== false ) {
110 $this->path
= $storagePath;
115 * Fetch HTML for this transform output
117 * @param array $options Associative array of options. Boolean options
118 * should be indicated with a value of true for true, and false or
121 * alt Alternate text or caption
122 * desc-link Boolean, show a description link
123 * file-link Boolean, show a file download link
124 * custom-url-link Custom URL to link to
125 * custom-title-link Custom Title object to link to
126 * valign vertical-align property, if the output is an inline element
127 * img-class Class applied to the "<img>" tag, if there is such a tag
129 * For images, desc-link and file-link are implemented as a click-through. For
130 * sounds and videos, they may be displayed in other ways.
134 abstract public function toHtml( $options = [] );
137 * This will be overridden to return true in error classes
140 public function isError() {
145 * Check if an output thumbnail file actually exists.
147 * This will return false if there was an error, the
148 * thumbnail is to be handled client-side only, or if
149 * transformation was deferred via TRANSFORM_LATER.
150 * This file may exist as a new file in /tmp, a file
151 * in permanent storage, or even refer to the original.
155 public function hasFile() {
156 // If TRANSFORM_LATER, $this->path will be false.
157 // Note: a null path means "use the source file".
158 return ( !$this->isError() && ( $this->path ||
$this->path
=== null ) );
162 * Check if the output thumbnail is the same as the source.
163 * This can occur if the requested width was bigger than the source.
167 public function fileIsSource() {
168 return ( !$this->isError() && $this->path
=== null );
172 * Get the path of a file system copy of the thumbnail.
173 * Callers should never write to this path.
175 * @return string|bool Returns false if there isn't one
177 public function getLocalCopyPath() {
178 if ( $this->isError() ) {
180 } elseif ( $this->path
=== null ) {
181 return $this->file
->getLocalRefPath(); // assume thumb was not scaled
182 } elseif ( FileBackend
::isStoragePath( $this->path
) ) {
183 $be = $this->file
->getRepo()->getBackend();
184 // The temp file will be process cached by FileBackend
185 $fsFile = $be->getLocalReference( [ 'src' => $this->path
] );
187 return $fsFile ?
$fsFile->getPath() : false;
189 return $this->path
; // may return false
194 * Stream the file if there were no errors
196 * @param array $headers Additional HTTP headers to send on success
200 public function streamFileWithStatus( $headers = [] ) {
201 if ( !$this->path
) {
202 return Status
::newFatal( 'backend-fail-stream', '<no path>' );
203 } elseif ( FileBackend
::isStoragePath( $this->path
) ) {
204 $be = $this->file
->getRepo()->getBackend();
206 $be->streamFile( [ 'src' => $this->path
, 'headers' => $headers ] ) );
208 $success = StreamFile
::stream( $this->getLocalCopyPath(), $headers );
209 return $success ? Status
::newGood() : Status
::newFatal( 'backend-fail-stream', $this->path
);
214 * Stream the file if there were no errors
216 * @deprecated since 1.26, use streamFileWithStatus
217 * @param array $headers Additional HTTP headers to send on success
218 * @return bool Success
220 public function streamFile( $headers = [] ) {
221 return $this->streamFileWithStatus( $headers )->isOK();
225 * Wrap some XHTML text in an anchor tag with the given attributes
227 * @param array $linkAttribs
228 * @param string $contents
231 protected function linkWrap( $linkAttribs, $contents ) {
232 if ( $linkAttribs ) {
233 return Xml
::tags( 'a', $linkAttribs, $contents );
240 * @param string|null $title
241 * @param string|array $params Query parameters to add
244 public function getDescLinkAttribs( $title = null, $params = [] ) {
245 if ( is_array( $params ) ) {
250 if ( $this->page
&& $this->page
!== 1 ) {
251 $query['page'] = $this->page
;
254 $query['lang'] = $this->lang
;
257 if ( is_string( $params ) && $params !== '' ) {
258 $query = $params . '&' . wfArrayToCgi( $query );
262 'href' => $this->file
->getTitle()->getLocalURL( $query ),
266 $attribs['title'] = $title;