Go to the documentation of this file.
23 use Psr\Log\LoggerInterface;
89 list( $required, $optional, $paths ) = $this->
allowedParams();
90 foreach ( $required as $name ) {
91 if ( isset(
$params[$name] ) ) {
92 $this->params[$name] =
$params[$name];
94 throw new InvalidArgumentException(
"File operation missing parameter '$name'." );
97 foreach ( $optional as $name ) {
98 if ( isset(
$params[$name] ) ) {
99 $this->params[$name] =
$params[$name];
102 foreach ( $paths as $name ) {
103 if ( isset( $this->params[$name] ) ) {
142 return $this->params[$name] ??
null;
160 return [ self::ASSUMED_EXISTS => [], self::ASSUMED_SHA1 => [], self::ASSUMED_SIZE => [] ];
169 return [
'read' => [],
'write' => [] ];
193 if ( isset( $deps[
'read'][
$path] ) || isset( $deps[
'write'][
$path] ) ) {
198 if ( isset( $deps[
'write'][
$path] ) ) {
214 if ( $this->cancelled ) {
224 'newSha1' => $this->
fileSha1( $path, $oPredicates )
228 if ( $nPredicates[self::ASSUMED_SHA1][
$path] ===
false ) {
236 'op' => $this->
fileExists( $path, $oPredicates ) ?
'update' :
'create',
243 return array_merge( $nullEntries, $updateEntries, $deleteEntries );
254 final public function precheck( array &$predicates ) {
255 if ( $this->state !== self::STATE_NEW ) {
262 if ( !$this->backend->isPathUsableInternal(
$path ) ) {
263 $status->fatal(
'backend-fail-usable',
$path );
266 if ( !$status->isOK() ) {
271 if ( !$status->isOK() ) {
292 if ( $this->state !== self::STATE_CHECKED ) {
294 } elseif ( $this->
failed ) {
298 if ( $this->cancelled ) {
302 if ( !$status->isOK() ) {
326 $this->async =
false;
359 return [ [], [], [] ];
396 return array_values( array_unique(
413 if ( $this->sourceSize ===
null ) {
414 $this->sourceSize = $this->
fileSize( $this->params[
'src'], $predicates );
418 if ( $this->sourceSha1 ===
null ) {
419 $this->sourceSha1 = $this->
fileSha1( $this->params[
'src'], $predicates );
422 $this->destExists = $this->
fileExists( $this->params[
'dst'], $predicates );
424 $this->overwriteSameCase =
false;
425 if ( $this->destExists ) {
426 if ( $this->
getParam(
'overwrite' ) ) {
428 } elseif ( $this->
getParam(
'overwriteSame' ) ) {
430 $dhash = $this->
fileSha1( $this->params[
'dst'], $predicates );
431 $dsize = $this->
fileSize( $this->params[
'dst'], $predicates );
433 if ( !strlen( $this->sourceSha1 ) || !strlen( $dhash ) ) {
434 $status->fatal(
'backend-fail-hashes' );
435 } elseif ( !is_int( $this->sourceSize ) || !is_int( $dsize ) ) {
436 $status->fatal(
'backend-fail-sizes' );
437 } elseif ( $this->sourceSha1 !== $dhash || $this->sourceSize !== $dsize ) {
439 $status->fatal(
'backend-fail-notsame', $this->params[
'dst'] );
441 $this->overwriteSameCase =
true;
444 $status->fatal(
'backend-fail-alreadyexists', $this->params[
'dst'] );
446 } elseif ( $this->destExists === FileBackend::EXISTENCE_ERROR ) {
447 $status->fatal(
'backend-fail-stat', $this->params[
'dst'] );
484 if ( isset( $predicates[self::ASSUMED_EXISTS][
$source] ) ) {
489 return $this->backend->fileExists(
$params );
505 if ( isset( $predicates[self::ASSUMED_SIZE][
$source] ) ) {
508 isset( $predicates[self::ASSUMED_EXISTS][
$source] ) &&
509 !$predicates[self::ASSUMED_EXISTS][
$source]
515 return $this->backend->getFileSize(
$params );
527 if ( isset( $predicates[self::ASSUMED_SHA1][
$source] ) ) {
530 isset( $predicates[self::ASSUMED_EXISTS][
$source] ) &&
531 !$predicates[self::ASSUMED_EXISTS][
$source]
537 return $this->backend->getFileSha1Base36(
$params );
557 $params[
'failedAction'] = $action;
559 $this->logger->error( static::class .
561 }
catch ( Exception $e ) {
logFailure( $action)
Log a file operation failure and preserve any temp files.
setBatchId( $batchId)
Set the batch UUID this operation belongs to.
fileSha1( $source, array $predicates)
Get the SHA-1 of a file in storage when this operation is attempted.
static newFatal( $message,... $parameters)
Factory function for fatal errors.
allowedParams()
Get the file operation parameters.
attemptAsyncQuick()
Attempt the operation in the background without regards to prechecks.
FileBackend helper class for representing operations.
attemptQuick()
Attempt the operation without regards to prechecks.
precheck(array &$predicates)
Check preconditions of the operation without writing anything.
static normalizeStoragePath( $storagePath)
Normalize a storage path by cleaning up directory separators.
getJournalEntries(array $oPredicates, array $nPredicates)
Get the file journal entries for this file operation.
doPrecheck(array &$predicates)
storagePathsChanged()
Get a list of storage paths written to for this operation.
applyDependencies(array $deps)
Update a dependency tracking array to account for this operation.
attemptAsync()
Attempt the operation in the background.
__construct(FileBackendStore $backend, array $params, LoggerInterface $logger)
Build a new batch file operation transaction.
getBackend()
Get the backend this operation is for.
getSourceSize()
precheckDestExistence() helper function to get the source file size.
failed()
Check if this operation failed precheck() or attempt()
static isStoragePath( $path)
Check if a given path is a "mwstore://" path.
setFlags(array $params)
Adjust params to FileBackendStore internal file calls.
fileSize( $source, array $predicates)
Get the size a file in storage will have when this operation is attempted.
FileBackendStore $backend
attempt()
Attempt the operation.
getParam( $name)
Get the value of the parameter with the given name.
dependsOn(array $deps)
Check if this operation changes files listed in $paths.
static newGood( $value=null)
Factory function for good results.
Base class for all backends using particular storage medium.
getSourceSha1Base36()
precheckDestExistence() helper function to get the source file SHA-1.
fileExists( $source, array $predicates)
Check if a file will exist in storage when this operation is attempted.
precheckDestExistence(array $predicates)
Check for errors with regards to the destination file already existing.
static newDependencies()
Get a new empty dependency tracking array for paths read/written to.
static normalizeIfValidStoragePath( $path)
Normalize a string if it is a valid storage path.
storagePathsReadOrChanged()
Get a list of storage paths read from or written to for this operation.
static newPredicates()
Get a new empty predicates array for precheck()
storagePathsRead()
Get a list of storage paths read from for this operation.