[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/filerepo/file/ -> OldLocalFile.php (source)

   1  <?php
   2  /**
   3   * Old file in the oldimage table.
   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 FileAbstraction
  22   */
  23  
  24  /**
  25   * Class to represent a file in the oldimage table
  26   *
  27   * @ingroup FileAbstraction
  28   */
  29  class OldLocalFile extends LocalFile {
  30      /** @var string Timestamp */
  31      protected $requestedTime;
  32  
  33      /** @var string Archive name */
  34      protected $archive_name;
  35  
  36      const CACHE_VERSION = 1;
  37      const MAX_CACHE_ROWS = 20;
  38  
  39      /**
  40       * @param Title $title
  41       * @param FileRepo $repo
  42       * @param null|int $time Timestamp or null
  43       * @return OldLocalFile
  44       * @throws MWException
  45       */
  46  	static function newFromTitle( $title, $repo, $time = null ) {
  47          # The null default value is only here to avoid an E_STRICT
  48          if ( $time === null ) {
  49              throw new MWException( __METHOD__ . ' got null for $time parameter' );
  50          }
  51  
  52          return new self( $title, $repo, $time, null );
  53      }
  54  
  55      /**
  56       * @param Title $title
  57       * @param FileRepo $repo
  58       * @param string $archiveName
  59       * @return OldLocalFile
  60       */
  61  	static function newFromArchiveName( $title, $repo, $archiveName ) {
  62          return new self( $title, $repo, null, $archiveName );
  63      }
  64  
  65      /**
  66       * @param stdClass $row
  67       * @param FileRepo $repo
  68       * @return OldLocalFile
  69       */
  70  	static function newFromRow( $row, $repo ) {
  71          $title = Title::makeTitle( NS_FILE, $row->oi_name );
  72          $file = new self( $title, $repo, null, $row->oi_archive_name );
  73          $file->loadFromRow( $row, 'oi_' );
  74  
  75          return $file;
  76      }
  77  
  78      /**
  79       * Create a OldLocalFile from a SHA-1 key
  80       * Do not call this except from inside a repo class.
  81       *
  82       * @param string $sha1 Base-36 SHA-1
  83       * @param LocalRepo $repo
  84       * @param string|bool $timestamp MW_timestamp (optional)
  85       *
  86       * @return bool|OldLocalFile
  87       */
  88  	static function newFromKey( $sha1, $repo, $timestamp = false ) {
  89          $dbr = $repo->getSlaveDB();
  90  
  91          $conds = array( 'oi_sha1' => $sha1 );
  92          if ( $timestamp ) {
  93              $conds['oi_timestamp'] = $dbr->timestamp( $timestamp );
  94          }
  95  
  96          $row = $dbr->selectRow( 'oldimage', self::selectFields(), $conds, __METHOD__ );
  97          if ( $row ) {
  98              return self::newFromRow( $row, $repo );
  99          } else {
 100              return false;
 101          }
 102      }
 103  
 104      /**
 105       * Fields in the oldimage table
 106       * @return array
 107       */
 108  	static function selectFields() {
 109          return array(
 110              'oi_name',
 111              'oi_archive_name',
 112              'oi_size',
 113              'oi_width',
 114              'oi_height',
 115              'oi_metadata',
 116              'oi_bits',
 117              'oi_media_type',
 118              'oi_major_mime',
 119              'oi_minor_mime',
 120              'oi_description',
 121              'oi_user',
 122              'oi_user_text',
 123              'oi_timestamp',
 124              'oi_deleted',
 125              'oi_sha1',
 126          );
 127      }
 128  
 129      /**
 130       * @param Title $title
 131       * @param FileRepo $repo
 132       * @param string $time Timestamp or null to load by archive name
 133       * @param string $archiveName Archive name or null to load by timestamp
 134       * @throws MWException
 135       */
 136  	function __construct( $title, $repo, $time, $archiveName ) {
 137          parent::__construct( $title, $repo );
 138          $this->requestedTime = $time;
 139          $this->archive_name = $archiveName;
 140          if ( is_null( $time ) && is_null( $archiveName ) ) {
 141              throw new MWException( __METHOD__ . ': must specify at least one of $time or $archiveName' );
 142          }
 143      }
 144  
 145      /**
 146       * @return bool
 147       */
 148  	function getCacheKey() {
 149          return false;
 150      }
 151  
 152      /**
 153       * @return string
 154       */
 155  	function getArchiveName() {
 156          if ( !isset( $this->archive_name ) ) {
 157              $this->load();
 158          }
 159  
 160          return $this->archive_name;
 161      }
 162  
 163      /**
 164       * @return bool
 165       */
 166  	function isOld() {
 167          return true;
 168      }
 169  
 170      /**
 171       * @return bool
 172       */
 173  	function isVisible() {
 174          return $this->exists() && !$this->isDeleted( File::DELETED_FILE );
 175      }
 176  
 177  	function loadFromDB( $flags = 0 ) {
 178          wfProfileIn( __METHOD__ );
 179  
 180          $this->dataLoaded = true;
 181  
 182          $dbr = $this->repo->getSlaveDB();
 183          $conds = array( 'oi_name' => $this->getName() );
 184          if ( is_null( $this->requestedTime ) ) {
 185              $conds['oi_archive_name'] = $this->archive_name;
 186          } else {
 187              $conds['oi_timestamp'] = $dbr->timestamp( $this->requestedTime );
 188          }
 189          $row = $dbr->selectRow( 'oldimage', $this->getCacheFields( 'oi_' ),
 190              $conds, __METHOD__, array( 'ORDER BY' => 'oi_timestamp DESC' ) );
 191          if ( $row ) {
 192              $this->loadFromRow( $row, 'oi_' );
 193          } else {
 194              $this->fileExists = false;
 195          }
 196  
 197          wfProfileOut( __METHOD__ );
 198      }
 199  
 200      /**
 201       * Load lazy file metadata from the DB
 202       */
 203  	protected function loadExtraFromDB() {
 204          wfProfileIn( __METHOD__ );
 205  
 206          $this->extraDataLoaded = true;
 207          $dbr = $this->repo->getSlaveDB();
 208          $conds = array( 'oi_name' => $this->getName() );
 209          if ( is_null( $this->requestedTime ) ) {
 210              $conds['oi_archive_name'] = $this->archive_name;
 211          } else {
 212              $conds['oi_timestamp'] = $dbr->timestamp( $this->requestedTime );
 213          }
 214          // In theory the file could have just been renamed/deleted...oh well
 215          $row = $dbr->selectRow( 'oldimage', $this->getLazyCacheFields( 'oi_' ),
 216              $conds, __METHOD__, array( 'ORDER BY' => 'oi_timestamp DESC' ) );
 217  
 218          if ( !$row ) { // fallback to master
 219              $dbr = $this->repo->getMasterDB();
 220              $row = $dbr->selectRow( 'oldimage', $this->getLazyCacheFields( 'oi_' ),
 221                  $conds, __METHOD__, array( 'ORDER BY' => 'oi_timestamp DESC' ) );
 222          }
 223  
 224          if ( $row ) {
 225              foreach ( $this->unprefixRow( $row, 'oi_' ) as $name => $value ) {
 226                  $this->$name = $value;
 227              }
 228          } else {
 229              wfProfileOut( __METHOD__ );
 230              throw new MWException( "Could not find data for image '{$this->archive_name}'." );
 231          }
 232  
 233          wfProfileOut( __METHOD__ );
 234      }
 235  
 236      /**
 237       * @param string $prefix
 238       * @return array
 239       */
 240  	function getCacheFields( $prefix = 'img_' ) {
 241          $fields = parent::getCacheFields( $prefix );
 242          $fields[] = $prefix . 'archive_name';
 243          $fields[] = $prefix . 'deleted';
 244  
 245          return $fields;
 246      }
 247  
 248      /**
 249       * @return string
 250       */
 251  	function getRel() {
 252          return 'archive/' . $this->getHashPath() . $this->getArchiveName();
 253      }
 254  
 255      /**
 256       * @return string
 257       */
 258  	function getUrlRel() {
 259          return 'archive/' . $this->getHashPath() . rawurlencode( $this->getArchiveName() );
 260      }
 261  
 262  	function upgradeRow() {
 263          wfProfileIn( __METHOD__ );
 264          $this->loadFromFile();
 265  
 266          # Don't destroy file info of missing files
 267          if ( !$this->fileExists ) {
 268              wfDebug( __METHOD__ . ": file does not exist, aborting\n" );
 269              wfProfileOut( __METHOD__ );
 270  
 271              return;
 272          }
 273  
 274          $dbw = $this->repo->getMasterDB();
 275          list( $major, $minor ) = self::splitMime( $this->mime );
 276  
 277          wfDebug( __METHOD__ . ': upgrading ' . $this->archive_name . " to the current schema\n" );
 278          $dbw->update( 'oldimage',
 279              array(
 280                  'oi_size' => $this->size, // sanity
 281                  'oi_width' => $this->width,
 282                  'oi_height' => $this->height,
 283                  'oi_bits' => $this->bits,
 284                  'oi_media_type' => $this->media_type,
 285                  'oi_major_mime' => $major,
 286                  'oi_minor_mime' => $minor,
 287                  'oi_metadata' => $this->metadata,
 288                  'oi_sha1' => $this->sha1,
 289              ), array(
 290                  'oi_name' => $this->getName(),
 291                  'oi_archive_name' => $this->archive_name ),
 292              __METHOD__
 293          );
 294          wfProfileOut( __METHOD__ );
 295      }
 296  
 297      /**
 298       * @param int $field One of DELETED_* bitfield constants for file or
 299       *   revision rows
 300       * @return bool
 301       */
 302  	function isDeleted( $field ) {
 303          $this->load();
 304  
 305          return ( $this->deleted & $field ) == $field;
 306      }
 307  
 308      /**
 309       * Returns bitfield value
 310       * @return int
 311       */
 312  	function getVisibility() {
 313          $this->load();
 314  
 315          return (int)$this->deleted;
 316      }
 317  
 318      /**
 319       * Determine if the current user is allowed to view a particular
 320       * field of this image file, if it's marked as deleted.
 321       *
 322       * @param int $field
 323       * @param User|null $user User object to check, or null to use $wgUser
 324       * @return bool
 325       */
 326  	function userCan( $field, User $user = null ) {
 327          $this->load();
 328  
 329          return Revision::userCanBitfield( $this->deleted, $field, $user );
 330      }
 331  
 332      /**
 333       * Upload a file directly into archive. Generally for Special:Import.
 334       *
 335       * @param string $srcPath File system path of the source file
 336       * @param string $archiveName Full archive name of the file, in the form
 337       *   $timestamp!$filename, where $filename must match $this->getName()
 338       * @param string $timestamp
 339       * @param string $comment
 340       * @param User $user
 341       * @param int $flags
 342       * @return FileRepoStatus
 343       */
 344  	function uploadOld( $srcPath, $archiveName, $timestamp, $comment, $user, $flags = 0 ) {
 345          $this->lock();
 346  
 347          $dstRel = 'archive/' . $this->getHashPath() . $archiveName;
 348          $status = $this->publishTo( $srcPath, $dstRel,
 349              $flags & File::DELETE_SOURCE ? FileRepo::DELETE_SOURCE : 0
 350          );
 351  
 352          if ( $status->isGood() ) {
 353              if ( !$this->recordOldUpload( $srcPath, $archiveName, $timestamp, $comment, $user ) ) {
 354                  $status->fatal( 'filenotfound', $srcPath );
 355              }
 356          }
 357  
 358          $this->unlock();
 359  
 360          return $status;
 361      }
 362  
 363      /**
 364       * Record a file upload in the oldimage table, without adding log entries.
 365       *
 366       * @param string $srcPath File system path to the source file
 367       * @param string $archiveName The archive name of the file
 368       * @param string $timestamp
 369       * @param string $comment Upload comment
 370       * @param User $user User who did this upload
 371       * @return bool
 372       */
 373  	function recordOldUpload( $srcPath, $archiveName, $timestamp, $comment, $user ) {
 374          $dbw = $this->repo->getMasterDB();
 375          $dbw->begin( __METHOD__ );
 376  
 377          $dstPath = $this->repo->getZonePath( 'public' ) . '/' . $this->getRel();
 378          $props = $this->repo->getFileProps( $dstPath );
 379          if ( !$props['fileExists'] ) {
 380              return false;
 381          }
 382  
 383          $dbw->insert( 'oldimage',
 384              array(
 385                  'oi_name' => $this->getName(),
 386                  'oi_archive_name' => $archiveName,
 387                  'oi_size' => $props['size'],
 388                  'oi_width' => intval( $props['width'] ),
 389                  'oi_height' => intval( $props['height'] ),
 390                  'oi_bits' => $props['bits'],
 391                  'oi_timestamp' => $dbw->timestamp( $timestamp ),
 392                  'oi_description' => $comment,
 393                  'oi_user' => $user->getId(),
 394                  'oi_user_text' => $user->getName(),
 395                  'oi_metadata' => $props['metadata'],
 396                  'oi_media_type' => $props['media_type'],
 397                  'oi_major_mime' => $props['major_mime'],
 398                  'oi_minor_mime' => $props['minor_mime'],
 399                  'oi_sha1' => $props['sha1'],
 400              ), __METHOD__
 401          );
 402  
 403          $dbw->commit( __METHOD__ );
 404  
 405          return true;
 406      }
 407  
 408      /**
 409       * If archive name is an empty string, then file does not "exist"
 410       *
 411       * This is the case for a couple files on Wikimedia servers where
 412       * the old version is "lost".
 413       */
 414  	public function exists() {
 415          $archiveName = $this->getArchiveName();
 416          if ( $archiveName === '' || !is_string( $archiveName ) ) {
 417              return false;
 418          }
 419          return parent::exists();
 420      }
 421  }


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