[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/upload/ -> UploadStash.php (source)

   1  <?php
   2  /**
   3   * Temporary storage for uploaded files.
   4   *
   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.
   9   *
  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.
  14   *
  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
  19   *
  20   * @file
  21   * @ingroup Upload
  22   */
  23  
  24  /**
  25   * UploadStash is intended to accomplish a few things:
  26   *   - Enable applications to temporarily stash files without publishing them to
  27   *     the wiki.
  28   *      - Several parts of MediaWiki do this in similar ways: UploadBase,
  29   *        UploadWizard, and FirefoggChunkedExtension.
  30   *        And there are several that reimplement stashing from scratch, in
  31   *        idiosyncratic ways. The idea is to unify them all here.
  32   *        Mostly all of them are the same except for storing some custom fields,
  33   *        which we subsume into the data array.
  34   *   - Enable applications to find said files later, as long as the db table or
  35   *     temp files haven't been purged.
  36   *   - Enable the uploading user (and *ONLY* the uploading user) to access said
  37   *     files, and thumbnails of said files, via a URL. We accomplish this using
  38   *     a database table, with ownership checking as you might expect. See
  39   *     SpecialUploadStash, which implements a web interface to some files stored
  40   *     this way.
  41   *
  42   * UploadStash right now is *mostly* intended to show you one user's slice of
  43   * the entire stash. The user parameter is only optional because there are few
  44   * cases where we clean out the stash from an automated script. In the future we
  45   * might refactor this.
  46   *
  47   * UploadStash represents the entire stash of temporary files.
  48   * UploadStashFile is a filestore for the actual physical disk files.
  49   * UploadFromStash extends UploadBase, and represents a single stashed file as
  50   * it is moved from the stash to the regular file repository
  51   *
  52   * @ingroup Upload
  53   */
  54  class UploadStash {
  55      // Format of the key for files -- has to be suitable as a filename itself (e.g. ab12cd34ef.jpg)
  56      const KEY_FORMAT_REGEX = '/^[\w-\.]+\.\w*$/';
  57  
  58      /**
  59       * repository that this uses to store temp files
  60       * public because we sometimes need to get a LocalFile within the same repo.
  61       *
  62       * @var LocalRepo
  63       */
  64      public $repo;
  65  
  66      // array of initialized repo objects
  67      protected $files = array();
  68  
  69      // cache of the file metadata that's stored in the database
  70      protected $fileMetadata = array();
  71  
  72      // fileprops cache
  73      protected $fileProps = array();
  74  
  75      // current user
  76      protected $user, $userId, $isLoggedIn;
  77  
  78      /**
  79       * Represents a temporary filestore, with metadata in the database.
  80       * Designed to be compatible with the session stashing code in UploadBase
  81       * (should replace it eventually).
  82       *
  83       * @param FileRepo $repo
  84       * @param User $user (default null)
  85       */
  86  	public function __construct( FileRepo $repo, $user = null ) {
  87          // this might change based on wiki's configuration.
  88          $this->repo = $repo;
  89  
  90          // if a user was passed, use it. otherwise, attempt to use the global.
  91          // this keeps FileRepo from breaking when it creates an UploadStash object
  92          if ( $user ) {
  93              $this->user = $user;
  94          } else {
  95              global $wgUser;
  96              $this->user = $wgUser;
  97          }
  98  
  99          if ( is_object( $this->user ) ) {
 100              $this->userId = $this->user->getId();
 101              $this->isLoggedIn = $this->user->isLoggedIn();
 102          }
 103      }
 104  
 105      /**
 106       * Get a file and its metadata from the stash.
 107       * The noAuth param is a bit janky but is required for automated scripts
 108       * which clean out the stash.
 109       *
 110       * @param string $key Key under which file information is stored
 111       * @param bool $noAuth (optional) Don't check authentication. Used by maintenance scripts.
 112       * @throws UploadStashFileNotFoundException
 113       * @throws UploadStashNotLoggedInException
 114       * @throws UploadStashWrongOwnerException
 115       * @throws UploadStashBadPathException
 116       * @return UploadStashFile
 117       */
 118  	public function getFile( $key, $noAuth = false ) {
 119          if ( !preg_match( self::KEY_FORMAT_REGEX, $key ) ) {
 120              throw new UploadStashBadPathException( "key '$key' is not in a proper format" );
 121          }
 122  
 123          if ( !$noAuth && !$this->isLoggedIn ) {
 124              throw new UploadStashNotLoggedInException( __METHOD__ .
 125                  ' No user is logged in, files must belong to users' );
 126          }
 127  
 128          if ( !isset( $this->fileMetadata[$key] ) ) {
 129              if ( !$this->fetchFileMetadata( $key ) ) {
 130                  // If nothing was received, it's likely due to replication lag.
 131                  // Check the master to see if the record is there.
 132                  $this->fetchFileMetadata( $key, DB_MASTER );
 133              }
 134  
 135              if ( !isset( $this->fileMetadata[$key] ) ) {
 136                  throw new UploadStashFileNotFoundException( "key '$key' not found in stash" );
 137              }
 138  
 139              // create $this->files[$key]
 140              $this->initFile( $key );
 141  
 142              // fetch fileprops
 143              if ( strlen( $this->fileMetadata[$key]['us_props'] ) ) {
 144                  $this->fileProps[$key] = unserialize( $this->fileMetadata[$key]['us_props'] );
 145              } else { // b/c for rows with no us_props
 146                  wfDebug( __METHOD__ . " fetched props for $key from file\n" );
 147                  $path = $this->fileMetadata[$key]['us_path'];
 148                  $this->fileProps[$key] = $this->repo->getFileProps( $path );
 149              }
 150          }
 151  
 152          if ( !$this->files[$key]->exists() ) {
 153              wfDebug( __METHOD__ . " tried to get file at $key, but it doesn't exist\n" );
 154              throw new UploadStashBadPathException( "path doesn't exist" );
 155          }
 156  
 157          if ( !$noAuth ) {
 158              if ( $this->fileMetadata[$key]['us_user'] != $this->userId ) {
 159                  throw new UploadStashWrongOwnerException( "This file ($key) doesn't "
 160                      . "belong to the current user." );
 161              }
 162          }
 163  
 164          return $this->files[$key];
 165      }
 166  
 167      /**
 168       * Getter for file metadata.
 169       *
 170       * @param string $key Key under which file information is stored
 171       * @return array
 172       */
 173  	public function getMetadata( $key ) {
 174          $this->getFile( $key );
 175  
 176          return $this->fileMetadata[$key];
 177      }
 178  
 179      /**
 180       * Getter for fileProps
 181       *
 182       * @param string $key Key under which file information is stored
 183       * @return array
 184       */
 185  	public function getFileProps( $key ) {
 186          $this->getFile( $key );
 187  
 188          return $this->fileProps[$key];
 189      }
 190  
 191      /**
 192       * Stash a file in a temp directory and record that we did this in the
 193       * database, along with other metadata.
 194       *
 195       * @param string $path Path to file you want stashed
 196       * @param string $sourceType The type of upload that generated this file
 197       *   (currently, I believe, 'file' or null)
 198       * @throws UploadStashBadPathException
 199       * @throws UploadStashFileException
 200       * @throws UploadStashNotLoggedInException
 201       * @return UploadStashFile|null File, or null on failure
 202       */
 203  	public function stashFile( $path, $sourceType = null ) {
 204          if ( !is_file( $path ) ) {
 205              wfDebug( __METHOD__ . " tried to stash file at '$path', but it doesn't exist\n" );
 206              throw new UploadStashBadPathException( "path doesn't exist" );
 207          }
 208          $fileProps = FSFile::getPropsFromPath( $path );
 209          wfDebug( __METHOD__ . " stashing file at '$path'\n" );
 210  
 211          // we will be initializing from some tmpnam files that don't have extensions.
 212          // most of MediaWiki assumes all uploaded files have good extensions. So, we fix this.
 213          $extension = self::getExtensionForPath( $path );
 214          if ( !preg_match( "/\\.\\Q$extension\\E$/", $path ) ) {
 215              $pathWithGoodExtension = "$path.$extension";
 216          } else {
 217              $pathWithGoodExtension = $path;
 218          }
 219  
 220          // If no key was supplied, make one.  a mysql insertid would be totally
 221          // reasonable here, except that for historical reasons, the key is this
 222          // random thing instead.  At least it's not guessable.
 223          //
 224          // Some things that when combined will make a suitably unique key.
 225          // see: http://www.jwz.org/doc/mid.html
 226          list( $usec, $sec ) = explode( ' ', microtime() );
 227          $usec = substr( $usec, 2 );
 228          $key = wfBaseConvert( $sec . $usec, 10, 36 ) . '.' .
 229              wfBaseConvert( mt_rand(), 10, 36 ) . '.' .
 230              $this->userId . '.' .
 231              $extension;
 232  
 233          $this->fileProps[$key] = $fileProps;
 234  
 235          if ( !preg_match( self::KEY_FORMAT_REGEX, $key ) ) {
 236              throw new UploadStashBadPathException( "key '$key' is not in a proper format" );
 237          }
 238  
 239          wfDebug( __METHOD__ . " key for '$path': $key\n" );
 240  
 241          // if not already in a temporary area, put it there
 242          $storeStatus = $this->repo->storeTemp( basename( $pathWithGoodExtension ), $path );
 243  
 244          if ( !$storeStatus->isOK() ) {
 245              // It is a convention in MediaWiki to only return one error per API
 246              // exception, even if multiple errors are available. We use reset()
 247              // to pick the "first" thing that was wrong, preferring errors to
 248              // warnings. This is a bit lame, as we may have more info in the
 249              // $storeStatus and we're throwing it away, but to fix it means
 250              // redesigning API errors significantly.
 251              // $storeStatus->value just contains the virtual URL (if anything)
 252              // which is probably useless to the caller.
 253              $error = $storeStatus->getErrorsArray();
 254              $error = reset( $error );
 255              if ( !count( $error ) ) {
 256                  $error = $storeStatus->getWarningsArray();
 257                  $error = reset( $error );
 258                  if ( !count( $error ) ) {
 259                      $error = array( 'unknown', 'no error recorded' );
 260                  }
 261              }
 262              // At this point, $error should contain the single "most important"
 263              // error, plus any parameters.
 264              $errorMsg = array_shift( $error );
 265              throw new UploadStashFileException( "Error storing file in '$path': "
 266                  . wfMessage( $errorMsg, $error )->text() );
 267          }
 268          $stashPath = $storeStatus->value;
 269  
 270          // fetch the current user ID
 271          if ( !$this->isLoggedIn ) {
 272              throw new UploadStashNotLoggedInException( __METHOD__
 273                  . ' No user is logged in, files must belong to users' );
 274          }
 275  
 276          // insert the file metadata into the db.
 277          wfDebug( __METHOD__ . " inserting $stashPath under $key\n" );
 278          $dbw = $this->repo->getMasterDb();
 279  
 280          $this->fileMetadata[$key] = array(
 281              'us_id' => $dbw->nextSequenceValue( 'uploadstash_us_id_seq' ),
 282              'us_user' => $this->userId,
 283              'us_key' => $key,
 284              'us_orig_path' => $path,
 285              'us_path' => $stashPath, // virtual URL
 286              'us_props' => $dbw->encodeBlob( serialize( $fileProps ) ),
 287              'us_size' => $fileProps['size'],
 288              'us_sha1' => $fileProps['sha1'],
 289              'us_mime' => $fileProps['mime'],
 290              'us_media_type' => $fileProps['media_type'],
 291              'us_image_width' => $fileProps['width'],
 292              'us_image_height' => $fileProps['height'],
 293              'us_image_bits' => $fileProps['bits'],
 294              'us_source_type' => $sourceType,
 295              'us_timestamp' => $dbw->timestamp(),
 296              'us_status' => 'finished'
 297          );
 298  
 299          $dbw->insert(
 300              'uploadstash',
 301              $this->fileMetadata[$key],
 302              __METHOD__
 303          );
 304  
 305          // store the insertid in the class variable so immediate retrieval
 306          // (possibly laggy) isn't necesary.
 307          $this->fileMetadata[$key]['us_id'] = $dbw->insertId();
 308  
 309          # create the UploadStashFile object for this file.
 310          $this->initFile( $key );
 311  
 312          return $this->getFile( $key );
 313      }
 314  
 315      /**
 316       * Remove all files from the stash.
 317       * Does not clean up files in the repo, just the record of them.
 318       *
 319       * @throws UploadStashNotLoggedInException
 320       * @return bool Success
 321       */
 322  	public function clear() {
 323          if ( !$this->isLoggedIn ) {
 324              throw new UploadStashNotLoggedInException( __METHOD__
 325                  . ' No user is logged in, files must belong to users' );
 326          }
 327  
 328          wfDebug( __METHOD__ . ' clearing all rows for user ' . $this->userId . "\n" );
 329          $dbw = $this->repo->getMasterDb();
 330          $dbw->delete(
 331              'uploadstash',
 332              array( 'us_user' => $this->userId ),
 333              __METHOD__
 334          );
 335  
 336          # destroy objects.
 337          $this->files = array();
 338          $this->fileMetadata = array();
 339  
 340          return true;
 341      }
 342  
 343      /**
 344       * Remove a particular file from the stash.  Also removes it from the repo.
 345       *
 346       * @param string $key
 347       * @throws UploadStashNoSuchKeyException|UploadStashNotLoggedInException
 348       * @throws UploadStashWrongOwnerException
 349       * @return bool Success
 350       */
 351  	public function removeFile( $key ) {
 352          if ( !$this->isLoggedIn ) {
 353              throw new UploadStashNotLoggedInException( __METHOD__
 354                  . ' No user is logged in, files must belong to users' );
 355          }
 356  
 357          $dbw = $this->repo->getMasterDb();
 358  
 359          // this is a cheap query. it runs on the master so that this function
 360          // still works when there's lag. It won't be called all that often.
 361          $row = $dbw->selectRow(
 362              'uploadstash',
 363              'us_user',
 364              array( 'us_key' => $key ),
 365              __METHOD__
 366          );
 367  
 368          if ( !$row ) {
 369              throw new UploadStashNoSuchKeyException( "No such key ($key), cannot remove" );
 370          }
 371  
 372          if ( $row->us_user != $this->userId ) {
 373              throw new UploadStashWrongOwnerException( "Can't delete: "
 374                  . "the file ($key) doesn't belong to this user." );
 375          }
 376  
 377          return $this->removeFileNoAuth( $key );
 378      }
 379  
 380      /**
 381       * Remove a file (see removeFile), but doesn't check ownership first.
 382       *
 383       * @param string $key
 384       * @return bool Success
 385       */
 386  	public function removeFileNoAuth( $key ) {
 387          wfDebug( __METHOD__ . " clearing row $key\n" );
 388  
 389          // Ensure we have the UploadStashFile loaded for this key
 390          $this->getFile( $key, true );
 391  
 392          $dbw = $this->repo->getMasterDb();
 393  
 394          $dbw->delete(
 395              'uploadstash',
 396              array( 'us_key' => $key ),
 397              __METHOD__
 398          );
 399  
 400          /** @todo Look into UnregisteredLocalFile and find out why the rv here is
 401           *  sometimes wrong (false when file was removed). For now, ignore.
 402           */
 403          $this->files[$key]->remove();
 404  
 405          unset( $this->files[$key] );
 406          unset( $this->fileMetadata[$key] );
 407  
 408          return true;
 409      }
 410  
 411      /**
 412       * List all files in the stash.
 413       *
 414       * @throws UploadStashNotLoggedInException
 415       * @return array
 416       */
 417  	public function listFiles() {
 418          if ( !$this->isLoggedIn ) {
 419              throw new UploadStashNotLoggedInException( __METHOD__
 420                  . ' No user is logged in, files must belong to users' );
 421          }
 422  
 423          $dbr = $this->repo->getSlaveDb();
 424          $res = $dbr->select(
 425              'uploadstash',
 426              'us_key',
 427              array( 'us_user' => $this->userId ),
 428              __METHOD__
 429          );
 430  
 431          if ( !is_object( $res ) || $res->numRows() == 0 ) {
 432              // nothing to do.
 433              return false;
 434          }
 435  
 436          // finish the read before starting writes.
 437          $keys = array();
 438          foreach ( $res as $row ) {
 439              array_push( $keys, $row->us_key );
 440          }
 441  
 442          return $keys;
 443      }
 444  
 445      /**
 446       * Find or guess extension -- ensuring that our extension matches our MIME type.
 447       * Since these files are constructed from php tempnames they may not start off
 448       * with an extension.
 449       * XXX this is somewhat redundant with the checks that ApiUpload.php does with incoming
 450       * uploads versus the desired filename. Maybe we can get that passed to us...
 451       * @param string $path
 452       * @throws UploadStashFileException
 453       * @return string
 454       */
 455  	public static function getExtensionForPath( $path ) {
 456          global $wgFileBlacklist;
 457          // Does this have an extension?
 458          $n = strrpos( $path, '.' );
 459          $extension = null;
 460          if ( $n !== false ) {
 461              $extension = $n ? substr( $path, $n + 1 ) : '';
 462          } else {
 463              // If not, assume that it should be related to the MIME type of the original file.
 464              $magic = MimeMagic::singleton();
 465              $mimeType = $magic->guessMimeType( $path );
 466              $extensions = explode( ' ', MimeMagic::singleton()->getExtensionsForType( $mimeType ) );
 467              if ( count( $extensions ) ) {
 468                  $extension = $extensions[0];
 469              }
 470          }
 471  
 472          if ( is_null( $extension ) ) {
 473              throw new UploadStashFileException( "extension is null" );
 474          }
 475  
 476          $extension = File::normalizeExtension( $extension );
 477          if ( in_array( $extension, $wgFileBlacklist ) ) {
 478              // The file should already be checked for being evil.
 479              // However, if somehow we got here, we definitely
 480              // don't want to give it an extension of .php and
 481              // put it in a web accesible directory.
 482              return '';
 483          }
 484  
 485          return $extension;
 486      }
 487  
 488      /**
 489       * Helper function: do the actual database query to fetch file metadata.
 490       *
 491       * @param string $key
 492       * @param int $readFromDB Constant (default: DB_SLAVE)
 493       * @return bool
 494       */
 495  	protected function fetchFileMetadata( $key, $readFromDB = DB_SLAVE ) {
 496          // populate $fileMetadata[$key]
 497          $dbr = null;
 498          if ( $readFromDB === DB_MASTER ) {
 499              // sometimes reading from the master is necessary, if there's replication lag.
 500              $dbr = $this->repo->getMasterDb();
 501          } else {
 502              $dbr = $this->repo->getSlaveDb();
 503          }
 504  
 505          $row = $dbr->selectRow(
 506              'uploadstash',
 507              '*',
 508              array( 'us_key' => $key ),
 509              __METHOD__
 510          );
 511  
 512          if ( !is_object( $row ) ) {
 513              // key wasn't present in the database. this will happen sometimes.
 514              return false;
 515          }
 516  
 517          $this->fileMetadata[$key] = (array)$row;
 518          $this->fileMetadata[$key]['us_props'] = $dbr->decodeBlob( $row->us_props );
 519  
 520          return true;
 521      }
 522  
 523      /**
 524       * Helper function: Initialize the UploadStashFile for a given file.
 525       *
 526       * @param string $key Key under which to store the object
 527       * @throws UploadStashZeroLengthFileException
 528       * @return bool
 529       */
 530  	protected function initFile( $key ) {
 531          $file = new UploadStashFile( $this->repo, $this->fileMetadata[$key]['us_path'], $key );
 532          if ( $file->getSize() === 0 ) {
 533              throw new UploadStashZeroLengthFileException( "File is zero length" );
 534          }
 535          $this->files[$key] = $file;
 536  
 537          return true;
 538      }
 539  }
 540  
 541  class UploadStashFile extends UnregisteredLocalFile {
 542      private $fileKey;
 543      private $urlName;
 544      protected $url;
 545  
 546      /**
 547       * A LocalFile wrapper around a file that has been temporarily stashed,
 548       * so we can do things like create thumbnails for it. Arguably
 549       * UnregisteredLocalFile should be handling its own file repo but that
 550       * class is a bit retarded currently.
 551       *
 552       * @param FileRepo $repo Repository where we should find the path
 553       * @param string $path Path to file
 554       * @param string $key Key to store the path and any stashed data under
 555       * @throws UploadStashBadPathException
 556       * @throws UploadStashFileNotFoundException
 557       */
 558  	public function __construct( $repo, $path, $key ) {
 559          $this->fileKey = $key;
 560  
 561          // resolve mwrepo:// urls
 562          if ( $repo->isVirtualUrl( $path ) ) {
 563              $path = $repo->resolveVirtualUrl( $path );
 564          } else {
 565              // check if path appears to be sane, no parent traversals,
 566              // and is in this repo's temp zone.
 567              $repoTempPath = $repo->getZonePath( 'temp' );
 568              if ( ( !$repo->validateFilename( $path ) ) ||
 569                  ( strpos( $path, $repoTempPath ) !== 0 )
 570              ) {
 571                  wfDebug( "UploadStash: tried to construct an UploadStashFile "
 572                      . "from a file that should already exist at '$path', but path is not valid\n" );
 573                  throw new UploadStashBadPathException( 'path is not valid' );
 574              }
 575  
 576              // check if path exists! and is a plain file.
 577              if ( !$repo->fileExists( $path ) ) {
 578                  wfDebug( "UploadStash: tried to construct an UploadStashFile from "
 579                      . "a file that should already exist at '$path', but path is not found\n" );
 580                  throw new UploadStashFileNotFoundException( 'cannot find path, or not a plain file' );
 581              }
 582          }
 583  
 584          parent::__construct( false, $repo, $path, false );
 585  
 586          $this->name = basename( $this->path );
 587      }
 588  
 589      /**
 590       * A method needed by the file transforming and scaling routines in File.php
 591       * We do not necessarily care about doing the description at this point
 592       * However, we also can't return the empty string, as the rest of MediaWiki
 593       * demands this (and calls to imagemagick convert require it to be there)
 594       *
 595       * @return string Dummy value
 596       */
 597  	public function getDescriptionUrl() {
 598          return $this->getUrl();
 599      }
 600  
 601      /**
 602       * Get the path for the thumbnail (actually any transformation of this file)
 603       * The actual argument is the result of thumbName although we seem to have
 604       * buggy code elsewhere that expects a boolean 'suffix'
 605       *
 606       * @param string $thumbName Name of thumbnail (e.g. "120px-123456.jpg" ),
 607       *   or false to just get the path
 608       * @return string Path thumbnail should take on filesystem, or containing
 609       *   directory if thumbname is false
 610       */
 611  	public function getThumbPath( $thumbName = false ) {
 612          $path = dirname( $this->path );
 613          if ( $thumbName !== false ) {
 614              $path .= "/$thumbName";
 615          }
 616  
 617          return $path;
 618      }
 619  
 620      /**
 621       * Return the file/url base name of a thumbnail with the specified parameters.
 622       * We override this because we want to use the pretty url name instead of the
 623       * ugly file name.
 624       *
 625       * @param array $params Handler-specific parameters
 626       * @param int $flags Bitfield that supports THUMB_* constants
 627       * @return string Base name for URL, like '120px-12345.jpg', or null if there is no handler
 628       */
 629  	function thumbName( $params, $flags = 0 ) {
 630          return $this->generateThumbName( $this->getUrlName(), $params );
 631      }
 632  
 633      /**
 634       * Helper function -- given a 'subpage', return the local URL,
 635       * e.g. /wiki/Special:UploadStash/subpage
 636       * @param string $subPage
 637       * @return string Local URL for this subpage in the Special:UploadStash space.
 638       */
 639  	private function getSpecialUrl( $subPage ) {
 640          return SpecialPage::getTitleFor( 'UploadStash', $subPage )->getLocalURL();
 641      }
 642  
 643      /**
 644       * Get a URL to access the thumbnail
 645       * This is required because the model of how files work requires that
 646       * the thumbnail urls be predictable. However, in our model the URL is
 647       * not based on the filename (that's hidden in the db)
 648       *
 649       * @param string $thumbName Basename of thumbnail file -- however, we don't
 650       *   want to use the file exactly
 651       * @return string URL to access thumbnail, or URL with partial path
 652       */
 653  	public function getThumbUrl( $thumbName = false ) {
 654          wfDebug( __METHOD__ . " getting for $thumbName \n" );
 655  
 656          return $this->getSpecialUrl( 'thumb/' . $this->getUrlName() . '/' . $thumbName );
 657      }
 658  
 659      /**
 660       * The basename for the URL, which we want to not be related to the filename.
 661       * Will also be used as the lookup key for a thumbnail file.
 662       *
 663       * @return string Base url name, like '120px-123456.jpg'
 664       */
 665  	public function getUrlName() {
 666          if ( !$this->urlName ) {
 667              $this->urlName = $this->fileKey;
 668          }
 669  
 670          return $this->urlName;
 671      }
 672  
 673      /**
 674       * Return the URL of the file, if for some reason we wanted to download it
 675       * We tend not to do this for the original file, but we do want thumb icons
 676       *
 677       * @return string Url
 678       */
 679  	public function getUrl() {
 680          if ( !isset( $this->url ) ) {
 681              $this->url = $this->getSpecialUrl( 'file/' . $this->getUrlName() );
 682          }
 683  
 684          return $this->url;
 685      }
 686  
 687      /**
 688       * Parent classes use this method, for no obvious reason, to return the path
 689       * (relative to wiki root, I assume). But with this class, the URL is
 690       * unrelated to the path.
 691       *
 692       * @return string Url
 693       */
 694  	public function getFullUrl() {
 695          return $this->getUrl();
 696      }
 697  
 698      /**
 699       * Getter for file key (the unique id by which this file's location &
 700       * metadata is stored in the db)
 701       *
 702       * @return string File key
 703       */
 704  	public function getFileKey() {
 705          return $this->fileKey;
 706      }
 707  
 708      /**
 709       * Remove the associated temporary file
 710       * @return status Success
 711       */
 712  	public function remove() {
 713          if ( !$this->repo->fileExists( $this->path ) ) {
 714              // Maybe the file's already been removed? This could totally happen in UploadBase.
 715              return true;
 716          }
 717  
 718          return $this->repo->freeTemp( $this->path );
 719      }
 720  
 721  	public function exists() {
 722          return $this->repo->fileExists( $this->path );
 723      }
 724  }
 725  
 726  class UploadStashException extends MWException {
 727  }
 728  
 729  class UploadStashNotAvailableException extends UploadStashException {
 730  }
 731  
 732  class UploadStashFileNotFoundException extends UploadStashException {
 733  }
 734  
 735  class UploadStashBadPathException extends UploadStashException {
 736  }
 737  
 738  class UploadStashFileException extends UploadStashException {
 739  }
 740  
 741  class UploadStashZeroLengthFileException extends UploadStashException {
 742  }
 743  
 744  class UploadStashNotLoggedInException extends UploadStashException {
 745  }
 746  
 747  class UploadStashWrongOwnerException extends UploadStashException {
 748  }
 749  
 750  class UploadStashNoSuchKeyException extends UploadStashException {
 751  }
 752  


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1