/**
  * Get a file and its metadata from the stash.
  *
  * @param $key String: key under which file information is stored
  * @param $noAuth Boolean (optional) Don't check authentication. Used by maintenance scripts.
  * @throws UploadStashFileNotFoundException
  * @throws UploadStashNotLoggedInException
  * @throws UploadStashWrongOwnerException
  * @throws UploadStashBadPathException
  * @return UploadStashFile
  */
 public function getFile($key, $noAuth = false)
 {
     if (!preg_match(self::KEY_FORMAT_REGEX, $key)) {
         throw new UploadStashBadPathException("key '{$key}' is not in a proper format");
     }
     if (!$noAuth) {
         if (!$this->isLoggedIn) {
             throw new UploadStashNotLoggedInException(__METHOD__ . ' No user is logged in, files must belong to users');
         }
     }
     $dbr = $this->repo->getSlaveDb();
     if (!isset($this->fileMetadata[$key])) {
         // try this first.  if it fails to find the row, check for lag, wait, try again. if its still missing, throw an exception.
         // this more complex solution keeps things moving for page loads with many requests
         // (ie. validating image ownership) when replag is high
         if (!$this->fetchFileMetadata($key)) {
             $lag = $dbr->getLag();
             if ($lag > 0 && $lag <= self::MAX_LAG) {
                 // if there's not too much replication lag, just wait for the slave to catch up to our last insert.
                 sleep(ceil($lag));
             } elseif ($lag > self::MAX_LAG) {
                 // that's a lot of lag to introduce into the middle of the UI.
                 throw new UploadStashMaxLagExceededException('Couldn\'t load stashed file metadata, and replication lag is above threshold: (MAX_LAG=' . self::MAX_LAG . ')');
             }
             // now that the waiting has happened, try again
             $this->fetchFileMetadata($key);
         }
         if (!isset($this->fileMetadata[$key])) {
             throw new UploadStashFileNotFoundException("key '{$key}' not found in stash");
         }
         // create $this->files[$key]
         $this->initFile($key);
         // fetch fileprops
         $path = $this->fileMetadata[$key]['us_path'];
         if ($this->repo->isVirtualUrl($path)) {
             $path = $this->repo->resolveVirtualUrl($path);
         }
         $this->fileProps[$key] = File::getPropsFromPath($path);
     }
     if (!$this->files[$key]->exists()) {
         wfDebug(__METHOD__ . " tried to get file at {$key}, but it doesn't exist\n");
         throw new UploadStashBadPathException("path doesn't exist");
     }
     if (!$noAuth) {
         if ($this->fileMetadata[$key]['us_user'] != $this->userId) {
             throw new UploadStashWrongOwnerException("This file ({$key}) doesn't belong to the current user.");
         }
     }
     return $this->files[$key];
 }
Beispiel #2
0
	/**
	 * Upload a file and record it in the DB
	 * @param string $srcPath source storage path, virtual URL, or filesystem path
	 * @param string $comment upload description
	 * @param string $pageText text to use for the new description page,
	 *                  if a new description page is created
	 * @param $flags Integer|bool: flags for publish()
	 * @param array|bool $props File properties, if known. This can be used to reduce the
	 *               upload time when uploading virtual URLs for which the file info
	 *               is already known
	 * @param string|bool $timestamp timestamp for img_timestamp, or false to use the current time
	 * @param $user User|null: User object or null to use $wgUser
	 *
	 * @return FileRepoStatus object. On success, the value member contains the
	 *     archive name, or an empty string if it was a new file.
	 */
	function upload( $srcPath, $comment, $pageText, $flags = 0, $props = false, $timestamp = false, $user = null ) {
		global $wgContLang;

		if ( $this->getRepo()->getReadOnlyReason() !== false ) {
			return $this->readOnlyFatalStatus();
		}

		if ( !$props ) {
			wfProfileIn( __METHOD__ . '-getProps' );
			if ( $this->repo->isVirtualUrl( $srcPath )
				|| FileBackend::isStoragePath( $srcPath ) )
			{
				$props = $this->repo->getFileProps( $srcPath );
			} else {
				$props = FSFile::getPropsFromPath( $srcPath );
			}
			wfProfileOut( __METHOD__ . '-getProps' );
		}

		$options = array();
		$handler = MediaHandler::getHandler( $props['mime'] );
		if ( $handler ) {
			$options['headers'] = $handler->getStreamHeaders( $props['metadata'] );
		} else {
			$options['headers'] = array();
		}

		// Trim spaces on user supplied text
		$comment = trim( $comment );

		// truncate nicely or the DB will do it for us
		// non-nicely (dangling multi-byte chars, non-truncated version in cache).
		$comment = $wgContLang->truncate( $comment, 255 );
		$this->lock(); // begin
		$status = $this->publish( $srcPath, $flags, $options );

		if ( $status->successCount > 0 ) {
			# Essentially we are displacing any existing current file and saving
			# a new current file at the old location. If just the first succeeded,
			# we still need to displace the current DB entry and put in a new one.
			if ( !$this->recordUpload2( $status->value, $comment, $pageText, $props, $timestamp, $user ) ) {
				$status->fatal( 'filenotfound', $srcPath );
			}
		}

		$this->unlock(); // done

		return $status;
	}
Beispiel #3
0
 /**
  * Get a file and its metadata from the stash.
  * The noAuth param is a bit janky but is required for automated scripts which clean out the stash.
  *
  * @param $key String: key under which file information is stored
  * @param $noAuth Boolean (optional) Don't check authentication. Used by maintenance scripts.
  * @throws UploadStashFileNotFoundException
  * @throws UploadStashNotLoggedInException
  * @throws UploadStashWrongOwnerException
  * @throws UploadStashBadPathException
  * @return UploadStashFile
  */
 public function getFile($key, $noAuth = false)
 {
     if (!preg_match(self::KEY_FORMAT_REGEX, $key)) {
         throw new UploadStashBadPathException("key '{$key}' is not in a proper format");
     }
     if (!$noAuth) {
         if (!$this->isLoggedIn) {
             throw new UploadStashNotLoggedInException(__METHOD__ . ' No user is logged in, files must belong to users');
         }
     }
     if (!isset($this->fileMetadata[$key])) {
         if (!$this->fetchFileMetadata($key)) {
             // If nothing was received, it's likely due to replication lag.  Check the master to see if the record is there.
             $this->fetchFileMetadata($key, DB_MASTER);
         }
         if (!isset($this->fileMetadata[$key])) {
             throw new UploadStashFileNotFoundException("key '{$key}' not found in stash");
         }
         // create $this->files[$key]
         $this->initFile($key);
         // fetch fileprops
         $path = $this->fileMetadata[$key]['us_path'];
         if ($this->repo->isVirtualUrl($path)) {
             $path = $this->repo->resolveVirtualUrl($path);
         }
         $this->fileProps[$key] = File::getPropsFromPath($path);
     }
     if (!$this->files[$key]->exists()) {
         wfDebug(__METHOD__ . " tried to get file at {$key}, but it doesn't exist\n");
         throw new UploadStashBadPathException("path doesn't exist");
     }
     if (!$noAuth) {
         if ($this->fileMetadata[$key]['us_user'] != $this->userId) {
             throw new UploadStashWrongOwnerException("This file ({$key}) doesn't belong to the current user.");
         }
     }
     return $this->files[$key];
 }