}
$this->lockManager = isset( $config['lockManager'] )
? $config['lockManager']
- : new NullLockManager( array() );
+ : new NullLockManager( [] );
$this->fileJournal = isset( $config['fileJournal'] )
? $config['fileJournal']
- : FileJournal::factory( array( 'class' => 'NullFileJournal' ), $this->name );
+ : FileJournal::factory( [ 'class' => 'NullFileJournal' ], $this->name );
$this->readOnly = isset( $config['readOnly'] )
? (string)$config['readOnly']
: '';
* - describe (since 1.21)
* - null
*
+ * FSFile/TempFSFile object support was added in 1.27.
+ *
* a) Create a new file in storage with the contents of a string
* @code
* array(
* @code
* array(
* 'op' => 'store',
- * 'src' => <file system path>,
+ * 'src' => <file system path, FSFile, or TempFSFile>,
* 'dst' => <storage path>,
* 'overwrite' => <boolean>,
* 'overwriteSame' => <boolean>,
* @param array $opts Batch operation options
* @return Status
*/
- final public function doOperations( array $ops, array $opts = array() ) {
+ final public function doOperations( array $ops, array $opts = [] ) {
if ( empty( $opts['bypassReadOnly'] ) && $this->isReadOnly() ) {
return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly );
}
if ( !count( $ops ) ) {
return Status::newGood(); // nothing to do
}
+
+ $ops = $this->resolveFSFileObjects( $ops );
if ( empty( $opts['force'] ) ) { // sanity
unset( $opts['nonLocking'] );
}
+
/** @noinspection PhpUnusedLocalVariableInspection */
$scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
+
return $this->doOperationsInternal( $ops, $opts );
}
* @param array $opts Operation options
* @return Status
*/
- final public function doOperation( array $op, array $opts = array() ) {
- return $this->doOperations( array( $op ), $opts );
+ final public function doOperation( array $op, array $opts = [] ) {
+ return $this->doOperations( [ $op ], $opts );
}
/**
* @param array $opts Operation options
* @return Status
*/
- final public function create( array $params, array $opts = array() ) {
- return $this->doOperation( array( 'op' => 'create' ) + $params, $opts );
+ final public function create( array $params, array $opts = [] ) {
+ return $this->doOperation( [ 'op' => 'create' ] + $params, $opts );
}
/**
* @param array $opts Operation options
* @return Status
*/
- final public function store( array $params, array $opts = array() ) {
- return $this->doOperation( array( 'op' => 'store' ) + $params, $opts );
+ final public function store( array $params, array $opts = [] ) {
+ return $this->doOperation( [ 'op' => 'store' ] + $params, $opts );
}
/**
* @param array $opts Operation options
* @return Status
*/
- final public function copy( array $params, array $opts = array() ) {
- return $this->doOperation( array( 'op' => 'copy' ) + $params, $opts );
+ final public function copy( array $params, array $opts = [] ) {
+ return $this->doOperation( [ 'op' => 'copy' ] + $params, $opts );
}
/**
* @param array $opts Operation options
* @return Status
*/
- final public function move( array $params, array $opts = array() ) {
- return $this->doOperation( array( 'op' => 'move' ) + $params, $opts );
+ final public function move( array $params, array $opts = [] ) {
+ return $this->doOperation( [ 'op' => 'move' ] + $params, $opts );
}
/**
* @param array $opts Operation options
* @return Status
*/
- final public function delete( array $params, array $opts = array() ) {
- return $this->doOperation( array( 'op' => 'delete' ) + $params, $opts );
+ final public function delete( array $params, array $opts = [] ) {
+ return $this->doOperation( [ 'op' => 'delete' ] + $params, $opts );
}
/**
* @return Status
* @since 1.21
*/
- final public function describe( array $params, array $opts = array() ) {
- return $this->doOperation( array( 'op' => 'describe' ) + $params, $opts );
+ final public function describe( array $params, array $opts = [] ) {
+ return $this->doOperation( [ 'op' => 'describe' ] + $params, $opts );
}
/**
* - describe (since 1.21)
* - null
*
+ * FSFile/TempFSFile object support was added in 1.27.
+ *
* a) Create a new file in storage with the contents of a string
* @code
* array(
* @code
* array(
* 'op' => 'store',
- * 'src' => <file system path>,
+ * 'src' => <file system path, FSFile, or TempFSFile>,
* 'dst' => <storage path>,
* 'headers' => <HTTP header name/value map> # since 1.21
* )
* @return Status
* @since 1.20
*/
- final public function doQuickOperations( array $ops, array $opts = array() ) {
+ final public function doQuickOperations( array $ops, array $opts = [] ) {
if ( empty( $opts['bypassReadOnly'] ) && $this->isReadOnly() ) {
return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly );
}
if ( !count( $ops ) ) {
return Status::newGood(); // nothing to do
}
+
+ $ops = $this->resolveFSFileObjects( $ops );
foreach ( $ops as &$op ) {
$op['overwrite'] = true; // avoids RTTs in key/value stores
}
+
/** @noinspection PhpUnusedLocalVariableInspection */
$scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
+
return $this->doQuickOperationsInternal( $ops );
}
* @since 1.20
*/
final public function doQuickOperation( array $op ) {
- return $this->doQuickOperations( array( $op ) );
+ return $this->doQuickOperations( [ $op ] );
}
/**
* @since 1.20
*/
final public function quickCreate( array $params ) {
- return $this->doQuickOperation( array( 'op' => 'create' ) + $params );
+ return $this->doQuickOperation( [ 'op' => 'create' ] + $params );
}
/**
* @since 1.20
*/
final public function quickStore( array $params ) {
- return $this->doQuickOperation( array( 'op' => 'store' ) + $params );
+ return $this->doQuickOperation( [ 'op' => 'store' ] + $params );
}
/**
* @since 1.20
*/
final public function quickCopy( array $params ) {
- return $this->doQuickOperation( array( 'op' => 'copy' ) + $params );
+ return $this->doQuickOperation( [ 'op' => 'copy' ] + $params );
}
/**
* @since 1.20
*/
final public function quickMove( array $params ) {
- return $this->doQuickOperation( array( 'op' => 'move' ) + $params );
+ return $this->doQuickOperation( [ 'op' => 'move' ] + $params );
}
/**
* @since 1.20
*/
final public function quickDelete( array $params ) {
- return $this->doQuickOperation( array( 'op' => 'delete' ) + $params );
+ return $this->doQuickOperation( [ 'op' => 'delete' ] + $params );
}
/**
* @since 1.21
*/
final public function quickDescribe( array $params ) {
- return $this->doQuickOperation( array( 'op' => 'describe' ) + $params );
+ return $this->doQuickOperation( [ 'op' => 'describe' ] + $params );
}
/**
*/
final public function getFileContents( array $params ) {
$contents = $this->getFileContentsMulti(
- array( 'srcs' => array( $params['src'] ) ) + $params );
+ [ 'srcs' => [ $params['src'] ] ] + $params );
return $contents[$params['src']];
}
*/
final public function getLocalReference( array $params ) {
$fsFiles = $this->getLocalReferenceMulti(
- array( 'srcs' => array( $params['src'] ) ) + $params );
+ [ 'srcs' => [ $params['src'] ] ] + $params );
return $fsFiles[$params['src']];
}
*/
final public function getLocalCopy( array $params ) {
$tmpFiles = $this->getLocalCopyMulti(
- array( 'srcs' => array( $params['src'] ) ) + $params );
+ [ 'srcs' => [ $params['src'] ] ] + $params );
return $tmpFiles[$params['src']];
}
* @since 1.20
*/
final public function getTopDirectoryList( array $params ) {
- return $this->getDirectoryList( array( 'topOnly' => true ) + $params );
+ return $this->getDirectoryList( [ 'topOnly' => true ] + $params );
}
/**
* @since 1.20
*/
final public function getTopFileList( array $params ) {
- return $this->getFileList( array( 'topOnly' => true ) + $params );
+ return $this->getFileList( [ 'topOnly' => true ] + $params );
}
/**
return $this->fileJournal;
}
+ /**
+ * Convert FSFile 'src' paths to string paths (with an 'srcRef' field set to the FSFile)
+ *
+ * The 'srcRef' field keeps any TempFSFile objects in scope for the backend to have it
+ * around as long it needs (which may vary greatly depending on configuration)
+ *
+ * @param array $ops File operation batch for FileBaclend::doOperations()
+ * @return array File operation batch
+ */
+ protected function resolveFSFileObjects( array $ops ) {
+ foreach ( $ops as &$op ) {
+ $src = isset( $op['src'] ) ? $op['src'] : null;
+ if ( $src instanceof FSFile ) {
+ $op['srcRef'] = $src;
+ $op['src'] = $src->getPath();
+ }
+ }
+ unset( $op );
+
+ return $ops;
+ }
+
/**
* Check if a given path is a "mwstore://" path.
* This does not do any further validation or any existence checks.
if ( count( $parts ) == 3 ) {
return $parts; // e.g. "backend/container/path"
} else {
- return array( $parts[0], $parts[1], '' ); // e.g. "backend/container"
+ return [ $parts[0], $parts[1], '' ]; // e.g. "backend/container"
}
}
}
- return array( null, null, null );
+ return [ null, null, null ];
}
/**
* @since 1.20
*/
final public static function makeContentDisposition( $type, $filename = '' ) {
- $parts = array();
+ $parts = [];
$type = strtolower( $type );
- if ( !in_array( $type, array( 'inline', 'attachment' ) ) ) {
+ if ( !in_array( $type, [ 'inline', 'attachment' ] ) ) {
throw new FileBackendError( "Invalid Content-Disposition type '$type'." );
}
$parts[] = $type;