Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like File often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use File, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 50 | abstract class File implements IDBAccessObject { |
||
| 51 | // Bitfield values akin to the Revision deletion constants |
||
| 52 | const DELETED_FILE = 1; |
||
| 53 | const DELETED_COMMENT = 2; |
||
| 54 | const DELETED_USER = 4; |
||
| 55 | const DELETED_RESTRICTED = 8; |
||
| 56 | |||
| 57 | /** Force rendering in the current process */ |
||
| 58 | const RENDER_NOW = 1; |
||
| 59 | /** |
||
| 60 | * Force rendering even if thumbnail already exist and using RENDER_NOW |
||
| 61 | * I.e. you have to pass both flags: File::RENDER_NOW | File::RENDER_FORCE |
||
| 62 | */ |
||
| 63 | const RENDER_FORCE = 2; |
||
| 64 | |||
| 65 | const DELETE_SOURCE = 1; |
||
| 66 | |||
| 67 | // Audience options for File::getDescription() |
||
| 68 | const FOR_PUBLIC = 1; |
||
| 69 | const FOR_THIS_USER = 2; |
||
| 70 | const RAW = 3; |
||
| 71 | |||
| 72 | // Options for File::thumbName() |
||
| 73 | const THUMB_FULL_NAME = 1; |
||
| 74 | |||
| 75 | /** |
||
| 76 | * Some member variables can be lazy-initialised using __get(). The |
||
| 77 | * initialisation function for these variables is always a function named |
||
| 78 | * like getVar(), where Var is the variable name with upper-case first |
||
| 79 | * letter. |
||
| 80 | * |
||
| 81 | * The following variables are initialised in this way in this base class: |
||
| 82 | * name, extension, handler, path, canRender, isSafeFile, |
||
| 83 | * transformScript, hashPath, pageCount, url |
||
| 84 | * |
||
| 85 | * Code within this class should generally use the accessor function |
||
| 86 | * directly, since __get() isn't re-entrant and therefore causes bugs that |
||
| 87 | * depend on initialisation order. |
||
| 88 | */ |
||
| 89 | |||
| 90 | /** |
||
| 91 | * The following member variables are not lazy-initialised |
||
| 92 | */ |
||
| 93 | |||
| 94 | /** @var FileRepo|LocalRepo|ForeignAPIRepo|bool */ |
||
| 95 | public $repo; |
||
| 96 | |||
| 97 | /** @var Title|string|bool */ |
||
| 98 | protected $title; |
||
| 99 | |||
| 100 | /** @var string Text of last error */ |
||
| 101 | protected $lastError; |
||
| 102 | |||
| 103 | /** @var string Main part of the title, with underscores (Title::getDBkey) */ |
||
| 104 | protected $redirected; |
||
| 105 | |||
| 106 | /** @var Title */ |
||
| 107 | protected $redirectedTitle; |
||
| 108 | |||
| 109 | /** @var FSFile|bool False if undefined */ |
||
| 110 | protected $fsFile; |
||
| 111 | |||
| 112 | /** @var MediaHandler */ |
||
| 113 | protected $handler; |
||
| 114 | |||
| 115 | /** @var string The URL corresponding to one of the four basic zones */ |
||
| 116 | protected $url; |
||
| 117 | |||
| 118 | /** @var string File extension */ |
||
| 119 | protected $extension; |
||
| 120 | |||
| 121 | /** @var string The name of a file from its title object */ |
||
| 122 | protected $name; |
||
| 123 | |||
| 124 | /** @var string The storage path corresponding to one of the zones */ |
||
| 125 | protected $path; |
||
| 126 | |||
| 127 | /** @var string Relative path including trailing slash */ |
||
| 128 | protected $hashPath; |
||
| 129 | |||
| 130 | /** @var string Number of pages of a multipage document, or false for |
||
| 131 | * documents which aren't multipage documents |
||
| 132 | */ |
||
| 133 | protected $pageCount; |
||
| 134 | |||
| 135 | /** @var string URL of transformscript (for example thumb.php) */ |
||
| 136 | protected $transformScript; |
||
| 137 | |||
| 138 | /** @var Title */ |
||
| 139 | protected $redirectTitle; |
||
| 140 | |||
| 141 | /** @var bool Whether the output of transform() for this file is likely to be valid. */ |
||
| 142 | protected $canRender; |
||
| 143 | |||
| 144 | /** @var bool Whether this media file is in a format that is unlikely to |
||
| 145 | * contain viruses or malicious content |
||
| 146 | */ |
||
| 147 | protected $isSafeFile; |
||
| 148 | |||
| 149 | /** @var string Required Repository class type */ |
||
| 150 | protected $repoClass = 'FileRepo'; |
||
| 151 | |||
| 152 | /** @var array Cache of tmp filepaths pointing to generated bucket thumbnails, keyed by width */ |
||
| 153 | protected $tmpBucketedThumbCache = []; |
||
| 154 | |||
| 155 | /** |
||
| 156 | * Call this constructor from child classes. |
||
| 157 | * |
||
| 158 | * Both $title and $repo are optional, though some functions |
||
| 159 | * may return false or throw exceptions if they are not set. |
||
| 160 | * Most subclasses will want to call assertRepoDefined() here. |
||
| 161 | * |
||
| 162 | * @param Title|string|bool $title |
||
| 163 | * @param FileRepo|bool $repo |
||
| 164 | */ |
||
| 165 | function __construct( $title, $repo ) { |
||
| 173 | |||
| 174 | /** |
||
| 175 | * Given a string or Title object return either a |
||
| 176 | * valid Title object with namespace NS_FILE or null |
||
| 177 | * |
||
| 178 | * @param Title|string $title |
||
| 179 | * @param string|bool $exception Use 'exception' to throw an error on bad titles |
||
| 180 | * @throws MWException |
||
| 181 | * @return Title|null |
||
| 182 | */ |
||
| 183 | static function normalizeTitle( $title, $exception = false ) { |
||
| 203 | |||
| 204 | function __get( $name ) { |
||
| 205 | $function = [ $this, 'get' . ucfirst( $name ) ]; |
||
| 206 | if ( !is_callable( $function ) ) { |
||
| 207 | return null; |
||
| 208 | } else { |
||
| 209 | $this->$name = call_user_func( $function ); |
||
| 210 | |||
| 211 | return $this->$name; |
||
| 212 | } |
||
| 213 | } |
||
| 214 | |||
| 215 | /** |
||
| 216 | * Normalize a file extension to the common form, making it lowercase and checking some synonyms, |
||
| 217 | * and ensure it's clean. Extensions with non-alphanumeric characters will be discarded. |
||
| 218 | * Keep in sync with mw.Title.normalizeExtension() in JS. |
||
| 219 | * |
||
| 220 | * @param string $extension File extension (without the leading dot) |
||
| 221 | * @return string File extension in canonical form |
||
| 222 | */ |
||
| 223 | static function normalizeExtension( $extension ) { |
||
| 239 | |||
| 240 | /** |
||
| 241 | * Checks if file extensions are compatible |
||
| 242 | * |
||
| 243 | * @param File $old Old file |
||
| 244 | * @param string $new New name |
||
| 245 | * |
||
| 246 | * @return bool|null |
||
| 247 | */ |
||
| 248 | static function checkExtensionCompatibility( File $old, $new ) { |
||
| 256 | |||
| 257 | /** |
||
| 258 | * Upgrade the database row if there is one |
||
| 259 | * Called by ImagePage |
||
| 260 | * STUB |
||
| 261 | */ |
||
| 262 | function upgradeRow() { |
||
| 264 | |||
| 265 | /** |
||
| 266 | * Split an internet media type into its two components; if not |
||
| 267 | * a two-part name, set the minor type to 'unknown'. |
||
| 268 | * |
||
| 269 | * @param string $mime "text/html" etc |
||
| 270 | * @return array ("text", "html") etc |
||
| 271 | */ |
||
| 272 | public static function splitMime( $mime ) { |
||
| 279 | |||
| 280 | /** |
||
| 281 | * Callback for usort() to do file sorts by name |
||
| 282 | * |
||
| 283 | * @param File $a |
||
| 284 | * @param File $b |
||
| 285 | * @return int Result of name comparison |
||
| 286 | */ |
||
| 287 | public static function compare( File $a, File $b ) { |
||
| 290 | |||
| 291 | /** |
||
| 292 | * Return the name of this file |
||
| 293 | * |
||
| 294 | * @return string |
||
| 295 | */ |
||
| 296 | public function getName() { |
||
| 304 | |||
| 305 | /** |
||
| 306 | * Get the file extension, e.g. "svg" |
||
| 307 | * |
||
| 308 | * @return string |
||
| 309 | */ |
||
| 310 | function getExtension() { |
||
| 319 | |||
| 320 | /** |
||
| 321 | * Return the associated title object |
||
| 322 | * |
||
| 323 | * @return Title |
||
| 324 | */ |
||
| 325 | public function getTitle() { |
||
| 328 | |||
| 329 | /** |
||
| 330 | * Return the title used to find this file |
||
| 331 | * |
||
| 332 | * @return Title |
||
| 333 | */ |
||
| 334 | public function getOriginalTitle() { |
||
| 341 | |||
| 342 | /** |
||
| 343 | * Return the URL of the file |
||
| 344 | * |
||
| 345 | * @return string |
||
| 346 | */ |
||
| 347 | public function getUrl() { |
||
| 356 | |||
| 357 | /* |
||
| 358 | * Get short description URL for a files based on the page ID |
||
| 359 | * |
||
| 360 | * @return string|null |
||
| 361 | * @since 1.27 |
||
| 362 | */ |
||
| 363 | public function getDescriptionShortUrl() { |
||
| 366 | |||
| 367 | /** |
||
| 368 | * Return a fully-qualified URL to the file. |
||
| 369 | * Upload URL paths _may or may not_ be fully qualified, so |
||
| 370 | * we check. Local paths are assumed to belong on $wgServer. |
||
| 371 | * |
||
| 372 | * @return string |
||
| 373 | */ |
||
| 374 | public function getFullUrl() { |
||
| 377 | |||
| 378 | /** |
||
| 379 | * @return string |
||
| 380 | */ |
||
| 381 | public function getCanonicalUrl() { |
||
| 384 | |||
| 385 | /** |
||
| 386 | * @return string |
||
| 387 | */ |
||
| 388 | function getViewURL() { |
||
| 402 | |||
| 403 | /** |
||
| 404 | * Return the storage path to the file. Note that this does |
||
| 405 | * not mean that a file actually exists under that location. |
||
| 406 | * |
||
| 407 | * This path depends on whether directory hashing is active or not, |
||
| 408 | * i.e. whether the files are all found in the same directory, |
||
| 409 | * or in hashed paths like /images/3/3c. |
||
| 410 | * |
||
| 411 | * Most callers don't check the return value, but ForeignAPIFile::getPath |
||
| 412 | * returns false. |
||
| 413 | * |
||
| 414 | * @return string|bool ForeignAPIFile::getPath can return false |
||
| 415 | */ |
||
| 416 | public function getPath() { |
||
| 424 | |||
| 425 | /** |
||
| 426 | * Get an FS copy or original of this file and return the path. |
||
| 427 | * Returns false on failure. Callers must not alter the file. |
||
| 428 | * Temporary files are cleared automatically. |
||
| 429 | * |
||
| 430 | * @return string|bool False on failure |
||
| 431 | */ |
||
| 432 | public function getLocalRefPath() { |
||
| 451 | |||
| 452 | /** |
||
| 453 | * Return the width of the image. Returns false if the width is unknown |
||
| 454 | * or undefined. |
||
| 455 | * |
||
| 456 | * STUB |
||
| 457 | * Overridden by LocalFile, UnregisteredLocalFile |
||
| 458 | * |
||
| 459 | * @param int $page |
||
| 460 | * @return int|bool |
||
| 461 | */ |
||
| 462 | public function getWidth( $page = 1 ) { |
||
| 465 | |||
| 466 | /** |
||
| 467 | * Return the height of the image. Returns false if the height is unknown |
||
| 468 | * or undefined |
||
| 469 | * |
||
| 470 | * STUB |
||
| 471 | * Overridden by LocalFile, UnregisteredLocalFile |
||
| 472 | * |
||
| 473 | * @param int $page |
||
| 474 | * @return bool|int False on failure |
||
| 475 | */ |
||
| 476 | public function getHeight( $page = 1 ) { |
||
| 479 | |||
| 480 | /** |
||
| 481 | * Return the smallest bucket from $wgThumbnailBuckets which is at least |
||
| 482 | * $wgThumbnailMinimumBucketDistance larger than $desiredWidth. The returned bucket, if any, |
||
| 483 | * will always be bigger than $desiredWidth. |
||
| 484 | * |
||
| 485 | * @param int $desiredWidth |
||
| 486 | * @param int $page |
||
| 487 | * @return bool|int |
||
| 488 | */ |
||
| 489 | public function getThumbnailBucket( $desiredWidth, $page = 1 ) { |
||
| 523 | |||
| 524 | /** |
||
| 525 | * Returns ID or name of user who uploaded the file |
||
| 526 | * STUB |
||
| 527 | * |
||
| 528 | * @param string $type 'text' or 'id' |
||
| 529 | * @return string|int |
||
| 530 | */ |
||
| 531 | public function getUser( $type = 'text' ) { |
||
| 534 | |||
| 535 | /** |
||
| 536 | * Get the duration of a media file in seconds |
||
| 537 | * |
||
| 538 | * @return int |
||
| 539 | */ |
||
| 540 | public function getLength() { |
||
| 548 | |||
| 549 | /** |
||
| 550 | * Return true if the file is vectorized |
||
| 551 | * |
||
| 552 | * @return bool |
||
| 553 | */ |
||
| 554 | public function isVectorized() { |
||
| 562 | |||
| 563 | /** |
||
| 564 | * Gives a (possibly empty) list of languages to render |
||
| 565 | * the file in. |
||
| 566 | * |
||
| 567 | * If the file doesn't have translations, or if the file |
||
| 568 | * format does not support that sort of thing, returns |
||
| 569 | * an empty array. |
||
| 570 | * |
||
| 571 | * @return array |
||
| 572 | * @since 1.23 |
||
| 573 | */ |
||
| 574 | public function getAvailableLanguages() { |
||
| 582 | |||
| 583 | /** |
||
| 584 | * In files that support multiple language, what is the default language |
||
| 585 | * to use if none specified. |
||
| 586 | * |
||
| 587 | * @return string|null Lang code, or null if filetype doesn't support multiple languages. |
||
| 588 | * @since 1.23 |
||
| 589 | */ |
||
| 590 | public function getDefaultRenderLanguage() { |
||
| 598 | |||
| 599 | /** |
||
| 600 | * Will the thumbnail be animated if one would expect it to be. |
||
| 601 | * |
||
| 602 | * Currently used to add a warning to the image description page |
||
| 603 | * |
||
| 604 | * @return bool False if the main image is both animated |
||
| 605 | * and the thumbnail is not. In all other cases must return |
||
| 606 | * true. If image is not renderable whatsoever, should |
||
| 607 | * return true. |
||
| 608 | */ |
||
| 609 | public function canAnimateThumbIfAppropriate() { |
||
| 631 | |||
| 632 | /** |
||
| 633 | * Get handler-specific metadata |
||
| 634 | * Overridden by LocalFile, UnregisteredLocalFile |
||
| 635 | * STUB |
||
| 636 | * @return bool|array |
||
| 637 | */ |
||
| 638 | public function getMetadata() { |
||
| 641 | |||
| 642 | /** |
||
| 643 | * Like getMetadata but returns a handler independent array of common values. |
||
| 644 | * @see MediaHandler::getCommonMetaArray() |
||
| 645 | * @return array|bool Array or false if not supported |
||
| 646 | * @since 1.23 |
||
| 647 | */ |
||
| 648 | public function getCommonMetaArray() { |
||
| 657 | |||
| 658 | /** |
||
| 659 | * get versioned metadata |
||
| 660 | * |
||
| 661 | * @param array|string $metadata Array or string of (serialized) metadata |
||
| 662 | * @param int $version Version number. |
||
| 663 | * @return array Array containing metadata, or what was passed to it on fail |
||
| 664 | * (unserializing if not array) |
||
| 665 | */ |
||
| 666 | public function convertMetadataVersion( $metadata, $version ) { |
||
| 678 | |||
| 679 | /** |
||
| 680 | * Return the bit depth of the file |
||
| 681 | * Overridden by LocalFile |
||
| 682 | * STUB |
||
| 683 | * @return int |
||
| 684 | */ |
||
| 685 | public function getBitDepth() { |
||
| 688 | |||
| 689 | /** |
||
| 690 | * Return the size of the image file, in bytes |
||
| 691 | * Overridden by LocalFile, UnregisteredLocalFile |
||
| 692 | * STUB |
||
| 693 | * @return bool |
||
| 694 | */ |
||
| 695 | public function getSize() { |
||
| 698 | |||
| 699 | /** |
||
| 700 | * Returns the MIME type of the file. |
||
| 701 | * Overridden by LocalFile, UnregisteredLocalFile |
||
| 702 | * STUB |
||
| 703 | * |
||
| 704 | * @return string |
||
| 705 | */ |
||
| 706 | function getMimeType() { |
||
| 709 | |||
| 710 | /** |
||
| 711 | * Return the type of the media in the file. |
||
| 712 | * Use the value returned by this function with the MEDIATYPE_xxx constants. |
||
| 713 | * Overridden by LocalFile, |
||
| 714 | * STUB |
||
| 715 | * @return string |
||
| 716 | */ |
||
| 717 | function getMediaType() { |
||
| 720 | |||
| 721 | /** |
||
| 722 | * Checks if the output of transform() for this file is likely |
||
| 723 | * to be valid. If this is false, various user elements will |
||
| 724 | * display a placeholder instead. |
||
| 725 | * |
||
| 726 | * Currently, this checks if the file is an image format |
||
| 727 | * that can be converted to a format |
||
| 728 | * supported by all browsers (namely GIF, PNG and JPEG), |
||
| 729 | * or if it is an SVG image and SVG conversion is enabled. |
||
| 730 | * |
||
| 731 | * @return bool |
||
| 732 | */ |
||
| 733 | function canRender() { |
||
| 740 | |||
| 741 | /** |
||
| 742 | * Accessor for __get() |
||
| 743 | * @return bool |
||
| 744 | */ |
||
| 745 | protected function getCanRender() { |
||
| 748 | |||
| 749 | /** |
||
| 750 | * Return true if the file is of a type that can't be directly |
||
| 751 | * rendered by typical browsers and needs to be re-rasterized. |
||
| 752 | * |
||
| 753 | * This returns true for everything but the bitmap types |
||
| 754 | * supported by all browsers, i.e. JPEG; GIF and PNG. It will |
||
| 755 | * also return true for any non-image formats. |
||
| 756 | * |
||
| 757 | * @return bool |
||
| 758 | */ |
||
| 759 | function mustRender() { |
||
| 762 | |||
| 763 | /** |
||
| 764 | * Alias for canRender() |
||
| 765 | * |
||
| 766 | * @return bool |
||
| 767 | */ |
||
| 768 | function allowInlineDisplay() { |
||
| 771 | |||
| 772 | /** |
||
| 773 | * Determines if this media file is in a format that is unlikely to |
||
| 774 | * contain viruses or malicious content. It uses the global |
||
| 775 | * $wgTrustedMediaFormats list to determine if the file is safe. |
||
| 776 | * |
||
| 777 | * This is used to show a warning on the description page of non-safe files. |
||
| 778 | * It may also be used to disallow direct [[media:...]] links to such files. |
||
| 779 | * |
||
| 780 | * Note that this function will always return true if allowInlineDisplay() |
||
| 781 | * or isTrustedFile() is true for this file. |
||
| 782 | * |
||
| 783 | * @return bool |
||
| 784 | */ |
||
| 785 | function isSafeFile() { |
||
| 792 | |||
| 793 | /** |
||
| 794 | * Accessor for __get() |
||
| 795 | * |
||
| 796 | * @return bool |
||
| 797 | */ |
||
| 798 | protected function getIsSafeFile() { |
||
| 801 | |||
| 802 | /** |
||
| 803 | * Uncached accessor |
||
| 804 | * |
||
| 805 | * @return bool |
||
| 806 | */ |
||
| 807 | protected function getIsSafeFileUncached() { |
||
| 837 | |||
| 838 | /** |
||
| 839 | * Returns true if the file is flagged as trusted. Files flagged that way |
||
| 840 | * can be linked to directly, even if that is not allowed for this type of |
||
| 841 | * file normally. |
||
| 842 | * |
||
| 843 | * This is a dummy function right now and always returns false. It could be |
||
| 844 | * implemented to extract a flag from the database. The trusted flag could be |
||
| 845 | * set on upload, if the user has sufficient privileges, to bypass script- |
||
| 846 | * and html-filters. It may even be coupled with cryptographics signatures |
||
| 847 | * or such. |
||
| 848 | * |
||
| 849 | * @return bool |
||
| 850 | */ |
||
| 851 | function isTrustedFile() { |
||
| 856 | |||
| 857 | /** |
||
| 858 | * Load any lazy-loaded file object fields from source |
||
| 859 | * |
||
| 860 | * This is only useful when setting $flags |
||
| 861 | * |
||
| 862 | * Overridden by LocalFile to actually query the DB |
||
| 863 | * |
||
| 864 | * @param integer $flags Bitfield of File::READ_* constants |
||
| 865 | */ |
||
| 866 | public function load( $flags = 0 ) { |
||
| 868 | |||
| 869 | /** |
||
| 870 | * Returns true if file exists in the repository. |
||
| 871 | * |
||
| 872 | * Overridden by LocalFile to avoid unnecessary stat calls. |
||
| 873 | * |
||
| 874 | * @return bool Whether file exists in the repository. |
||
| 875 | */ |
||
| 876 | public function exists() { |
||
| 879 | |||
| 880 | /** |
||
| 881 | * Returns true if file exists in the repository and can be included in a page. |
||
| 882 | * It would be unsafe to include private images, making public thumbnails inadvertently |
||
| 883 | * |
||
| 884 | * @return bool Whether file exists in the repository and is includable. |
||
| 885 | */ |
||
| 886 | public function isVisible() { |
||
| 889 | |||
| 890 | /** |
||
| 891 | * @return string |
||
| 892 | */ |
||
| 893 | function getTransformScript() { |
||
| 906 | |||
| 907 | /** |
||
| 908 | * Get a ThumbnailImage which is the same size as the source |
||
| 909 | * |
||
| 910 | * @param array $handlerParams |
||
| 911 | * |
||
| 912 | * @return string |
||
| 913 | */ |
||
| 914 | function getUnscaledThumb( $handlerParams = [] ) { |
||
| 927 | |||
| 928 | /** |
||
| 929 | * Return the file name of a thumbnail with the specified parameters. |
||
| 930 | * Use File::THUMB_FULL_NAME to always get a name like "<params>-<source>". |
||
| 931 | * Otherwise, the format may be "<params>-<source>" or "<params>-thumbnail.<ext>". |
||
| 932 | * |
||
| 933 | * @param array $params Handler-specific parameters |
||
| 934 | * @param int $flags Bitfield that supports THUMB_* constants |
||
| 935 | * @return string|null |
||
| 936 | */ |
||
| 937 | public function thumbName( $params, $flags = 0 ) { |
||
| 944 | |||
| 945 | /** |
||
| 946 | * Generate a thumbnail file name from a name and specified parameters |
||
| 947 | * |
||
| 948 | * @param string $name |
||
| 949 | * @param array $params Parameters which will be passed to MediaHandler::makeParamString |
||
| 950 | * @return string|null |
||
| 951 | */ |
||
| 952 | public function generateThumbName( $name, $params ) { |
||
| 973 | |||
| 974 | /** |
||
| 975 | * Create a thumbnail of the image having the specified width/height. |
||
| 976 | * The thumbnail will not be created if the width is larger than the |
||
| 977 | * image's width. Let the browser do the scaling in this case. |
||
| 978 | * The thumbnail is stored on disk and is only computed if the thumbnail |
||
| 979 | * file does not exist OR if it is older than the image. |
||
| 980 | * Returns the URL. |
||
| 981 | * |
||
| 982 | * Keeps aspect ratio of original image. If both width and height are |
||
| 983 | * specified, the generated image will be no bigger than width x height, |
||
| 984 | * and will also have correct aspect ratio. |
||
| 985 | * |
||
| 986 | * @param int $width Maximum width of the generated thumbnail |
||
| 987 | * @param int $height Maximum height of the image (optional) |
||
| 988 | * |
||
| 989 | * @return string |
||
| 990 | */ |
||
| 991 | public function createThumb( $width, $height = -1 ) { |
||
| 1003 | |||
| 1004 | /** |
||
| 1005 | * Return either a MediaTransformError or placeholder thumbnail (if $wgIgnoreImageErrors) |
||
| 1006 | * |
||
| 1007 | * @param string $thumbPath Thumbnail storage path |
||
| 1008 | * @param string $thumbUrl Thumbnail URL |
||
| 1009 | * @param array $params |
||
| 1010 | * @param int $flags |
||
| 1011 | * @return MediaTransformOutput |
||
| 1012 | */ |
||
| 1013 | protected function transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags ) { |
||
| 1024 | |||
| 1025 | /** |
||
| 1026 | * Transform a media file |
||
| 1027 | * |
||
| 1028 | * @param array $params An associative array of handler-specific parameters. |
||
| 1029 | * Typical keys are width, height and page. |
||
| 1030 | * @param int $flags A bitfield, may contain self::RENDER_NOW to force rendering |
||
| 1031 | * @return MediaTransformOutput|bool False on failure |
||
| 1032 | */ |
||
| 1033 | function transform( $params, $flags = 0 ) { |
||
| 1110 | |||
| 1111 | /** |
||
| 1112 | * Generates a thumbnail according to the given parameters and saves it to storage |
||
| 1113 | * @param TempFSFile $tmpFile Temporary file where the rendered thumbnail will be saved |
||
| 1114 | * @param array $transformParams |
||
| 1115 | * @param int $flags |
||
| 1116 | * @return bool|MediaTransformOutput |
||
| 1117 | */ |
||
| 1118 | public function generateAndSaveThumb( $tmpFile, $transformParams, $flags ) { |
||
| 1178 | |||
| 1179 | /** |
||
| 1180 | * Generates chained bucketed thumbnails if needed |
||
| 1181 | * @param array $params |
||
| 1182 | * @param int $flags |
||
| 1183 | * @return bool Whether at least one bucket was generated |
||
| 1184 | */ |
||
| 1185 | protected function generateBucketsIfNeeded( $params, $flags = 0 ) { |
||
| 1236 | |||
| 1237 | /** |
||
| 1238 | * Returns the most appropriate source image for the thumbnail, given a target thumbnail size |
||
| 1239 | * @param array $params |
||
| 1240 | * @return array Source path and width/height of the source |
||
| 1241 | */ |
||
| 1242 | public function getThumbnailSource( $params ) { |
||
| 1243 | if ( $this->repo |
||
| 1244 | && $this->getHandler()->supportsBucketing() |
||
| 1245 | && isset( $params['physicalWidth'] ) |
||
| 1246 | && $bucket = $this->getThumbnailBucket( $params['physicalWidth'] ) |
||
| 1247 | ) { |
||
| 1248 | if ( $this->getWidth() != 0 ) { |
||
| 1249 | $bucketHeight = round( $this->getHeight() * ( $bucket / $this->getWidth() ) ); |
||
| 1250 | } else { |
||
| 1251 | $bucketHeight = 0; |
||
| 1252 | } |
||
| 1253 | |||
| 1254 | // Try to avoid reading from storage if the file was generated by this script |
||
| 1255 | if ( isset( $this->tmpBucketedThumbCache[$bucket] ) ) { |
||
| 1256 | $tmpPath = $this->tmpBucketedThumbCache[$bucket]; |
||
| 1257 | |||
| 1258 | if ( file_exists( $tmpPath ) ) { |
||
| 1259 | return [ |
||
| 1260 | 'path' => $tmpPath, |
||
| 1261 | 'width' => $bucket, |
||
| 1262 | 'height' => $bucketHeight |
||
| 1263 | ]; |
||
| 1264 | } |
||
| 1265 | } |
||
| 1266 | |||
| 1267 | $bucketPath = $this->getBucketThumbPath( $bucket ); |
||
| 1268 | |||
| 1269 | if ( $this->repo->fileExists( $bucketPath ) ) { |
||
| 1270 | $fsFile = $this->repo->getLocalReference( $bucketPath ); |
||
| 1271 | |||
| 1272 | if ( $fsFile ) { |
||
| 1273 | return [ |
||
| 1274 | 'path' => $fsFile->getPath(), |
||
| 1275 | 'width' => $bucket, |
||
| 1276 | 'height' => $bucketHeight |
||
| 1277 | ]; |
||
| 1278 | } |
||
| 1279 | } |
||
| 1280 | } |
||
| 1281 | |||
| 1282 | // Thumbnailing a very large file could result in network saturation if |
||
| 1283 | // everyone does it at once. |
||
| 1284 | if ( $this->getSize() >= 1e7 ) { // 10MB |
||
| 1285 | $that = $this; |
||
| 1286 | $work = new PoolCounterWorkViaCallback( 'GetLocalFileCopy', sha1( $this->getName() ), |
||
| 1287 | [ |
||
| 1288 | 'doWork' => function () use ( $that ) { |
||
| 1289 | return $that->getLocalRefPath(); |
||
| 1290 | } |
||
| 1291 | ] |
||
| 1292 | ); |
||
| 1293 | $srcPath = $work->execute(); |
||
| 1294 | } else { |
||
| 1295 | $srcPath = $this->getLocalRefPath(); |
||
| 1296 | } |
||
| 1297 | |||
| 1298 | // Original file |
||
| 1299 | return [ |
||
| 1300 | 'path' => $srcPath, |
||
| 1301 | 'width' => $this->getWidth(), |
||
| 1302 | 'height' => $this->getHeight() |
||
| 1303 | ]; |
||
| 1304 | } |
||
| 1305 | |||
| 1306 | /** |
||
| 1307 | * Returns the repo path of the thumb for a given bucket |
||
| 1308 | * @param int $bucket |
||
| 1309 | * @return string |
||
| 1310 | */ |
||
| 1311 | protected function getBucketThumbPath( $bucket ) { |
||
| 1315 | |||
| 1316 | /** |
||
| 1317 | * Returns the name of the thumb for a given bucket |
||
| 1318 | * @param int $bucket |
||
| 1319 | * @return string |
||
| 1320 | */ |
||
| 1321 | protected function getBucketThumbName( $bucket ) { |
||
| 1324 | |||
| 1325 | /** |
||
| 1326 | * Creates a temp FS file with the same extension and the thumbnail |
||
| 1327 | * @param string $thumbPath Thumbnail path |
||
| 1328 | * @return TempFSFile |
||
| 1329 | */ |
||
| 1330 | protected function makeTransformTmpFile( $thumbPath ) { |
||
| 1334 | |||
| 1335 | /** |
||
| 1336 | * @param string $thumbName Thumbnail name |
||
| 1337 | * @param string $dispositionType Type of disposition (either "attachment" or "inline") |
||
| 1338 | * @return string Content-Disposition header value |
||
| 1339 | */ |
||
| 1340 | function getThumbDisposition( $thumbName, $dispositionType = 'inline' ) { |
||
| 1349 | |||
| 1350 | /** |
||
| 1351 | * Hook into transform() to allow migration of thumbnail files |
||
| 1352 | * STUB |
||
| 1353 | * Overridden by LocalFile |
||
| 1354 | * @param string $thumbName |
||
| 1355 | */ |
||
| 1356 | function migrateThumbFile( $thumbName ) { |
||
| 1358 | |||
| 1359 | /** |
||
| 1360 | * Get a MediaHandler instance for this file |
||
| 1361 | * |
||
| 1362 | * @return MediaHandler|bool Registered MediaHandler for file's MIME type |
||
| 1363 | * or false if none found |
||
| 1364 | */ |
||
| 1365 | function getHandler() { |
||
| 1372 | |||
| 1373 | /** |
||
| 1374 | * Get a ThumbnailImage representing a file type icon |
||
| 1375 | * |
||
| 1376 | * @return ThumbnailImage |
||
| 1377 | */ |
||
| 1378 | function iconThumb() { |
||
| 1394 | |||
| 1395 | /** |
||
| 1396 | * Get last thumbnailing error. |
||
| 1397 | * Largely obsolete. |
||
| 1398 | * @return string |
||
| 1399 | */ |
||
| 1400 | function getLastError() { |
||
| 1403 | |||
| 1404 | /** |
||
| 1405 | * Get all thumbnail names previously generated for this file |
||
| 1406 | * STUB |
||
| 1407 | * Overridden by LocalFile |
||
| 1408 | * @return array |
||
| 1409 | */ |
||
| 1410 | function getThumbnails() { |
||
| 1413 | |||
| 1414 | /** |
||
| 1415 | * Purge shared caches such as thumbnails and DB data caching |
||
| 1416 | * STUB |
||
| 1417 | * Overridden by LocalFile |
||
| 1418 | * @param array $options Options, which include: |
||
| 1419 | * 'forThumbRefresh' : The purging is only to refresh thumbnails |
||
| 1420 | */ |
||
| 1421 | function purgeCache( $options = [] ) { |
||
| 1423 | |||
| 1424 | /** |
||
| 1425 | * Purge the file description page, but don't go after |
||
| 1426 | * pages using the file. Use when modifying file history |
||
| 1427 | * but not the current data. |
||
| 1428 | */ |
||
| 1429 | function purgeDescription() { |
||
| 1436 | |||
| 1437 | /** |
||
| 1438 | * Purge metadata and all affected pages when the file is created, |
||
| 1439 | * deleted, or majorly updated. |
||
| 1440 | */ |
||
| 1441 | function purgeEverything() { |
||
| 1452 | |||
| 1453 | /** |
||
| 1454 | * Return a fragment of the history of file. |
||
| 1455 | * |
||
| 1456 | * STUB |
||
| 1457 | * @param int $limit Limit of rows to return |
||
| 1458 | * @param string $start Only revisions older than $start will be returned |
||
| 1459 | * @param string $end Only revisions newer than $end will be returned |
||
| 1460 | * @param bool $inc Include the endpoints of the time range |
||
| 1461 | * |
||
| 1462 | * @return File[] |
||
| 1463 | */ |
||
| 1464 | function getHistory( $limit = null, $start = null, $end = null, $inc = true ) { |
||
| 1467 | |||
| 1468 | /** |
||
| 1469 | * Return the history of this file, line by line. Starts with current version, |
||
| 1470 | * then old versions. Should return an object similar to an image/oldimage |
||
| 1471 | * database row. |
||
| 1472 | * |
||
| 1473 | * STUB |
||
| 1474 | * Overridden in LocalFile |
||
| 1475 | * @return bool |
||
| 1476 | */ |
||
| 1477 | public function nextHistoryLine() { |
||
| 1480 | |||
| 1481 | /** |
||
| 1482 | * Reset the history pointer to the first element of the history. |
||
| 1483 | * Always call this function after using nextHistoryLine() to free db resources |
||
| 1484 | * STUB |
||
| 1485 | * Overridden in LocalFile. |
||
| 1486 | */ |
||
| 1487 | public function resetHistory() { |
||
| 1489 | |||
| 1490 | /** |
||
| 1491 | * Get the filename hash component of the directory including trailing slash, |
||
| 1492 | * e.g. f/fa/ |
||
| 1493 | * If the repository is not hashed, returns an empty string. |
||
| 1494 | * |
||
| 1495 | * @return string |
||
| 1496 | */ |
||
| 1497 | function getHashPath() { |
||
| 1505 | |||
| 1506 | /** |
||
| 1507 | * Get the path of the file relative to the public zone root. |
||
| 1508 | * This function is overridden in OldLocalFile to be like getArchiveRel(). |
||
| 1509 | * |
||
| 1510 | * @return string |
||
| 1511 | */ |
||
| 1512 | function getRel() { |
||
| 1515 | |||
| 1516 | /** |
||
| 1517 | * Get the path of an archived file relative to the public zone root |
||
| 1518 | * |
||
| 1519 | * @param bool|string $suffix If not false, the name of an archived thumbnail file |
||
| 1520 | * |
||
| 1521 | * @return string |
||
| 1522 | */ |
||
| 1523 | View Code Duplication | function getArchiveRel( $suffix = false ) { |
|
| 1533 | |||
| 1534 | /** |
||
| 1535 | * Get the path, relative to the thumbnail zone root, of the |
||
| 1536 | * thumbnail directory or a particular file if $suffix is specified |
||
| 1537 | * |
||
| 1538 | * @param bool|string $suffix If not false, the name of a thumbnail file |
||
| 1539 | * @return string |
||
| 1540 | */ |
||
| 1541 | function getThumbRel( $suffix = false ) { |
||
| 1549 | |||
| 1550 | /** |
||
| 1551 | * Get urlencoded path of the file relative to the public zone root. |
||
| 1552 | * This function is overridden in OldLocalFile to be like getArchiveUrl(). |
||
| 1553 | * |
||
| 1554 | * @return string |
||
| 1555 | */ |
||
| 1556 | function getUrlRel() { |
||
| 1559 | |||
| 1560 | /** |
||
| 1561 | * Get the path, relative to the thumbnail zone root, for an archived file's thumbs directory |
||
| 1562 | * or a specific thumb if the $suffix is given. |
||
| 1563 | * |
||
| 1564 | * @param string $archiveName The timestamped name of an archived image |
||
| 1565 | * @param bool|string $suffix If not false, the name of a thumbnail file |
||
| 1566 | * @return string |
||
| 1567 | */ |
||
| 1568 | View Code Duplication | function getArchiveThumbRel( $archiveName, $suffix = false ) { |
|
| 1578 | |||
| 1579 | /** |
||
| 1580 | * Get the path of the archived file. |
||
| 1581 | * |
||
| 1582 | * @param bool|string $suffix If not false, the name of an archived file. |
||
| 1583 | * @return string |
||
| 1584 | */ |
||
| 1585 | function getArchivePath( $suffix = false ) { |
||
| 1590 | |||
| 1591 | /** |
||
| 1592 | * Get the path of an archived file's thumbs, or a particular thumb if $suffix is specified |
||
| 1593 | * |
||
| 1594 | * @param string $archiveName The timestamped name of an archived image |
||
| 1595 | * @param bool|string $suffix If not false, the name of a thumbnail file |
||
| 1596 | * @return string |
||
| 1597 | */ |
||
| 1598 | function getArchiveThumbPath( $archiveName, $suffix = false ) { |
||
| 1604 | |||
| 1605 | /** |
||
| 1606 | * Get the path of the thumbnail directory, or a particular file if $suffix is specified |
||
| 1607 | * |
||
| 1608 | * @param bool|string $suffix If not false, the name of a thumbnail file |
||
| 1609 | * @return string |
||
| 1610 | */ |
||
| 1611 | function getThumbPath( $suffix = false ) { |
||
| 1616 | |||
| 1617 | /** |
||
| 1618 | * Get the path of the transcoded directory, or a particular file if $suffix is specified |
||
| 1619 | * |
||
| 1620 | * @param bool|string $suffix If not false, the name of a media file |
||
| 1621 | * @return string |
||
| 1622 | */ |
||
| 1623 | function getTranscodedPath( $suffix = false ) { |
||
| 1628 | |||
| 1629 | /** |
||
| 1630 | * Get the URL of the archive directory, or a particular file if $suffix is specified |
||
| 1631 | * |
||
| 1632 | * @param bool|string $suffix If not false, the name of an archived file |
||
| 1633 | * @return string |
||
| 1634 | */ |
||
| 1635 | View Code Duplication | function getArchiveUrl( $suffix = false ) { |
|
| 1647 | |||
| 1648 | /** |
||
| 1649 | * Get the URL of the archived file's thumbs, or a particular thumb if $suffix is specified |
||
| 1650 | * |
||
| 1651 | * @param string $archiveName The timestamped name of an archived image |
||
| 1652 | * @param bool|string $suffix If not false, the name of a thumbnail file |
||
| 1653 | * @return string |
||
| 1654 | */ |
||
| 1655 | View Code Duplication | function getArchiveThumbUrl( $archiveName, $suffix = false ) { |
|
| 1668 | |||
| 1669 | /** |
||
| 1670 | * Get the URL of the zone directory, or a particular file if $suffix is specified |
||
| 1671 | * |
||
| 1672 | * @param string $zone Name of requested zone |
||
| 1673 | * @param bool|string $suffix If not false, the name of a file in zone |
||
| 1674 | * @return string Path |
||
| 1675 | */ |
||
| 1676 | function getZoneUrl( $zone, $suffix = false ) { |
||
| 1686 | |||
| 1687 | /** |
||
| 1688 | * Get the URL of the thumbnail directory, or a particular file if $suffix is specified |
||
| 1689 | * |
||
| 1690 | * @param bool|string $suffix If not false, the name of a thumbnail file |
||
| 1691 | * @return string Path |
||
| 1692 | */ |
||
| 1693 | function getThumbUrl( $suffix = false ) { |
||
| 1696 | |||
| 1697 | /** |
||
| 1698 | * Get the URL of the transcoded directory, or a particular file if $suffix is specified |
||
| 1699 | * |
||
| 1700 | * @param bool|string $suffix If not false, the name of a media file |
||
| 1701 | * @return string Path |
||
| 1702 | */ |
||
| 1703 | function getTranscodedUrl( $suffix = false ) { |
||
| 1706 | |||
| 1707 | /** |
||
| 1708 | * Get the public zone virtual URL for a current version source file |
||
| 1709 | * |
||
| 1710 | * @param bool|string $suffix If not false, the name of a thumbnail file |
||
| 1711 | * @return string |
||
| 1712 | */ |
||
| 1713 | View Code Duplication | function getVirtualUrl( $suffix = false ) { |
|
| 1722 | |||
| 1723 | /** |
||
| 1724 | * Get the public zone virtual URL for an archived version source file |
||
| 1725 | * |
||
| 1726 | * @param bool|string $suffix If not false, the name of a thumbnail file |
||
| 1727 | * @return string |
||
| 1728 | */ |
||
| 1729 | View Code Duplication | function getArchiveVirtualUrl( $suffix = false ) { |
|
| 1740 | |||
| 1741 | /** |
||
| 1742 | * Get the virtual URL for a thumbnail file or directory |
||
| 1743 | * |
||
| 1744 | * @param bool|string $suffix If not false, the name of a thumbnail file |
||
| 1745 | * @return string |
||
| 1746 | */ |
||
| 1747 | View Code Duplication | function getThumbVirtualUrl( $suffix = false ) { |
|
| 1756 | |||
| 1757 | /** |
||
| 1758 | * @return bool |
||
| 1759 | */ |
||
| 1760 | function isHashed() { |
||
| 1765 | |||
| 1766 | /** |
||
| 1767 | * @throws MWException |
||
| 1768 | */ |
||
| 1769 | function readOnlyError() { |
||
| 1772 | |||
| 1773 | /** |
||
| 1774 | * Record a file upload in the upload log and the image table |
||
| 1775 | * STUB |
||
| 1776 | * Overridden by LocalFile |
||
| 1777 | * @param string $oldver |
||
| 1778 | * @param string $desc |
||
| 1779 | * @param string $license |
||
| 1780 | * @param string $copyStatus |
||
| 1781 | * @param string $source |
||
| 1782 | * @param bool $watch |
||
| 1783 | * @param string|bool $timestamp |
||
| 1784 | * @param null|User $user User object or null to use $wgUser |
||
| 1785 | * @return bool |
||
| 1786 | * @throws MWException |
||
| 1787 | */ |
||
| 1788 | function recordUpload( $oldver, $desc, $license = '', $copyStatus = '', $source = '', |
||
| 1793 | |||
| 1794 | /** |
||
| 1795 | * Move or copy a file to its public location. If a file exists at the |
||
| 1796 | * destination, move it to an archive. Returns a FileRepoStatus object with |
||
| 1797 | * the archive name in the "value" member on success. |
||
| 1798 | * |
||
| 1799 | * The archive name should be passed through to recordUpload for database |
||
| 1800 | * registration. |
||
| 1801 | * |
||
| 1802 | * Options to $options include: |
||
| 1803 | * - headers : name/value map of HTTP headers to use in response to GET/HEAD requests |
||
| 1804 | * |
||
| 1805 | * @param string|FSFile $src Local filesystem path to the source image |
||
| 1806 | * @param int $flags A bitwise combination of: |
||
| 1807 | * File::DELETE_SOURCE Delete the source file, i.e. move rather than copy |
||
| 1808 | * @param array $options Optional additional parameters |
||
| 1809 | * @return FileRepoStatus On success, the value member contains the |
||
| 1810 | * archive name, or an empty string if it was a new file. |
||
| 1811 | * |
||
| 1812 | * STUB |
||
| 1813 | * Overridden by LocalFile |
||
| 1814 | */ |
||
| 1815 | function publish( $src, $flags = 0, array $options = [] ) { |
||
| 1818 | |||
| 1819 | /** |
||
| 1820 | * @param bool|IContextSource $context Context to use (optional) |
||
| 1821 | * @return bool |
||
| 1822 | */ |
||
| 1823 | function formatMetadata( $context = false ) { |
||
| 1830 | |||
| 1831 | /** |
||
| 1832 | * Returns true if the file comes from the local file repository. |
||
| 1833 | * |
||
| 1834 | * @return bool |
||
| 1835 | */ |
||
| 1836 | function isLocal() { |
||
| 1839 | |||
| 1840 | /** |
||
| 1841 | * Returns the name of the repository. |
||
| 1842 | * |
||
| 1843 | * @return string |
||
| 1844 | */ |
||
| 1845 | function getRepoName() { |
||
| 1848 | |||
| 1849 | /** |
||
| 1850 | * Returns the repository |
||
| 1851 | * |
||
| 1852 | * @return FileRepo|LocalRepo|bool |
||
| 1853 | */ |
||
| 1854 | function getRepo() { |
||
| 1857 | |||
| 1858 | /** |
||
| 1859 | * Returns true if the image is an old version |
||
| 1860 | * STUB |
||
| 1861 | * |
||
| 1862 | * @return bool |
||
| 1863 | */ |
||
| 1864 | function isOld() { |
||
| 1867 | |||
| 1868 | /** |
||
| 1869 | * Is this file a "deleted" file in a private archive? |
||
| 1870 | * STUB |
||
| 1871 | * |
||
| 1872 | * @param int $field One of DELETED_* bitfield constants |
||
| 1873 | * @return bool |
||
| 1874 | */ |
||
| 1875 | function isDeleted( $field ) { |
||
| 1878 | |||
| 1879 | /** |
||
| 1880 | * Return the deletion bitfield |
||
| 1881 | * STUB |
||
| 1882 | * @return int |
||
| 1883 | */ |
||
| 1884 | function getVisibility() { |
||
| 1887 | |||
| 1888 | /** |
||
| 1889 | * Was this file ever deleted from the wiki? |
||
| 1890 | * |
||
| 1891 | * @return bool |
||
| 1892 | */ |
||
| 1893 | function wasDeleted() { |
||
| 1898 | |||
| 1899 | /** |
||
| 1900 | * Move file to the new title |
||
| 1901 | * |
||
| 1902 | * Move current, old version and all thumbnails |
||
| 1903 | * to the new filename. Old file is deleted. |
||
| 1904 | * |
||
| 1905 | * Cache purging is done; checks for validity |
||
| 1906 | * and logging are caller's responsibility |
||
| 1907 | * |
||
| 1908 | * @param Title $target New file name |
||
| 1909 | * @return FileRepoStatus |
||
| 1910 | */ |
||
| 1911 | function move( $target ) { |
||
| 1914 | |||
| 1915 | /** |
||
| 1916 | * Delete all versions of the file. |
||
| 1917 | * |
||
| 1918 | * Moves the files into an archive directory (or deletes them) |
||
| 1919 | * and removes the database rows. |
||
| 1920 | * |
||
| 1921 | * Cache purging is done; logging is caller's responsibility. |
||
| 1922 | * |
||
| 1923 | * @param string $reason |
||
| 1924 | * @param bool $suppress Hide content from sysops? |
||
| 1925 | * @param User|null $user |
||
| 1926 | * @return FileRepoStatus |
||
| 1927 | * STUB |
||
| 1928 | * Overridden by LocalFile |
||
| 1929 | */ |
||
| 1930 | function delete( $reason, $suppress = false, $user = null ) { |
||
| 1933 | |||
| 1934 | /** |
||
| 1935 | * Restore all or specified deleted revisions to the given file. |
||
| 1936 | * Permissions and logging are left to the caller. |
||
| 1937 | * |
||
| 1938 | * May throw database exceptions on error. |
||
| 1939 | * |
||
| 1940 | * @param array $versions Set of record ids of deleted items to restore, |
||
| 1941 | * or empty to restore all revisions. |
||
| 1942 | * @param bool $unsuppress Remove restrictions on content upon restoration? |
||
| 1943 | * @return int|bool The number of file revisions restored if successful, |
||
| 1944 | * or false on failure |
||
| 1945 | * STUB |
||
| 1946 | * Overridden by LocalFile |
||
| 1947 | */ |
||
| 1948 | function restore( $versions = [], $unsuppress = false ) { |
||
| 1951 | |||
| 1952 | /** |
||
| 1953 | * Returns 'true' if this file is a type which supports multiple pages, |
||
| 1954 | * e.g. DJVU or PDF. Note that this may be true even if the file in |
||
| 1955 | * question only has a single page. |
||
| 1956 | * |
||
| 1957 | * @return bool |
||
| 1958 | */ |
||
| 1959 | function isMultipage() { |
||
| 1962 | |||
| 1963 | /** |
||
| 1964 | * Returns the number of pages of a multipage document, or false for |
||
| 1965 | * documents which aren't multipage documents |
||
| 1966 | * |
||
| 1967 | * @return bool|int |
||
| 1968 | */ |
||
| 1969 | View Code Duplication | function pageCount() { |
|
| 1980 | |||
| 1981 | /** |
||
| 1982 | * Calculate the height of a thumbnail using the source and destination width |
||
| 1983 | * |
||
| 1984 | * @param int $srcWidth |
||
| 1985 | * @param int $srcHeight |
||
| 1986 | * @param int $dstWidth |
||
| 1987 | * |
||
| 1988 | * @return int |
||
| 1989 | */ |
||
| 1990 | static function scaleHeight( $srcWidth, $srcHeight, $dstWidth ) { |
||
| 1998 | |||
| 1999 | /** |
||
| 2000 | * Get an image size array like that returned by getImageSize(), or false if it |
||
| 2001 | * can't be determined. Loads the image size directly from the file ignoring caches. |
||
| 2002 | * |
||
| 2003 | * @note Use getWidth()/getHeight() instead of this method unless you have a |
||
| 2004 | * a good reason. This method skips all caches. |
||
| 2005 | * |
||
| 2006 | * @param string $filePath The path to the file (e.g. From getLocalPathRef() ) |
||
| 2007 | * @return array The width, followed by height, with optionally more things after |
||
| 2008 | */ |
||
| 2009 | function getImageSize( $filePath ) { |
||
| 2016 | |||
| 2017 | /** |
||
| 2018 | * Get the URL of the image description page. May return false if it is |
||
| 2019 | * unknown or not applicable. |
||
| 2020 | * |
||
| 2021 | * @return string |
||
| 2022 | */ |
||
| 2023 | function getDescriptionUrl() { |
||
| 2030 | |||
| 2031 | /** |
||
| 2032 | * Get the HTML text of the description page, if available |
||
| 2033 | * |
||
| 2034 | * @param bool|Language $lang Optional language to fetch description in |
||
| 2035 | * @return string |
||
| 2036 | */ |
||
| 2037 | function getDescriptionText( $lang = false ) { |
||
| 2038 | global $wgLang; |
||
| 2039 | |||
| 2040 | if ( !$this->repo || !$this->repo->fetchDescription ) { |
||
| 2041 | return false; |
||
| 2042 | } |
||
| 2043 | |||
| 2044 | $lang = $lang ?: $wgLang; |
||
| 2045 | |||
| 2046 | $renderUrl = $this->repo->getDescriptionRenderUrl( $this->getName(), $lang->getCode() ); |
||
| 2047 | if ( $renderUrl ) { |
||
| 2048 | $cache = ObjectCache::getMainWANInstance(); |
||
| 2049 | $key = $this->repo->getLocalCacheKey( |
||
| 2050 | 'RemoteFileDescription', |
||
| 2051 | 'url', |
||
| 2052 | $lang->getCode(), |
||
| 2053 | $this->getName() |
||
| 2054 | ); |
||
| 2055 | |||
| 2056 | return $cache->getWithSetCallback( |
||
| 2057 | $key, |
||
| 2058 | $this->repo->descriptionCacheExpiry ?: $cache::TTL_UNCACHEABLE, |
||
| 2059 | View Code Duplication | function ( $oldValue, &$ttl, array &$setOpts ) use ( $renderUrl ) { |
|
| 2060 | wfDebug( "Fetching shared description from $renderUrl\n" ); |
||
| 2061 | $res = Http::get( $renderUrl, [], __METHOD__ ); |
||
| 2062 | if ( !$res ) { |
||
| 2063 | $ttl = WANObjectCache::TTL_UNCACHEABLE; |
||
| 2064 | } |
||
| 2065 | |||
| 2066 | return $res; |
||
| 2067 | } |
||
| 2068 | ); |
||
| 2069 | } |
||
| 2070 | |||
| 2071 | return false; |
||
| 2072 | } |
||
| 2073 | |||
| 2074 | /** |
||
| 2075 | * Get description of file revision |
||
| 2076 | * STUB |
||
| 2077 | * |
||
| 2078 | * @param int $audience One of: |
||
| 2079 | * File::FOR_PUBLIC to be displayed to all users |
||
| 2080 | * File::FOR_THIS_USER to be displayed to the given user |
||
| 2081 | * File::RAW get the description regardless of permissions |
||
| 2082 | * @param User $user User object to check for, only if FOR_THIS_USER is |
||
| 2083 | * passed to the $audience parameter |
||
| 2084 | * @return string |
||
| 2085 | */ |
||
| 2086 | function getDescription( $audience = self::FOR_PUBLIC, User $user = null ) { |
||
| 2089 | |||
| 2090 | /** |
||
| 2091 | * Get the 14-character timestamp of the file upload |
||
| 2092 | * |
||
| 2093 | * @return string|bool TS_MW timestamp or false on failure |
||
| 2094 | */ |
||
| 2095 | function getTimestamp() { |
||
| 2100 | |||
| 2101 | /** |
||
| 2102 | * Returns the timestamp (in TS_MW format) of the last change of the description page. |
||
| 2103 | * Returns false if the file does not have a description page, or retrieving the timestamp |
||
| 2104 | * would be expensive. |
||
| 2105 | * @since 1.25 |
||
| 2106 | * @return string|bool |
||
| 2107 | */ |
||
| 2108 | public function getDescriptionTouched() { |
||
| 2111 | |||
| 2112 | /** |
||
| 2113 | * Get the SHA-1 base 36 hash of the file |
||
| 2114 | * |
||
| 2115 | * @return string |
||
| 2116 | */ |
||
| 2117 | function getSha1() { |
||
| 2122 | |||
| 2123 | /** |
||
| 2124 | * Get the deletion archive key, "<sha1>.<ext>" |
||
| 2125 | * |
||
| 2126 | * @return string |
||
| 2127 | */ |
||
| 2128 | function getStorageKey() { |
||
| 2138 | |||
| 2139 | /** |
||
| 2140 | * Determine if the current user is allowed to view a particular |
||
| 2141 | * field of this file, if it's marked as deleted. |
||
| 2142 | * STUB |
||
| 2143 | * @param int $field |
||
| 2144 | * @param User $user User object to check, or null to use $wgUser |
||
| 2145 | * @return bool |
||
| 2146 | */ |
||
| 2147 | function userCan( $field, User $user = null ) { |
||
| 2150 | |||
| 2151 | /** |
||
| 2152 | * @return array HTTP header name/value map to use for HEAD/GET request responses |
||
| 2153 | */ |
||
| 2154 | function getStreamHeaders() { |
||
| 2162 | |||
| 2163 | /** |
||
| 2164 | * @return string |
||
| 2165 | */ |
||
| 2166 | function getLongDesc() { |
||
| 2174 | |||
| 2175 | /** |
||
| 2176 | * @return string |
||
| 2177 | */ |
||
| 2178 | function getShortDesc() { |
||
| 2186 | |||
| 2187 | /** |
||
| 2188 | * @return string |
||
| 2189 | */ |
||
| 2190 | function getDimensionsString() { |
||
| 2198 | |||
| 2199 | /** |
||
| 2200 | * @return string |
||
| 2201 | */ |
||
| 2202 | function getRedirected() { |
||
| 2205 | |||
| 2206 | /** |
||
| 2207 | * @return Title|null |
||
| 2208 | */ |
||
| 2209 | function getRedirectedTitle() { |
||
| 2220 | |||
| 2221 | /** |
||
| 2222 | * @param string $from |
||
| 2223 | * @return void |
||
| 2224 | */ |
||
| 2225 | function redirectedFrom( $from ) { |
||
| 2228 | |||
| 2229 | /** |
||
| 2230 | * @return bool |
||
| 2231 | */ |
||
| 2232 | function isMissing() { |
||
| 2235 | |||
| 2236 | /** |
||
| 2237 | * Check if this file object is small and can be cached |
||
| 2238 | * @return bool |
||
| 2239 | */ |
||
| 2240 | public function isCacheable() { |
||
| 2243 | |||
| 2244 | /** |
||
| 2245 | * Assert that $this->repo is set to a valid FileRepo instance |
||
| 2246 | * @throws MWException |
||
| 2247 | */ |
||
| 2248 | protected function assertRepoDefined() { |
||
| 2253 | |||
| 2254 | /** |
||
| 2255 | * Assert that $this->title is set to a Title |
||
| 2256 | * @throws MWException |
||
| 2257 | */ |
||
| 2258 | protected function assertTitleDefined() { |
||
| 2263 | |||
| 2264 | /** |
||
| 2265 | * True if creating thumbnails from the file is large or otherwise resource-intensive. |
||
| 2266 | * @return bool |
||
| 2267 | */ |
||
| 2268 | public function isExpensiveToThumbnail() { |
||
| 2272 | |||
| 2273 | /** |
||
| 2274 | * Whether the thumbnails created on the same server as this code is running. |
||
| 2275 | * @since 1.25 |
||
| 2276 | * @return bool |
||
| 2277 | */ |
||
| 2278 | public function isTransformedLocally() { |
||
| 2281 | } |
||
| 2282 |
This check looks for assignments to scalar types that may be of the wrong type.
To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.