if ( $timestamp !== false ) {
$timestamp = wfTimestamp( TS_MW, $timestamp );
}
+
return $timestamp;
}
* Get an associative array containing information about
* a file with the given storage path.
*
- * @param Mixed $ext: the file extension, or true to extract it from the filename.
+ * @param mixed $ext The file extension, or true to extract it from the filename.
* Set it to false to ignore the extension.
*
* @return array
}
wfProfileOut( __METHOD__ );
+
return $info;
}
$info['width'] = 0;
$info['height'] = 0;
$info['bits'] = 0;
+
return $info;
}
} else {
$info['bits'] = 0;
}
+
return $info;
}
if ( $this->sha1Base36 !== null && !$recache ) {
wfProfileOut( __METHOD__ );
+
return $this->sha1Base36;
}
}
wfProfileOut( __METHOD__ );
+
return $this->sha1Base36;
}
*/
public static function extensionFromPath( $path ) {
$i = strrpos( $path, '.' );
+
return strtolower( $i ? substr( $path, $i + 1 ) : '' );
}
* Get an associative array containing information about a file in the local filesystem.
*
* @param string $path absolute local filesystem path
- * @param Mixed $ext: the file extension, or true to extract it from the filename.
+ * @param mixed $ext The file extension, or true to extract it from the filename.
* Set it to false to ignore the extension.
* @return array
*/
public static function getPropsFromPath( $path, $ext = true ) {
$fsFile = new self( $path );
+
return $fsFile->getProps( $ext );
}
*/
public static function getSha1Base36FromPath( $path ) {
$fsFile = new self( $path );
+
return $fsFile->getSha1Base36();
}
}
return $relStoragePath;
}
}
+
return null;
}
} elseif ( isset( $this->basePath ) ) {
return "{$this->basePath}/{$fullCont}";
}
+
return null; // no container base path defined
}
if ( $relPath != '' ) {
$fsPath .= "/{$relPath}";
}
+
return $fsPath;
}
$dest = $this->resolveToFSPath( $params['dst'] );
if ( $dest === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['dst'] );
+
return $status;
}
$tempFile = TempFSFile::factory( 'create_', 'tmp' );
if ( !$tempFile ) {
$status->fatal( 'backend-fail-create', $params['dst'] );
+
return $status;
}
$this->trapWarnings();
$this->untrapWarnings();
if ( $bytes === false ) {
$status->fatal( 'backend-fail-create', $params['dst'] );
+
return $status;
}
$cmd = implode( ' ', array(
$this->untrapWarnings();
if ( $bytes === false ) {
$status->fatal( 'backend-fail-create', $params['dst'] );
+
return $status;
}
$this->chmod( $dest );
$dest = $this->resolveToFSPath( $params['dst'] );
if ( $dest === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['dst'] );
+
return $status;
}
trigger_error( __METHOD__ . ": copy() failed but returned true." );
}
$status->fatal( 'backend-fail-store', $params['src'], $params['dst'] );
+
return $status;
}
$this->chmod( $dest );
$source = $this->resolveToFSPath( $params['src'] );
if ( $source === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['src'] );
+
return $status;
}
$dest = $this->resolveToFSPath( $params['dst'] );
if ( $dest === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['dst'] );
+
return $status;
}
if ( empty( $params['ignoreMissingSource'] ) ) {
$status->fatal( 'backend-fail-copy', $params['src'] );
}
+
return $status; // do nothing; either OK or bad status
}
trigger_error( __METHOD__ . ": copy() failed but returned true." );
}
$status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
+
return $status;
}
$this->chmod( $dest );
$source = $this->resolveToFSPath( $params['src'] );
if ( $source === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['src'] );
+
return $status;
}
$dest = $this->resolveToFSPath( $params['dst'] );
if ( $dest === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['dst'] );
+
return $status;
}
if ( empty( $params['ignoreMissingSource'] ) ) {
$status->fatal( 'backend-fail-move', $params['src'] );
}
+
return $status; // do nothing; either OK or bad status
}
clearstatcache(); // file no longer at source
if ( !$ok ) {
$status->fatal( 'backend-fail-move', $params['src'], $params['dst'] );
+
return $status;
}
}
$source = $this->resolveToFSPath( $params['src'] );
if ( $source === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['src'] );
+
return $status;
}
if ( empty( $params['ignoreMissingSource'] ) ) {
$status->fatal( 'backend-fail-delete', $params['src'] );
}
+
return $status; // do nothing; either OK or bad status
}
$this->untrapWarnings();
if ( !$ok ) {
$status->fatal( 'backend-fail-delete', $params['src'] );
+
return $status;
}
}
if ( is_dir( $dir ) && !$existed ) {
$status->merge( $this->doSecureInternal( $fullCont, $dirRel, $params ) );
}
+
return $status;
}
$status->fatal( 'backend-fail-create', "{$storeDir}/.htaccess" );
}
}
+
return $status;
}
}
$this->untrapWarnings();
}
+
return $status;
}
rmdir( $dir ); // remove directory if empty
}
$this->untrapWarnings();
+
return $status;
}
$exists = is_dir( $dir );
if ( !$exists ) {
wfDebug( __METHOD__ . "() given directory does not exist: '$dir'\n" );
+
return array(); // nothing under this dir
} elseif ( !is_readable( $dir ) ) {
wfDebug( __METHOD__ . "() given directory is unreadable: '$dir'\n" );
+
return null; // bad permissions?
}
+
return new FSFileBackendDirList( $dir, $params );
}
$exists = is_dir( $dir );
if ( !$exists ) {
wfDebug( __METHOD__ . "() given directory does not exist: '$dir'\n" );
+
return array(); // nothing under this dir
} elseif ( !is_readable( $dir ) ) {
wfDebug( __METHOD__ . "() given directory is unreadable: '$dir'\n" );
+
return null; // bad permissions?
}
+
return new FSFileBackendFileList( $dir, $params );
}
public function handleWarning( $errno, $errstr ) {
wfDebugLog( 'FSFileBackend', $errstr ); // more detailed error logging
$this->hadWarningErrors[count( $this->hadWarningErrors ) - 1] = true;
+
return true; // suppress from PHP handler
}
}
# RecursiveDirectoryIterator extends FilesystemIterator.
# FilesystemIterator::SKIP_DOTS default is inconsistent in PHP 5.3.x.
$flags = FilesystemIterator::CURRENT_AS_SELF | FilesystemIterator::SKIP_DOTS;
+
return new RecursiveIteratorIterator(
new RecursiveDirectoryIterator( $dir, $flags ),
RecursiveIteratorIterator::CHILD_FIRST // include dirs
/**
* Filter out items by advancing to the next ones
*/
- protected function filterViaNext() {}
+ protected function filterViaNext() {
+ }
/**
* Return only the relative path and normalize slashes to FileBackend-style.
if ( $path === false ) {
$path = $dir;
}
+
return strtr( substr( $path, $this->suffixStart ), '\\', '/' );
}
}
final protected function getScopedPHPBehaviorForOps() {
if ( PHP_SAPI != 'cli' ) { // http://bugs.php.net/bug.php?id=47540
$old = ignore_user_abort( true ); // avoid half-finished operations
- return new ScopedCallback( function() use ( $old ) {
+ return new ScopedCallback( function () use ( $old ) {
ignore_user_abort( $old );
} );
}
+
return null;
}
* @param array $paths Storage paths
* @return void
*/
- public function preloadCache( array $paths ) {}
+ public function preloadCache( array $paths ) {
+ }
/**
* Invalidate any in-process file stat and property cache.
* @param array $paths Storage paths (optional)
* @return void
*/
- public function clearCache( array $paths = null ) {}
+ public function clearCache( array $paths = null ) {
+ }
/**
* Lock the files at the given storage paths in the backend.
*/
final public function lockFiles( array $paths, $type ) {
$paths = array_map( 'FileBackend::normalizeStoragePath', $paths );
+
return $this->lockManager->lock( $paths, $type );
}
*/
final public function unlockFiles( array $paths, $type ) {
$paths = array_map( 'FileBackend::normalizeStoragePath', $paths );
+
return $this->lockManager->unlock( $paths, $type );
}
} else {
$paths = array_map( 'FileBackend::normalizeStoragePath', $paths );
}
+
return ScopedLock::factory( $this->lockManager, $paths, $type, $status );
}
}
}
}
+
return array( null, null, null );
}
: "mwstore://{$backend}/{$container}";
}
}
+
return null;
}
final public static function parentStoragePath( $storagePath ) {
$storagePath = dirname( $storagePath );
list( , , $rel ) = self::splitStoragePath( $storagePath );
+
return ( $rel === null ) ? null : $storagePath;
}
*/
final public static function extensionFromPath( $path ) {
$i = strrpos( $path, '.' );
+
return strtolower( $i ? substr( $path, $i + 1 ) : '' );
}
return null;
}
}
+
return $path;
}
}
* @ingroup FileBackend
* @since 1.22
*/
-class FileBackendError extends MWException {}
+class FileBackendError extends MWException {
+}
/** @var Array (name => ('class' => string, 'config' => array, 'instance' => object)) */
protected $backends = array();
- protected function __construct() {}
+ protected function __construct() {
+ }
/**
* @return FileBackendGroup
self::$instance = new self();
self::$instance->initFromGlobals();
}
+
return self::$instance;
}
$config = $this->backends[$name]['config'];
$this->backends[$name]['instance'] = new $class( $config );
}
+
return $this->backends[$name]['instance'];
}
throw new MWException( "No backend defined with the name `$name`." );
}
$class = $this->backends[$name]['class'];
+
return array( 'class' => $class ) + $this->backends[$name]['config'];
}
if ( $backend !== null && isset( $this->backends[$backend] ) ) {
return $this->get( $backend );
}
+
return null;
}
}
// Try to resync the clone backends to the master on the spot...
if ( !$this->autoResync || !$this->resyncFiles( $relevantPaths )->isOK() ) {
$status->merge( $syncStatus );
+
return $status; // abort
}
}
// already synced; nothing to do
} elseif ( $mSha1 !== false ) { // file is in master
if ( $this->autoResync === 'conservative'
- && $cStat && $cStat['mtime'] > $mStat['mtime'] )
- {
+ && $cStat && $cStat['mtime'] > $mStat['mtime']
+ ) {
$status->fatal( 'backend-fail-synced', $path );
continue; // don't rollback data
}
// For things like copy/move/delete with "ignoreMissingSource" and there
// is no source file, nothing should happen and there should be no errors.
if ( empty( $op['ignoreMissingSource'] )
- || $this->fileExists( array( 'src' => $op['src'] ) ) )
- {
+ || $this->fileExists( array( 'src' => $op['src'] ) )
+ ) {
$paths[] = $op['src'];
}
}
$paths[] = $op['dst'];
}
}
+
return array_values( array_unique( array_filter( $paths, 'FileBackend::isStoragePath' ) ) );
}
}
$newOps[] = $newOp;
}
+
return $newOps;
}
*/
protected function substOpPaths( array $ops, FileBackendStore $backend ) {
$newOps = $this->substOpBatchPaths( array( $ops ), $backend );
+
return $newOps[0];
}
$status->success = $masterStatus->success;
$status->successCount = $masterStatus->successCount;
$status->failCount = $masterStatus->failCount;
+
return $status;
}
*/
protected function replicateContainerDirChanges( $path ) {
list( , $shortCont, ) = self::splitStoragePath( $path );
+
return !in_array( $shortCont, $this->noPushDirConts );
}
$status->merge( $backend->doPrepare( $realParams ) );
}
}
+
return $status;
}
$status->merge( $backend->doSecure( $realParams ) );
}
}
+
return $status;
}
$status->merge( $backend->doPublish( $realParams ) );
}
}
+
return $status;
}
$status->merge( $backend->doClean( $realParams ) );
}
}
+
return $status;
}
public function concatenate( array $params ) {
// We are writing to an FS file, so we don't need to do this per-backend
$realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+
return $this->backends[$this->masterIndex]->concatenate( $realParams );
}
public function fileExists( array $params ) {
$realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+
return $this->backends[$this->masterIndex]->fileExists( $realParams );
}
public function getFileTimestamp( array $params ) {
$realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+
return $this->backends[$this->masterIndex]->getFileTimestamp( $realParams );
}
public function getFileSize( array $params ) {
$realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+
return $this->backends[$this->masterIndex]->getFileSize( $realParams );
}
public function getFileStat( array $params ) {
$realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+
return $this->backends[$this->masterIndex]->getFileStat( $realParams );
}
foreach ( $contentsM as $path => $data ) {
$contents[$this->unsubstPaths( $path )] = $data;
}
+
return $contents;
}
public function getFileSha1Base36( array $params ) {
$realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+
return $this->backends[$this->masterIndex]->getFileSha1Base36( $realParams );
}
public function getFileProps( array $params ) {
$realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+
return $this->backends[$this->masterIndex]->getFileProps( $realParams );
}
public function streamFile( array $params ) {
$realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+
return $this->backends[$this->masterIndex]->streamFile( $realParams );
}
foreach ( $fsFilesM as $path => $fsFile ) {
$fsFiles[$this->unsubstPaths( $path )] = $fsFile;
}
+
return $fsFiles;
}
foreach ( $tempFilesM as $path => $tempFile ) {
$tempFiles[$this->unsubstPaths( $path )] = $tempFile;
}
+
return $tempFiles;
}
public function getFileHttpUrl( array $params ) {
$realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+
return $this->backends[$this->masterIndex]->getFileHttpUrl( $realParams );
}
public function directoryExists( array $params ) {
$realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+
return $this->backends[$this->masterIndex]->directoryExists( $realParams );
}
public function getDirectoryList( array $params ) {
$realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+
return $this->backends[$this->masterIndex]->getDirectoryList( $realParams );
}
public function getFileList( array $params ) {
$realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+
return $this->backends[$this->masterIndex]->getFileList( $realParams );
}
LockManager::LOCK_UW => $this->unsubstPaths( $paths[LockManager::LOCK_UW] ),
LockManager::LOCK_EX => $this->unsubstPaths( $paths[LockManager::LOCK_EX] )
);
+
// Actually acquire the locks
return array( $this->getScopedFileLocks( $pbPaths, 'mixed', $status ) );
}
parent::__construct( $config );
$this->mimeCallback = isset( $config['mimeCallback'] )
? $config['mimeCallback']
- : function( $storagePath, $content, $fsPath ) {
+ : function ( $storagePath, $content, $fsPath ) {
// @TODO: handle the case of extension-less files using the contents
- return StreamFile::contentTypeFromPath( $storagePath ) ?: 'unknown/unknown';
+ return StreamFile::contentTypeFromPath( $storagePath ) ? : 'unknown/unknown';
};
$this->memCache = new EmptyBagOStuff(); // disabled by default
$this->cheapCache = new ProcessCacheLRU( self::CACHE_CHEAP_SIZE );
$this->deleteFileCache( $params['dst'] ); // persistent cache
}
}
+
return $status;
}
$this->deleteFileCache( $params['dst'] ); // persistent cache
}
}
+
return $status;
}
if ( !isset( $params['dstExists'] ) || $params['dstExists'] ) {
$this->deleteFileCache( $params['dst'] ); // persistent cache
}
+
return $status;
}
if ( !isset( $params['dstExists'] ) || $params['dstExists'] ) {
$this->deleteFileCache( $params['dst'] ); // persistent cache
}
+
return $status;
}
$status->merge( $this->deleteInternal( array( 'src' => $params['src'] ) ) );
$status->setResult( true, $status->value ); // ignore delete() errors
}
+
return $status;
}
} else {
$status = Status::newGood(); // nothing to do
}
+
return $status;
}
wfRestoreWarnings();
if ( !$ok ) { // not present or not empty
$status->fatal( 'backend-fail-opentemp', $tmpPath );
+
return $status;
}
$fsFile = $this->getLocalReference( array( 'src' => $path ) );
if ( !$fsFile ) { // retry failed?
$status->fatal( 'backend-fail-read', $path );
+
return $status;
}
}
$tmpHandle = fopen( $tmpPath, 'ab' );
if ( $tmpHandle === false ) {
$status->fatal( 'backend-fail-opentemp', $tmpPath );
+
return $status;
}
if ( $sourceHandle === false ) {
fclose( $tmpHandle );
$status->fatal( 'backend-fail-read', $virtualSource );
+
return $status;
}
// Append chunk to file (pass chunk size to avoid magic quotes)
fclose( $sourceHandle );
fclose( $tmpHandle );
$status->fatal( 'backend-fail-writetemp', $tmpPath );
+
return $status;
}
fclose( $sourceHandle );
}
if ( !fclose( $tmpHandle ) ) {
$status->fatal( 'backend-fail-closetemp', $tmpPath );
+
return $status;
}
list( $fullCont, $dir, $shard ) = $this->resolveStoragePath( $params['dir'] );
if ( $dir === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['dir'] );
+
return $status; // invalid storage path
}
list( $fullCont, $dir, $shard ) = $this->resolveStoragePath( $params['dir'] );
if ( $dir === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['dir'] );
+
return $status; // invalid storage path
}
list( $fullCont, $dir, $shard ) = $this->resolveStoragePath( $params['dir'] );
if ( $dir === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['dir'] );
+
return $status; // invalid storage path
}
list( $fullCont, $dir, $shard ) = $this->resolveStoragePath( $params['dir'] );
if ( $dir === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['dir'] );
+
return $status; // invalid storage path
}
final public function fileExists( array $params ) {
$section = new ProfileSection( __METHOD__ . "-{$this->name}" );
$stat = $this->getFileStat( $params );
+
return ( $stat === null ) ? null : (bool)$stat; // null => failure
}
final public function getFileTimestamp( array $params ) {
$section = new ProfileSection( __METHOD__ . "-{$this->name}" );
$stat = $this->getFileStat( $params );
+
return $stat ? $stat['mtime'] : false;
}
final public function getFileSize( array $params ) {
$section = new ProfileSection( __METHOD__ . "-{$this->name}" );
$stat = $this->getFileStat( $params );
+
return $stat ? $stat['size'] : false;
}
} else { // an error occurred
wfDebug( __METHOD__ . ": Could not stat file $path.\n" );
}
+
return $stat;
}
$contents[$path] = $fsFile ? file_get_contents( $fsFile->getPath() ) : false;
wfRestoreWarnings();
}
+
return $contents;
}
$hash = $this->doGetFileSha1Base36( $params );
wfProfileOut( __METHOD__ . '-miss-' . $this->name );
$this->cheapCache->set( $path, 'sha1', array( 'hash' => $hash, 'latest' => $latest ) );
+
return $hash;
}
$section = new ProfileSection( __METHOD__ . "-{$this->name}" );
$fsFile = $this->getLocalReference( $params );
$props = $fsFile ? $fsFile->getProps() : FSFile::placeholderProps();
+
return $props;
}
$res = null; // if we don't find anything, it is indeterminate
}
}
+
return $res;
}
}
wfDebug( __METHOD__ . ": iterating over all container shards.\n" );
// File listing spans multiple containers/shards
list( , $shortCont, ) = self::splitStoragePath( $params['dir'] );
+
return new FileBackendStoreShardDirIterator( $this,
$fullCont, $dir, $this->getContainerSuffixes( $shortCont ), $params );
}
wfDebug( __METHOD__ . ": iterating over all container shards.\n" );
// File listing spans multiple containers/shards
list( , $shortCont, ) = self::splitStoragePath( $params['dir'] );
+
return new FileBackendStoreShardFileIterator( $this,
$fullCont, $dir, $this->getContainerSuffixes( $shortCont ), $params );
}
public function getScopedLocksForOps( array $ops, Status $status ) {
$paths = $this->getPathsToLockForOpsInternal( $this->getOperationsInternal( $ops ) );
+
return array( $this->getScopedFileLocks( $paths, 'mixed', $status ) );
}
foreach ( $fileOpHandles as $fileOpHandle ) {
$fileOpHandle->closeResources();
}
+
return $res;
}
foreach ( $fileOpHandles as $fileOpHandle ) { // OK if empty
throw new MWException( "This backend supports no asynchronous operations." );
}
+
return array();
}
}
}
}
+
return $op;
}
* @param array $paths Storage paths (optional)
* @return void
*/
- protected function doClearCache( array $paths = null ) {}
+ protected function doClearCache( array $paths = null ) {
+ }
/**
* Is this a key/value store where directories are just virtual?
}
}
}
+
return array( null, null, null );
}
if ( $cShard !== null && substr( $relPath, -1 ) !== '/' ) {
return array( $container, $relPath );
}
+
return array( null, null );
}
if ( preg_match( "!^(?:[^/]{2,}/)*$hashDirRegex(?:/|$)!", $relPath, $m ) ) {
return '.' . implode( '', array_slice( $m, 1 ) );
}
+
return null; // failed to match
}
+
return ''; // no sharding
}
*/
final public function isSingleShardPathInternal( $storagePath ) {
list( , , $shard ) = $this->resolveStoragePath( $storagePath );
+
return ( $shard !== null );
}
}
}
}
+
return array( 0, 0, false ); // no sharding
}
$shards[] = '.' . wfBaseConvert( $index, 10, $base, $digits );
}
}
+
return $shards;
}
* @param array $containerInfo Map of resolved container names to cached info
* @return void
*/
- protected function doPrimeContainerCache( array $containerInfo ) {}
+ protected function doPrimeContainerCache( array $containerInfo ) {
+ }
/**
* Get the cache key for a file path
$opts['concurrency'] = $this->concurrency;
}
}
+
return $opts;
}
return false;
} else {
$this->multiShardPaths[$rel] = 1;
+
return true;
}
}
protected static function normalizeIfValidStoragePath( $path ) {
if ( FileBackend::isStoragePath( $path ) ) {
$res = FileBackend::normalizeStoragePath( $path );
+
return ( $res !== null ) ? $res : $path;
}
+
return $path;
}
final public function applyDependencies( array $deps ) {
$deps['read'] += array_fill_keys( $this->storagePathsRead(), 1 );
$deps['write'] += array_fill_keys( $this->storagePathsChanged(), 1 );
+
return $deps;
}
return true; // "flow" dependency
}
}
+
return false;
}
);
}
}
+
return array_merge( $nullEntries, $updateEntries, $deleteEntries );
}
if ( !$status->isOK() ) {
$this->failed = true;
}
+
return $status;
}
} else { // no-op
$status = Status::newGood();
}
+
return $status;
}
$this->async = true;
$result = $this->attempt();
$this->async = false;
+
return $result;
}
} else {
$this->overwriteSameCase = true; // OK
}
+
return $status; // do nothing; either OK or bad status
} else {
$status->fatal( 'backend-fail-alreadyexists', $this->params['dst'] );
+
return $status;
}
}
+
return $status;
}
return $predicates['exists'][$source]; // previous op assures this
} else {
$params = array( 'src' => $source, 'latest' => true );
+
return $this->backend->fileExists( $params );
}
}
return false; // previous op assures this
} else {
$params = array( 'src' => $source, 'latest' => true );
+
return $this->backend->getFileSha1Base36( $params );
}
}
$status->fatal( 'backend-fail-maxsize',
$this->params['dst'], $this->backend->maxFileSizeInternal() );
$status->fatal( 'backend-fail-create', $this->params['dst'] );
+
return $status;
// Check if a file can be placed/changed at the destination
} elseif ( !$this->backend->isPathUsableInternal( $this->params['dst'] ) ) {
$status->fatal( 'backend-fail-usable', $this->params['dst'] );
$status->fatal( 'backend-fail-create', $this->params['dst'] );
+
return $status;
}
// Check if destination file exists
$predicates['exists'][$this->params['dst']] = true;
$predicates['sha1'][$this->params['dst']] = $this->sourceSha1;
}
+
return $status; // safe to call attempt()
}
// Create the file at the destination
return $this->backend->createInternal( $this->setFlags( $this->params ) );
}
+
return Status::newGood();
}
// Check if the source file exists on the file system
if ( !is_file( $this->params['src'] ) ) {
$status->fatal( 'backend-fail-notexists', $this->params['src'] );
+
return $status;
// Check if the source file is too big
} elseif ( filesize( $this->params['src'] ) > $this->backend->maxFileSizeInternal() ) {
$status->fatal( 'backend-fail-maxsize',
$this->params['dst'], $this->backend->maxFileSizeInternal() );
$status->fatal( 'backend-fail-store', $this->params['src'], $this->params['dst'] );
+
return $status;
// Check if a file can be placed/changed at the destination
} elseif ( !$this->backend->isPathUsableInternal( $this->params['dst'] ) ) {
$status->fatal( 'backend-fail-usable', $this->params['dst'] );
$status->fatal( 'backend-fail-store', $this->params['src'], $this->params['dst'] );
+
return $status;
}
// Check if destination file exists
$predicates['exists'][$this->params['dst']] = true;
$predicates['sha1'][$this->params['dst']] = $this->sourceSha1;
}
+
return $status; // safe to call attempt()
}
// Store the file at the destination
return $this->backend->storeInternal( $this->setFlags( $this->params ) );
}
+
return Status::newGood();
}
if ( $hash !== false ) {
$hash = wfBaseConvert( $hash, 16, 36, 31 );
}
+
return $hash;
}
// Update file existence predicates (cache 404s)
$predicates['exists'][$this->params['src']] = false;
$predicates['sha1'][$this->params['src']] = false;
+
return $status; // nothing to do
} else {
$status->fatal( 'backend-fail-notexists', $this->params['src'] );
+
return $status;
}
- // Check if a file can be placed/changed at the destination
+ // Check if a file can be placed/changed at the destination
} elseif ( !$this->backend->isPathUsableInternal( $this->params['dst'] ) ) {
$status->fatal( 'backend-fail-usable', $this->params['dst'] );
$status->fatal( 'backend-fail-copy', $this->params['src'], $this->params['dst'] );
+
return $status;
}
// Check if destination file exists
$predicates['exists'][$this->params['dst']] = true;
$predicates['sha1'][$this->params['dst']] = $this->sourceSha1;
}
+
return $status; // safe to call attempt()
}
$status = Status::newGood(); // nothing to do
} elseif ( $this->params['src'] === $this->params['dst'] ) {
// Just update the destination file headers
- $headers = $this->getParam( 'headers' ) ?: array();
+ $headers = $this->getParam( 'headers' ) ? : array();
$status = $this->backend->describeInternal( $this->setFlags( array(
'src' => $this->params['dst'], 'headers' => $headers
) ) );
// Copy the file to the destination
$status = $this->backend->copyInternal( $this->setFlags( $this->params ) );
}
+
return $status;
}
// Update file existence predicates (cache 404s)
$predicates['exists'][$this->params['src']] = false;
$predicates['sha1'][$this->params['src']] = false;
+
return $status; // nothing to do
} else {
$status->fatal( 'backend-fail-notexists', $this->params['src'] );
+
return $status;
}
// Check if a file can be placed/changed at the destination
} elseif ( !$this->backend->isPathUsableInternal( $this->params['dst'] ) ) {
$status->fatal( 'backend-fail-usable', $this->params['dst'] );
$status->fatal( 'backend-fail-move', $this->params['src'], $this->params['dst'] );
+
return $status;
}
// Check if destination file exists
$predicates['exists'][$this->params['dst']] = true;
$predicates['sha1'][$this->params['dst']] = $this->sourceSha1;
}
+
return $status; // safe to call attempt()
}
// Move the file to the destination
$status = $this->backend->moveInternal( $this->setFlags( $this->params ) );
}
+
return $status;
}
// Update file existence predicates (cache 404s)
$predicates['exists'][$this->params['src']] = false;
$predicates['sha1'][$this->params['src']] = false;
+
return $status; // nothing to do
} else {
$status->fatal( 'backend-fail-notexists', $this->params['src'] );
+
return $status;
}
// Check if a file can be placed/changed at the source
} elseif ( !$this->backend->isPathUsableInternal( $this->params['src'] ) ) {
$status->fatal( 'backend-fail-usable', $this->params['src'] );
$status->fatal( 'backend-fail-delete', $this->params['src'] );
+
return $status;
}
// Update file existence predicates
$predicates['exists'][$this->params['src']] = false;
$predicates['sha1'][$this->params['src']] = false;
+
return $status; // safe to call attempt()
}
// Check if the source file exists
if ( !$this->fileExists( $this->params['src'], $predicates ) ) {
$status->fatal( 'backend-fail-notexists', $this->params['src'] );
+
return $status;
// Check if a file can be placed/changed at the source
} elseif ( !$this->backend->isPathUsableInternal( $this->params['src'] ) ) {
$status->fatal( 'backend-fail-usable', $this->params['src'] );
$status->fatal( 'backend-fail-describe', $this->params['src'] );
+
return $status;
}
// Update file existence predicates
$this->fileExists( $this->params['src'], $predicates );
$predicates['sha1'][$this->params['src']] =
$this->fileSha1( $this->params['src'], $predicates );
+
return $status; // safe to call attempt()
}
/**
* Placeholder operation that has no params and does nothing
*/
-class NullFileOp extends FileOp {}
+class NullFileOp extends FileOp {
+}
if ( $n > self::MAX_BATCH_SIZE ) {
$status->fatal( 'backend-fail-batchsize', $n, self::MAX_BATCH_SIZE );
wfProfileOut( __METHOD__ );
+
return $status;
}
++$status->failCount;
if ( !$ignoreErrors ) {
wfProfileOut( __METHOD__ );
+
return $status; // abort
}
}
$subStatus = $journal->logChangeBatch( $entries, $batchId );
if ( !$subStatus->isOK() ) {
wfProfileOut( __METHOD__ );
+
return $subStatus; // abort
}
}
self::runParallelBatches( $pPerformOps, $status );
wfProfileOut( __METHOD__ );
+
return $status;
}
}
}
}
+
return $status;
}
}
} else {
try { // look for APC, XCache, WinCache, ect...
$this->srvCache = ObjectCache::newAccelerator( array() );
- } catch ( Exception $e ) {}
+ } catch ( Exception $e ) {
+ }
}
}
$this->srvCache = $this->srvCache ? $this->srvCache : new EmptyBagOStuff();
} elseif ( strlen( urlencode( $relStoragePath ) ) > 1024 ) {
return null; // too long for Swift
}
+
return $relStoragePath;
}
try {
$this->getContainer( $container );
+
return true; // container exists
} catch ( NoSuchContainerException $e ) {
} catch ( CloudFilesException $e ) { // some other exception?
if ( isset( $headers['Content-Disposition'] ) ) {
$headers['Content-Disposition'] = $this->truncDisp( $headers['Content-Disposition'] );
}
+
return $headers;
}
break; // too long; sigh
}
}
+
return $res;
}
list( $dstCont, $dstRel ) = $this->resolveStoragePathReal( $params['dst'] );
if ( $dstRel === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['dst'] );
+
return $status;
}
$dContObj = $this->getContainer( $dstCont );
} catch ( NoSuchContainerException $e ) {
$status->fatal( 'backend-fail-create', $params['dst'] );
+
return $status;
} catch ( CloudFilesException $e ) { // some other exception?
$this->handleException( $e, $status, __METHOD__, $params );
+
return $status;
}
list( $dstCont, $dstRel ) = $this->resolveStoragePathReal( $params['dst'] );
if ( $dstRel === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['dst'] );
+
return $status;
}
$dContObj = $this->getContainer( $dstCont );
} catch ( NoSuchContainerException $e ) {
$status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
+
return $status;
} catch ( CloudFilesException $e ) { // some other exception?
$this->handleException( $e, $status, __METHOD__, $params );
+
return $status;
}
wfRestoreWarnings();
if ( $sha1Hash === false ) { // source doesn't exist?
$status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
+
return $status;
}
$sha1Hash = wfBaseConvert( $sha1Hash, 16, 36, 31 );
list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] );
if ( $srcRel === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['src'] );
+
return $status;
}
list( $dstCont, $dstRel ) = $this->resolveStoragePathReal( $params['dst'] );
if ( $dstRel === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['dst'] );
+
return $status;
}
if ( empty( $params['ignoreMissingSource'] ) || isset( $sContObj ) ) {
$status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
}
+
return $status;
} catch ( CloudFilesException $e ) { // some other exception?
$this->handleException( $e, $status, __METHOD__, $params );
+
return $status;
}
list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] );
if ( $srcRel === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['src'] );
+
return $status;
}
list( $dstCont, $dstRel ) = $this->resolveStoragePathReal( $params['dst'] );
if ( $dstRel === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['dst'] );
+
return $status;
}
if ( empty( $params['ignoreMissingSource'] ) || isset( $sContObj ) ) {
$status->fatal( 'backend-fail-move', $params['src'], $params['dst'] );
}
+
return $status;
} catch ( CloudFilesException $e ) { // some other exception?
$this->handleException( $e, $status, __METHOD__, $params );
+
return $status;
}
list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] );
if ( $srcRel === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['src'] );
+
return $status;
}
list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] );
if ( $srcRel === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['src'] );
+
return $status;
}
// (a) Check if container already exists
try {
$this->getContainer( $fullCont );
+
// NoSuchContainerException not thrown: container must exist
return $status; // already exists
} catch ( NoSuchContainerException $e ) {
// NoSuchContainerException thrown: container does not exist
} catch ( CloudFilesException $e ) { // some other exception?
$this->handleException( $e, $status, __METHOD__, $params );
+
return $status;
}
// CDN not enabled; nothing to see here
} catch ( CloudFilesException $e ) { // some other exception?
$this->handleException( $e, $status, __METHOD__, $params );
+
return $status;
}
return $status; // ok, nothing to do
} catch ( CloudFilesException $e ) { // some other exception?
$this->handleException( $e, $status, __METHOD__, $params );
+
return $status;
}
return $status; // race? consistency delay?
} catch ( CloudFilesException $e ) { // some other exception?
$this->handleException( $e, $status, __METHOD__, $params );
+
return $status;
}
}
*/
protected function convertSwiftDate( $ts, $format = TS_MW ) {
$timestamp = new MWTimestamp( $ts );
+
return $timestamp->getTimestamp( $format );
}
$obj->setMetadataValues( array( 'Sha1base36' => $hash ) );
$obj->sync_metadata(); // save to Swift
wfProfileOut( __METHOD__ );
+
return true; // success
}
}
trigger_error( "Unable to set SHA-1 metadata for $path", E_USER_WARNING );
$obj->setMetadataValues( array( 'Sha1base36' => false ) );
wfProfileOut( __METHOD__ );
+
return false; // failed
}
try {
$container = $this->getContainer( $fullCont );
$prefix = ( $dir == '' ) ? null : "{$dir}/";
+
return ( count( $container->list_objects( 1, null, $prefix ) ) > 0 );
} catch ( NoSuchContainerException $e ) {
return false;
if ( is_object( $object ) ) {
$stat = array(
// Convert various random Swift dates to TS_MW
- 'mtime' => $this->convertSwiftDate( $object->last_modified, TS_MW ),
- 'size' => (int)$object->content_length,
+ 'mtime' => $this->convertSwiftDate( $object->last_modified, TS_MW ),
+ 'size' => (int)$object->content_length,
'latest' => false // eventually consistent
);
$names[] = array( $object->name, $stat );
$names[] = array( $object, null );
}
}
+
return $names;
}
$this->clearCache( array( $params['src'] ) );
$stat = $this->getFileStat( $params );
}
+
return $stat['sha1'];
} else {
return false;
$cont = $this->getContainer( $srcCont );
} catch ( NoSuchContainerException $e ) {
$status->fatal( 'backend-fail-stream', $params['src'] );
+
return $status;
} catch ( CloudFilesException $e ) { // some other exception?
$this->handleException( $e, $status, __METHOD__, $params );
+
return $status;
}
public function getFileHttpUrl( array $params ) {
if ( $this->swiftTempUrlKey != '' ||
- ( $this->rgwS3AccessKey != '' && $this->rgwS3SecretKey != '' ) )
- {
+ ( $this->rgwS3AccessKey != '' && $this->rgwS3SecretKey != '' )
+ ) {
list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] );
if ( $srcRel === null ) {
return null; // invalid path
$this->rgwS3SecretKey,
true // raw
) );
+
// See http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html.
// Note: adding a newline for empty CanonicalizedAmzHeaders does not work.
return wfAppendQuery(
$this->handleException( $e, null, __METHOD__, $params );
}
}
+
return null;
}
if ( !empty( $params['latest'] ) ) {
$hdrs[] = 'X-Newest: true';
}
+
return $hdrs;
}
}
$this->conn = new CF_Connection( $this->auth );
}
+
return $this->conn;
}
);
}
}
+
return $this->connContainerCache->get( $container, 'obj' );
}
* This also sets the Status object to have a fatal error.
*
* @param Exception $e
- * @param Status $status|null
+ * @param Status $status null
* @param string $func
* @param array $params
* @return void
*
* @param string $container Resolved container name
* @param string $dir Resolved path relative to container
- * @param string $after|null
+ * @param string $after null
* @param integer $limit
* @param array $params
* @return Traversable|Array
$storageDir = rtrim( $this->params['dir'], '/' );
$this->backend->loadListingStatInternal( "$storageDir/$relPath", $stat );
}
+
return $relPath;
}
}
if ( $attempt >= 5 ) {
wfProfileOut( __METHOD__ );
+
return null; // give up
}
}
$tmpFile = new self( $path );
$tmpFile->canDelete = true; // safely instantiated
wfProfileOut( __METHOD__ );
+
return $tmpFile;
}
wfSuppressWarnings();
$ok = unlink( $this->path );
wfRestoreWarnings();
+
return $ok;
}
}
$object->tempFSFileReferences[] = $this;
}
+
return $this;
}
*/
public function preserve() {
$this->canDelete = false;
+
return $this;
}
*/
public function autocollect() {
$this->canDelete = true;
+
return $this;
}
$dbw = $this->getMasterDB();
} catch ( DBError $e ) {
$status->fatal( 'filejournal-fail-dbconnect', $this->backend );
+
return $status;
}
}
} catch ( DBError $e ) {
$status->fatal( 'filejournal-fail-dbquery', $this->backend );
+
return $status;
}
$dbw = $this->getMasterDB();
$encTimestamp = $dbw->addQuotes( $dbw->timestamp( $time ) );
+
return $dbw->selectField( 'filejournal', 'fj_id',
array( 'fj_backend' => $this->backend, "fj_timestamp <= $encTimestamp" ),
__METHOD__,
$this->dbw = $lb->getConnection( DB_MASTER, array(), $this->wiki );
$this->dbw->clearFlag( DBO_TRX );
}
+
return $this->dbw;
}
}
throw new MWException( "Class given is not an instance of FileJournal." );
}
$jrn->backend = $backend;
+
return $jrn;
}
$s .= mt_rand( 0, 2147483647 );
}
$s = wfBaseConvert( sha1( $s ), 16, 36, 31 );
+
return substr( wfBaseConvert( wfTimestamp( TS_MW ), 10, 36, 9 ) . $s, 0, 31 );
}
if ( !count( $entries ) ) {
return Status::newGood();
}
+
return $this->doLogChangeBatch( $entries, $batchId );
}
* path : affected storage path
* new_sha1 : base 36 sha1 of the new file had the operation succeeded
* timestamp : TS_MW timestamp of the batch change
-
* Also, $next is updated to the ID of the next entry.
*
* @param $start integer Starting change ID or null
} else {
$next = null; // end of list
}
+
return $entries;
}
foreach ( $pathsByType as $type => $paths ) {
$status->merge( $this->doGetLocksOnServer( $lockSrv, $paths, $type ) );
}
+
return $status;
}
$this->getConnection( $lockSrv );
} catch ( DBError $e ) {
$this->cacheRecordFailure( $lockSrv );
+
return false; // failed to connect
}
+
return true;
}
if ( !$this->conns[$lockDb]->trxLevel() ) {
$this->conns[$lockDb]->begin( __METHOD__ ); // start transaction
}
+
return $this->conns[$lockDb];
}
* @return void
* @throws DBError
*/
- protected function initConnection( $lockDb, DatabaseBase $db ) {}
+ protected function initConnection( $lockDb, DatabaseBase $db ) {
+ }
/**
* Checks if the DB has not recently had connection/query errors.
$db = $this->getConnection( $lockSrv ); // checked in isServerUp()
$bigints = array_unique( array_map(
- function( $key ) {
+ function ( $key ) {
return wfBaseConvert( substr( $key, 0, 15 ), 16, 10 );
},
array_map( array( $this, 'sha1Base16Absolute' ), $paths )
} else {
// Abort and unlock everything
$status->merge( $this->doUnlock( $lockedPaths, $type ) );
+
return $status;
}
}
$status->warning( 'lockmanager-fail-closelock', $path );
}
}
+
return $status;
}
}
unset( $this->handles[$path] );
}
+
return $status;
}
if ( $response === false ) {
return false;
}
+
return trim( $response );
}
stream_set_timeout( $conn, $sec, $usec );
$this->conns[$lockSrv] = $conn;
}
+
return $this->conns[$lockSrv];
}
$elapsed = microtime( true ) - $start;
} while ( $elapsed < $timeout && $elapsed >= 0 );
wfProfileOut( __METHOD__ );
+
return $status;
}
$pathsByType = $this->normalizePathsByType( $pathsByType );
$status = $this->doUnlockByType( $pathsByType );
wfProfileOut( __METHOD__ );
+
return $status;
}
foreach ( $pathsByType as $type => $paths ) {
$res[$this->lockTypeMap[$type]] = array_unique( $paths );
}
+
return $res;
}
break;
}
}
+
return $status;
}
foreach ( $pathsByType as $type => $paths ) {
$status->merge( $this->doUnlock( $paths, $type ) );
}
+
return $status;
}
self::$instances[$domain] = new self( $domain );
self::$instances[$domain]->initFromGlobals();
}
+
return self::$instances[$domain];
}
$config = $this->managers[$name]['config'];
$this->managers[$name]['instance'] = new $class( $config );
}
+
return $this->managers[$name]['instance'];
}
throw new MWException( "No lock manager defined with the name `$name`." );
}
$class = $this->managers[$name]['class'];
+
return array( 'class' => $class ) + $this->managers[$name]['config'];
}
foreach ( $paths as $path ) {
$status->fatal( 'lockmanager-fail-acquirelock', $path );
}
+
return $status;
}
foreach ( $paths as $path ) {
$status->fatal( 'lockmanager-fail-releaselock', $path );
}
+
return;
}
return null; // server appears to be down
}
}
+
return $memc;
}
return $a;
} else {
trigger_error( __METHOD__ . ": reset invalid lock array.", E_USER_WARNING );
+
return self::newLockArray();
}
}
$status->merge( $this->doLockingRequestBucket( $bucket, $pathsToLockByType ) );
if ( !$status->isOK() ) {
$status->merge( $this->doUnlockByType( $lockedPaths ) );
+
return $status;
}
// Record these locks as active
foreach ( $paths as $path ) {
$status->fatal( 'lockmanager-fail-acquirelock', $path );
}
+
return $status;
}
foreach ( $paths as $path ) {
$status->fatal( 'lockmanager-fail-releaselock', $path );
}
+
return $status;
}
if ( $lockStatus->isOK() ) {
return new self( $manager, $pathsByType, $status );
}
+
return null;
}