From: Aaron Schulz Date: Fri, 16 Sep 2016 22:55:40 +0000 (-0700) Subject: Make Status extend StatusValue and start FileBackend update X-Git-Tag: 1.31.0-rc.0~5504^2 X-Git-Url: https://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/banques/?a=commitdiff_plain;h=c64c3ef9a8f33d89df9a801efa6c1d498f8722b1;p=lhc%2Fweb%2Fwiklou.git Make Status extend StatusValue and start FileBackend update * This avoids code duplication. * Callers can safely start type-hinting StatusValue as well. * Also moved the wrap() logic out of Status::__construct(), which only wrap() was (and should have been) using. Use "static" as well, so subclass behave properly. * The docs and type-hints in /filebackend are updated as an example. * A migration pattern is to inject a StatusValue wrapper into the backend and use it on all returned statuses, so MediaWiki will still get Status for message methods. Change-Id: Iff9255f34870ea6b0c4b91f6ddc69eea95186aba --- diff --git a/includes/Status.php b/includes/Status.php index a6348b7165..07828fec7c 100644 --- a/includes/Status.php +++ b/includes/Status.php @@ -37,34 +37,10 @@ * developer of the calling code is reminded that the function can fail, and * so that a lack of error-handling will be explicit. */ -class Status { - /** @var StatusValue */ - protected $sv; - - /** @var mixed */ - public $value; - /** @var array Map of (key => bool) to indicate success of each part of batch operations */ - public $success = []; - /** @var int Counter for batch operations */ - public $successCount = 0; - /** @var int Counter for batch operations */ - public $failCount = 0; - +class Status extends StatusValue { /** @var callable */ public $cleanCallback = false; - /** - * @param StatusValue $sv [optional] - */ - public function __construct( StatusValue $sv = null ) { - $this->sv = ( $sv === null ) ? new StatusValue() : $sv; - // B/C field aliases - $this->value =& $this->sv->value; - $this->successCount =& $this->sv->successCount; - $this->failCount =& $this->sv->failCount; - $this->success =& $this->sv->success; - } - /** * Succinct helper method to wrap a StatusValue * @@ -77,119 +53,83 @@ class Status { * @return Status */ public static function wrap( $sv ) { - return $sv instanceof Status ? $sv : new self( $sv ); + if ( $sv instanceof static ) { + return $sv; + } + + $result = new static(); + $result->ok =& $sv->ok; + $result->errors =& $sv->errors; + $result->value =& $sv->value; + $result->successCount =& $sv->successCount; + $result->failCount =& $sv->failCount; + $result->success =& $sv->success; + + return $result; } /** - * Factory function for fatal errors + * Backwards compatibility logic * - * @param string|Message $message Message name or object - * @return Status + * @param string $name + * @return mixed + * @throws RuntimeException */ - public static function newFatal( $message /*, parameters...*/ ) { - return new self( call_user_func_array( - [ 'StatusValue', 'newFatal' ], func_get_args() - ) ); + function __get( $name ) { + if ( $name === 'ok' ) { + return $this->isOK(); + } elseif ( $name === 'errors' ) { + return $this->getErrors(); + } + + throw new RuntimeException( "Cannot get '$name' property." ); } /** - * Factory function for good results + * Change operation result + * Backwards compatibility logic * + * @param string $name * @param mixed $value - * @return Status + * @throws RuntimeException */ - public static function newGood( $value = null ) { - $sv = new StatusValue(); - $sv->value = $value; - - return new self( $sv ); + function __set( $name, $value ) { + if ( $name === 'ok' ) { + $this->setOK( $value ); + } elseif ( !property_exists( $this, $name ) ) { + // Caller is using undeclared ad-hoc properties + $this->$name = $value; + } else { + throw new RuntimeException( "Cannot set '$name' property." ); + } } /** * Splits this Status object into two new Status objects, one which contains only * the error messages, and one that contains the warnings, only. The returned array is * defined as: - * array( - * 0 => object(Status) # the Status with error messages, only - * 1 => object(Status) # The Status with warning messages, only - * ) + * [ + * 0 => object(Status) # the Status with error messages, only + * 1 => object(Status) # The Status with warning messages, only + * ] * * @return array */ public function splitByErrorType() { - list( $errorsOnlyStatusValue, $warningsOnlyStatusValue ) = $this->sv->splitByErrorType(); - $errorsOnlyStatus = new Status( $errorsOnlyStatusValue ); - $warningsOnlyStatus = new Status( $warningsOnlyStatusValue ); - $errorsOnlyStatus->cleanCallback = $warningsOnlyStatus->cleanCallback = $this->cleanCallback; + list( $errorsOnlyStatus, $warningsOnlyStatus ) = parent::splitByErrorType(); + $errorsOnlyStatus->cleanCallback = + $warningsOnlyStatus->cleanCallback = $this->cleanCallback; return [ $errorsOnlyStatus, $warningsOnlyStatus ]; } - /** - * Change operation result - * - * @param bool $ok Whether the operation completed - * @param mixed $value - */ - public function setResult( $ok, $value = null ) { - $this->sv->setResult( $ok, $value ); - } - /** * Returns the wrapped StatusValue object * @return StatusValue * @since 1.27 */ public function getStatusValue() { - return $this->sv; - } - - /** - * Returns whether the operation completed and didn't have any error or - * warnings - * - * @return bool - */ - public function isGood() { - return $this->sv->isGood(); - } - - /** - * Returns whether the operation completed - * - * @return bool - */ - public function isOK() { - return $this->sv->isOK(); - } - - /** - * Add a new warning - * - * @param string|Message $message Message name or object - */ - public function warning( $message /*, parameters... */ ) { - call_user_func_array( [ $this->sv, 'warning' ], func_get_args() ); - } - - /** - * Add an error, do not set fatal flag - * This can be used for non-fatal errors - * - * @param string|Message $message Message name or object - */ - public function error( $message /*, parameters... */ ) { - call_user_func_array( [ $this->sv, 'error' ], func_get_args() ); - } - - /** - * Add an error and set OK to false, indicating that the operation - * as a whole was fatal - * - * @param string|Message $message Message name or object - */ - public function fatal( $message /*, parameters... */ ) { - call_user_func_array( [ $this->sv, 'fatal' ], func_get_args() ); + return $this; } /** @@ -237,16 +177,16 @@ class Status { public function getWikiText( $shortContext = false, $longContext = false, $lang = null ) { $lang = $this->languageFromParam( $lang ); - $rawErrors = $this->sv->getErrors(); + $rawErrors = $this->getErrors(); if ( count( $rawErrors ) == 0 ) { - if ( $this->sv->isOK() ) { - $this->sv->fatal( 'internalerror_info', + if ( $this->isOK() ) { + $this->fatal( 'internalerror_info', __METHOD__ . " called for a good result, this is incorrect\n" ); } else { - $this->sv->fatal( 'internalerror_info', + $this->fatal( 'internalerror_info', __METHOD__ . ": Invalid result object: no error text but not OK\n" ); } - $rawErrors = $this->sv->getErrors(); // just added a fatal + $rawErrors = $this->getErrors(); // just added a fatal } if ( count( $rawErrors ) == 1 ) { $s = $this->getErrorMessage( $rawErrors[0], $lang )->plain(); @@ -285,24 +225,24 @@ class Status { * * If both parameters are missing, and there is only one error, no bullet will be added. * - * @param string|string[] $shortContext A message name or an array of message names. - * @param string|string[] $longContext A message name or an array of message names. + * @param string|string[]|bool $shortContext A message name or an array of message names. + * @param string|string[]|bool $longContext A message name or an array of message names. * @param string|Language $lang Language to use for processing messages * @return Message */ public function getMessage( $shortContext = false, $longContext = false, $lang = null ) { $lang = $this->languageFromParam( $lang ); - $rawErrors = $this->sv->getErrors(); + $rawErrors = $this->getErrors(); if ( count( $rawErrors ) == 0 ) { - if ( $this->sv->isOK() ) { - $this->sv->fatal( 'internalerror_info', + if ( $this->isOK() ) { + $this->fatal( 'internalerror_info', __METHOD__ . " called for a good result, this is incorrect\n" ); } else { - $this->sv->fatal( 'internalerror_info', + $this->fatal( 'internalerror_info', __METHOD__ . ": Invalid result object: no error text but not OK\n" ); } - $rawErrors = $this->sv->getErrors(); // just added a fatal + $rawErrors = $this->getErrors(); // just added a fatal } if ( count( $rawErrors ) == 1 ) { $s = $this->getErrorMessage( $rawErrors[0], $lang ); @@ -333,12 +273,12 @@ class Status { } /** - * Return the message for a single error. + * Return the message for a single error * - * @param mixed $error With an array & two values keyed by - * 'message' and 'params', use those keys-value pairs. - * Otherwise, if its an array, just use the first value as the - * message and the remaining items as the params. + * The code string can be used a message key with per-language versions. + * If $error is an array, the "params" field is a list of parameters for the message. + * + * @param array|string $error Code string or (key: code string, params: string[]) map * @param string|Language $lang Language to use for processing messages * @return Message */ @@ -354,8 +294,10 @@ class Status { $msg = wfMessage( $msgName, array_map( 'wfEscapeWikiText', $this->cleanParams( $error ) ) ); } - } else { + } elseif ( is_string( $error ) ) { $msg = wfMessage( $error ); + } else { + throw new UnexpectedValueException( "Got " . get_class( $error ) . " for key." ); } $msg->inLanguage( $this->languageFromParam( $lang ) ); @@ -363,12 +305,11 @@ class Status { } /** - * Get the error message as HTML. This is done by parsing the wikitext error - * message. - * @param string $shortContext A short enclosing context message name, to + * Get the error message as HTML. This is done by parsing the wikitext error message + * @param string|bool $shortContext A short enclosing context message name, to * be used when there is a single error - * @param string $longContext A long enclosing context message name, for a list - * @param string|Language $lang Language to use for processing messages + * @param string|bool $longContext A long enclosing context message name, for a list + * @param string|Language|null $lang Language to use for processing messages * @return string */ public function getHTML( $shortContext = false, $longContext = false, $lang = null ) { @@ -391,16 +332,6 @@ class Status { }, $errors ); } - /** - * Merge another status object into this one - * - * @param Status $other Other Status object - * @param bool $overwriteValue Whether to override the "value" member - */ - public function merge( $other, $overwriteValue = false ) { - $this->sv->merge( $other->sv, $overwriteValue ); - } - /** * Get the list of errors (but not warnings) * @@ -434,7 +365,7 @@ class Status { protected function getStatusArray( $type = false ) { $result = []; - foreach ( $this->sv->getErrors() as $error ) { + foreach ( $this->getErrors() as $error ) { if ( $type === false || $error['type'] === $type ) { if ( $error['message'] instanceof MessageSpecifier ) { $result[] = array_merge( @@ -452,92 +383,6 @@ class Status { return $result; } - /** - * Returns a list of status messages of the given type, with message and - * params left untouched, like a sane version of getStatusArray - * - * Each entry is a map of: - * - message: string message key or MessageSpecifier - * - params: array list of parameters - * - * @param string $type - * @return array - */ - public function getErrorsByType( $type ) { - return $this->sv->getErrorsByType( $type ); - } - - /** - * Returns true if the specified message is present as a warning or error - * - * @param string|Message $message Message key or object to search for - * - * @return bool - */ - public function hasMessage( $message ) { - return $this->sv->hasMessage( $message ); - } - - /** - * If the specified source message exists, replace it with the specified - * destination message, but keep the same parameters as in the original error. - * - * Note, due to the lack of tools for comparing Message objects, this - * function will not work when using a Message object as the search parameter. - * - * @param Message|string $source Message key or object to search for - * @param Message|string $dest Replacement message key or object - * @return bool Return true if the replacement was done, false otherwise. - */ - public function replaceMessage( $source, $dest ) { - return $this->sv->replaceMessage( $source, $dest ); - } - - /** - * @return mixed - */ - public function getValue() { - return $this->sv->getValue(); - } - - /** - * Backwards compatibility logic - * - * @param string $name - */ - function __get( $name ) { - if ( $name === 'ok' ) { - return $this->sv->isOK(); - } elseif ( $name === 'errors' ) { - return $this->sv->getErrors(); - } - throw new Exception( "Cannot get '$name' property." ); - } - - /** - * Backwards compatibility logic - * - * @param string $name - * @param mixed $value - */ - function __set( $name, $value ) { - if ( $name === 'ok' ) { - $this->sv->setOK( $value ); - } elseif ( !property_exists( $this, $name ) ) { - // Caller is using undeclared ad-hoc properties - $this->$name = $value; - } else { - throw new Exception( "Cannot set '$name' property." ); - } - } - - /** - * @return string - */ - public function __toString() { - return $this->sv->__toString(); - } - /** * Don't save the callback when serializing, because Closures can't be * serialized and we're going to clear it in __wakeup anyway. diff --git a/includes/filebackend/FSFileBackend.php b/includes/filebackend/FSFileBackend.php index efe78ee24b..b0e3eee78f 100644 --- a/includes/filebackend/FSFileBackend.php +++ b/includes/filebackend/FSFileBackend.php @@ -32,7 +32,7 @@ * Having directories with thousands of files will diminish performance. * Sharding can be accomplished by using FileRepo-style hash paths. * - * Status messages should avoid mentioning the internal FS paths. + * StatusValue messages should avoid mentioning the internal FS paths. * PHP warnings are assumed to be logged rather than output. * * @ingroup FileBackend @@ -185,7 +185,7 @@ class FSFileBackend extends FileBackendStore { } protected function doCreateInternal( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); $dest = $this->resolveToFSPath( $params['dst'] ); if ( $dest === null ) { @@ -214,7 +214,7 @@ class FSFileBackend extends FileBackendStore { wfEscapeShellArg( $this->cleanPathSlashes( $tempFile->getPath() ) ), wfEscapeShellArg( $this->cleanPathSlashes( $dest ) ) ] ); - $handler = function ( $errors, Status $status, array $params, $cmd ) { + $handler = function ( $errors, StatusValue $status, array $params, $cmd ) { if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) { $status->fatal( 'backend-fail-create', $params['dst'] ); trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output @@ -238,7 +238,7 @@ class FSFileBackend extends FileBackendStore { } protected function doStoreInternal( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); $dest = $this->resolveToFSPath( $params['dst'] ); if ( $dest === null ) { @@ -253,7 +253,7 @@ class FSFileBackend extends FileBackendStore { wfEscapeShellArg( $this->cleanPathSlashes( $params['src'] ) ), wfEscapeShellArg( $this->cleanPathSlashes( $dest ) ) ] ); - $handler = function ( $errors, Status $status, array $params, $cmd ) { + $handler = function ( $errors, StatusValue $status, array $params, $cmd ) { if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) { $status->fatal( 'backend-fail-store', $params['src'], $params['dst'] ); trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output @@ -281,7 +281,7 @@ class FSFileBackend extends FileBackendStore { } protected function doCopyInternal( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); $source = $this->resolveToFSPath( $params['src'] ); if ( $source === null ) { @@ -311,7 +311,7 @@ class FSFileBackend extends FileBackendStore { wfEscapeShellArg( $this->cleanPathSlashes( $source ) ), wfEscapeShellArg( $this->cleanPathSlashes( $dest ) ) ] ); - $handler = function ( $errors, Status $status, array $params, $cmd ) { + $handler = function ( $errors, StatusValue $status, array $params, $cmd ) { if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) { $status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] ); trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output @@ -341,7 +341,7 @@ class FSFileBackend extends FileBackendStore { } protected function doMoveInternal( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); $source = $this->resolveToFSPath( $params['src'] ); if ( $source === null ) { @@ -371,7 +371,7 @@ class FSFileBackend extends FileBackendStore { wfEscapeShellArg( $this->cleanPathSlashes( $source ) ), wfEscapeShellArg( $this->cleanPathSlashes( $dest ) ) ] ); - $handler = function ( $errors, Status $status, array $params, $cmd ) { + $handler = function ( $errors, StatusValue $status, array $params, $cmd ) { if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) { $status->fatal( 'backend-fail-move', $params['src'], $params['dst'] ); trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output @@ -394,7 +394,7 @@ class FSFileBackend extends FileBackendStore { } protected function doDeleteInternal( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); $source = $this->resolveToFSPath( $params['src'] ); if ( $source === null ) { @@ -416,7 +416,7 @@ class FSFileBackend extends FileBackendStore { wfIsWindows() ? 'DEL' : 'unlink', wfEscapeShellArg( $this->cleanPathSlashes( $source ) ) ] ); - $handler = function ( $errors, Status $status, array $params, $cmd ) { + $handler = function ( $errors, StatusValue $status, array $params, $cmd ) { if ( $errors !== '' && !( wfIsWindows() && $errors[0] === " " ) ) { $status->fatal( 'backend-fail-delete', $params['src'] ); trigger_error( "$cmd\n$errors", E_USER_WARNING ); // command output @@ -441,10 +441,10 @@ class FSFileBackend extends FileBackendStore { * @param string $fullCont * @param string $dirRel * @param array $params - * @return Status + * @return StatusValue */ protected function doPrepareInternal( $fullCont, $dirRel, array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); list( , $shortCont, ) = FileBackend::splitStoragePath( $params['dir'] ); $contRoot = $this->containerFSRoot( $shortCont, $fullCont ); // must be valid $dir = ( $dirRel != '' ) ? "{$contRoot}/{$dirRel}" : $contRoot; @@ -471,7 +471,7 @@ class FSFileBackend extends FileBackendStore { } protected function doSecureInternal( $fullCont, $dirRel, array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); list( , $shortCont, ) = FileBackend::splitStoragePath( $params['dir'] ); $contRoot = $this->containerFSRoot( $shortCont, $fullCont ); // must be valid $dir = ( $dirRel != '' ) ? "{$contRoot}/{$dirRel}" : $contRoot; @@ -499,7 +499,7 @@ class FSFileBackend extends FileBackendStore { } protected function doPublishInternal( $fullCont, $dirRel, array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); list( , $shortCont, ) = FileBackend::splitStoragePath( $params['dir'] ); $contRoot = $this->containerFSRoot( $shortCont, $fullCont ); // must be valid $dir = ( $dirRel != '' ) ? "{$contRoot}/{$dirRel}" : $contRoot; @@ -527,7 +527,7 @@ class FSFileBackend extends FileBackendStore { } protected function doCleanInternal( $fullCont, $dirRel, array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); list( , $shortCont, ) = FileBackend::splitStoragePath( $params['dir'] ); $contRoot = $this->containerFSRoot( $shortCont, $fullCont ); // must be valid $dir = ( $dirRel != '' ) ? "{$contRoot}/{$dirRel}" : $contRoot; @@ -682,7 +682,7 @@ class FSFileBackend extends FileBackendStore { /** * @param FSFileOpHandle[] $fileOpHandles * - * @return Status[] + * @return StatusValue[] */ protected function doExecuteOpHandlesInternal( array $fileOpHandles ) { $statuses = []; @@ -701,7 +701,7 @@ class FSFileBackend extends FileBackendStore { } foreach ( $fileOpHandles as $index => $fileOpHandle ) { - $status = Status::newGood(); + $status = $this->newStatus(); $function = $fileOpHandle->call; $function( $errs[$index], $status, $fileOpHandle->params, $fileOpHandle->cmd ); $statuses[$index] = $status; diff --git a/includes/filebackend/FileBackend.php b/includes/filebackend/FileBackend.php index ed36a1f7b0..1f91b3f13a 100644 --- a/includes/filebackend/FileBackend.php +++ b/includes/filebackend/FileBackend.php @@ -104,6 +104,9 @@ abstract class FileBackend { /** @var FileJournal */ protected $fileJournal; + /** @var callable */ + protected $statusWrapper; + /** Bitfield flags for supported features */ const ATTR_HEADERS = 1; // files can be tagged with standard HTTP headers const ATTR_METADATA = 2; // files can be stored with metadata key/values @@ -156,6 +159,8 @@ abstract class FileBackend { $this->concurrency = isset( $config['concurrency'] ) ? (int)$config['concurrency'] : 50; + // @TODO: dependency inject this + $this->statusWrapper = [ 'Status', 'wrap' ]; } /** @@ -359,20 +364,20 @@ abstract class FileBackend { * during the operation. The 'failCount', 'successCount', and 'success' members * will reflect each operation attempted. * - * The status will be "OK" unless: + * The StatusValue will be "OK" unless: * - a) unexpected operation errors occurred (network partitions, disk full...) * - b) significant operation errors occurred and 'force' was not set * * @param array $ops List of operations to execute in order * @param array $opts Batch operation options - * @return Status + * @return StatusValue */ final public function doOperations( array $ops, array $opts = [] ) { if ( empty( $opts['bypassReadOnly'] ) && $this->isReadOnly() ) { - return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly ); + return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly ); } if ( !count( $ops ) ) { - return Status::newGood(); // nothing to do + return $this->newStatus(); // nothing to do } $ops = $this->resolveFSFileObjects( $ops ); @@ -402,7 +407,7 @@ abstract class FileBackend { * * @param array $op Operation * @param array $opts Operation options - * @return Status + * @return StatusValue */ final public function doOperation( array $op, array $opts = [] ) { return $this->doOperations( [ $op ], $opts ); @@ -416,7 +421,7 @@ abstract class FileBackend { * * @param array $params Operation parameters * @param array $opts Operation options - * @return Status + * @return StatusValue */ final public function create( array $params, array $opts = [] ) { return $this->doOperation( [ 'op' => 'create' ] + $params, $opts ); @@ -430,7 +435,7 @@ abstract class FileBackend { * * @param array $params Operation parameters * @param array $opts Operation options - * @return Status + * @return StatusValue */ final public function store( array $params, array $opts = [] ) { return $this->doOperation( [ 'op' => 'store' ] + $params, $opts ); @@ -444,7 +449,7 @@ abstract class FileBackend { * * @param array $params Operation parameters * @param array $opts Operation options - * @return Status + * @return StatusValue */ final public function copy( array $params, array $opts = [] ) { return $this->doOperation( [ 'op' => 'copy' ] + $params, $opts ); @@ -458,7 +463,7 @@ abstract class FileBackend { * * @param array $params Operation parameters * @param array $opts Operation options - * @return Status + * @return StatusValue */ final public function move( array $params, array $opts = [] ) { return $this->doOperation( [ 'op' => 'move' ] + $params, $opts ); @@ -472,7 +477,7 @@ abstract class FileBackend { * * @param array $params Operation parameters * @param array $opts Operation options - * @return Status + * @return StatusValue */ final public function delete( array $params, array $opts = [] ) { return $this->doOperation( [ 'op' => 'delete' ] + $params, $opts ); @@ -486,7 +491,7 @@ abstract class FileBackend { * * @param array $params Operation parameters * @param array $opts Operation options - * @return Status + * @return StatusValue * @since 1.21 */ final public function describe( array $params, array $opts = [] ) { @@ -597,20 +602,20 @@ abstract class FileBackend { * @par Return value: * This returns a Status, which contains all warnings and fatals that occurred * during the operation. The 'failCount', 'successCount', and 'success' members - * will reflect each operation attempted for the given files. The status will be + * will reflect each operation attempted for the given files. The StatusValue will be * considered "OK" as long as no fatal errors occurred. * * @param array $ops Set of operations to execute * @param array $opts Batch operation options - * @return Status + * @return StatusValue * @since 1.20 */ final public function doQuickOperations( array $ops, array $opts = [] ) { if ( empty( $opts['bypassReadOnly'] ) && $this->isReadOnly() ) { - return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly ); + return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly ); } if ( !count( $ops ) ) { - return Status::newGood(); // nothing to do + return $this->newStatus(); // nothing to do } $ops = $this->resolveFSFileObjects( $ops ); @@ -638,7 +643,7 @@ abstract class FileBackend { * @see FileBackend::doQuickOperations() * * @param array $op Operation - * @return Status + * @return StatusValue * @since 1.20 */ final public function doQuickOperation( array $op ) { @@ -652,7 +657,7 @@ abstract class FileBackend { * @see FileBackend::doQuickOperation() * * @param array $params Operation parameters - * @return Status + * @return StatusValue * @since 1.20 */ final public function quickCreate( array $params ) { @@ -666,7 +671,7 @@ abstract class FileBackend { * @see FileBackend::doQuickOperation() * * @param array $params Operation parameters - * @return Status + * @return StatusValue * @since 1.20 */ final public function quickStore( array $params ) { @@ -680,7 +685,7 @@ abstract class FileBackend { * @see FileBackend::doQuickOperation() * * @param array $params Operation parameters - * @return Status + * @return StatusValue * @since 1.20 */ final public function quickCopy( array $params ) { @@ -694,7 +699,7 @@ abstract class FileBackend { * @see FileBackend::doQuickOperation() * * @param array $params Operation parameters - * @return Status + * @return StatusValue * @since 1.20 */ final public function quickMove( array $params ) { @@ -708,7 +713,7 @@ abstract class FileBackend { * @see FileBackend::doQuickOperation() * * @param array $params Operation parameters - * @return Status + * @return StatusValue * @since 1.20 */ final public function quickDelete( array $params ) { @@ -722,7 +727,7 @@ abstract class FileBackend { * @see FileBackend::doQuickOperation() * * @param array $params Operation parameters - * @return Status + * @return StatusValue * @since 1.21 */ final public function quickDescribe( array $params ) { @@ -739,7 +744,7 @@ abstract class FileBackend { * - srcs : ordered source storage paths (e.g. chunk1, chunk2, ...) * - dst : file system path to 0-byte temp file * - parallelize : try to do operations in parallel when possible - * @return Status + * @return StatusValue */ abstract public function concatenate( array $params ); @@ -759,11 +764,11 @@ abstract class FileBackend { * - noAccess : try to deny file access (since 1.20) * - noListing : try to deny file listing (since 1.20) * - bypassReadOnly : allow writes in read-only mode (since 1.20) - * @return Status + * @return StatusValue */ final public function prepare( array $params ) { if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) { - return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly ); + return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly ); } /** @noinspection PhpUnusedLocalVariableInspection */ $scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts @@ -790,11 +795,11 @@ abstract class FileBackend { * - noAccess : try to deny file access * - noListing : try to deny file listing * - bypassReadOnly : allow writes in read-only mode (since 1.20) - * @return Status + * @return StatusValue */ final public function secure( array $params ) { if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) { - return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly ); + return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly ); } /** @noinspection PhpUnusedLocalVariableInspection */ $scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts @@ -822,12 +827,12 @@ abstract class FileBackend { * - access : try to allow file access * - listing : try to allow file listing * - bypassReadOnly : allow writes in read-only mode (since 1.20) - * @return Status + * @return StatusValue * @since 1.20 */ final public function publish( array $params ) { if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) { - return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly ); + return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly ); } /** @noinspection PhpUnusedLocalVariableInspection */ $scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts @@ -849,11 +854,11 @@ abstract class FileBackend { * - dir : storage directory * - recursive : recursively delete empty subdirectories first (since 1.20) * - bypassReadOnly : allow writes in read-only mode (since 1.20) - * @return Status + * @return StatusValue */ final public function clean( array $params ) { if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) { - return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly ); + return $this->newStatus( 'backend-fail-readonly', $this->name, $this->readOnly ); } /** @noinspection PhpUnusedLocalVariableInspection */ $scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts @@ -1020,7 +1025,7 @@ abstract class FileBackend { * - headless : only include the body (and headers from "headers") (since 1.28) * - latest : use the latest available data * - allowOB : preserve any output buffers (since 1.28) - * @return Status + * @return StatusValue */ abstract public function streamFile( array $params ); @@ -1250,7 +1255,7 @@ abstract class FileBackend { * @param array $paths Storage paths * @param int $type LockManager::LOCK_* constant * @param int $timeout Timeout in seconds (0 means non-blocking) (since 1.24) - * @return Status + * @return StatusValue */ final public function lockFiles( array $paths, $type, $timeout = 0 ) { $paths = array_map( 'FileBackend::normalizeStoragePath', $paths ); @@ -1263,7 +1268,7 @@ abstract class FileBackend { * * @param array $paths Storage paths * @param int $type LockManager::LOCK_* constant - * @return Status + * @return StatusValue */ final public function unlockFiles( array $paths, $type ) { $paths = array_map( 'FileBackend::normalizeStoragePath', $paths ); @@ -1274,20 +1279,22 @@ abstract class FileBackend { /** * Lock the files at the given storage paths in the backend. * This will either lock all the files or none (on failure). - * On failure, the status object will be updated with errors. + * On failure, the StatusValue object will be updated with errors. * * Once the return value goes out scope, the locks will be released and - * the status updated. Unlock fatals will not change the status "OK" value. + * the StatusValue updated. Unlock fatals will not change the StatusValue "OK" value. * * @see ScopedLock::factory() * * @param array $paths List of storage paths or map of lock types to path lists * @param int|string $type LockManager::LOCK_* constant or "mixed" - * @param Status $status Status to update on lock/unlock + * @param StatusValue $status StatusValue to update on lock/unlock * @param int $timeout Timeout in seconds (0 means non-blocking) (since 1.24) * @return ScopedLock|null Returns null on failure */ - final public function getScopedFileLocks( array $paths, $type, Status $status, $timeout = 0 ) { + final public function getScopedFileLocks( + array $paths, $type, StatusValue $status, $timeout = 0 + ) { if ( $type === 'mixed' ) { foreach ( $paths as &$typePaths ) { $typePaths = array_map( 'FileBackend::normalizeStoragePath', $typePaths ); @@ -1311,11 +1318,11 @@ abstract class FileBackend { * @see FileBackend::doOperations() * * @param array $ops List of file operations to FileBackend::doOperations() - * @param Status $status Status to update on lock/unlock + * @param StatusValue $status StatusValue to update on lock/unlock * @return ScopedLock|null * @since 1.20 */ - abstract public function getScopedLocksForOps( array $ops, Status $status ); + abstract public function getScopedLocksForOps( array $ops, StatusValue $status ); /** * Get the root storage path of this backend. @@ -1530,6 +1537,33 @@ abstract class FileBackend { return $path; } + + /** + * Yields the result of the status wrapper callback on either: + * - StatusValue::newGood() if this method is called without parameters + * - StatusValue::newFatal() with all parameters to this method if passed in + * + * @param ... string + * @return StatusValue + */ + final protected function newStatus() { + $args = func_get_args(); + if ( count( $args ) ) { + $sv = call_user_func_array( [ 'StatusValue', 'newFatal' ], $args ); + } else { + $sv = StatusValue::newGood(); + } + + return $this->wrapStatus( $sv ); + } + + /** + * @param StatusValue $sv + * @return StatusValue Modified status or StatusValue subclass + */ + final protected function wrapStatus( StatusValue $sv ) { + return $this->statusWrapper ? call_user_func( $this->statusWrapper, $sv ) : $sv; + } } /** diff --git a/includes/filebackend/FileBackendMultiWrite.php b/includes/filebackend/FileBackendMultiWrite.php index 3b2004827d..c1cc7bb35e 100644 --- a/includes/filebackend/FileBackendMultiWrite.php +++ b/includes/filebackend/FileBackendMultiWrite.php @@ -148,7 +148,7 @@ class FileBackendMultiWrite extends FileBackend { } final protected function doOperationsInternal( array $ops, array $opts ) { - $status = Status::newGood(); + $status = $this->newStatus(); $mbe = $this->backends[$this->masterIndex]; // convenience @@ -233,10 +233,10 @@ class FileBackendMultiWrite extends FileBackend { * Check that a set of files are consistent across all internal backends * * @param array $paths List of storage paths - * @return Status + * @return StatusValue */ public function consistencyCheck( array $paths ) { - $status = Status::newGood(); + $status = $this->newStatus(); if ( $this->syncChecks == 0 || count( $this->backends ) <= 1 ) { return $status; // skip checks } @@ -305,10 +305,10 @@ class FileBackendMultiWrite extends FileBackend { * Check that a set of file paths are usable across all internal backends * * @param array $paths List of storage paths - * @return Status + * @return StatusValue */ public function accessibilityCheck( array $paths ) { - $status = Status::newGood(); + $status = $this->newStatus(); if ( count( $this->backends ) <= 1 ) { return $status; // skip checks } @@ -331,10 +331,10 @@ class FileBackendMultiWrite extends FileBackend { * * @param array $paths List of storage paths * @param string|bool $resyncMode False, True, or "conservative"; see __construct() - * @return Status + * @return StatusValue */ public function resyncFiles( array $paths, $resyncMode = true ) { - $status = Status::newGood(); + $status = $this->newStatus(); $mBackend = $this->backends[$this->masterIndex]; foreach ( $paths as $path ) { @@ -502,8 +502,8 @@ class FileBackendMultiWrite extends FileBackend { } protected function doQuickOperationsInternal( array $ops ) { - $status = Status::newGood(); - // Do the operations on the master backend; setting Status fields... + $status = $this->newStatus(); + // Do the operations on the master backend; setting StatusValue fields... $realOps = $this->substOpBatchPaths( $ops, $this->backends[$this->masterIndex] ); $masterStatus = $this->backends[$this->masterIndex]->doQuickOperations( $realOps ); $status->merge( $masterStatus ); @@ -553,10 +553,10 @@ class FileBackendMultiWrite extends FileBackend { /** * @param string $method One of (doPrepare,doSecure,doPublish,doClean) * @param array $params Method arguments - * @return Status + * @return StatusValue */ protected function doDirectoryOp( $method, array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] ); $masterStatus = $this->backends[$this->masterIndex]->$method( $realParams ); @@ -736,7 +736,7 @@ class FileBackendMultiWrite extends FileBackend { return $this->backends[$index]->preloadFileStat( $realParams ); } - public function getScopedLocksForOps( array $ops, Status $status ) { + public function getScopedLocksForOps( array $ops, StatusValue $status ) { $realOps = $this->substOpBatchPaths( $ops, $this->backends[$this->masterIndex] ); $fileOps = $this->backends[$this->masterIndex]->getOperationsInternal( $realOps ); // Get the paths to lock from the master backend diff --git a/includes/filebackend/FileBackendStore.php b/includes/filebackend/FileBackendStore.php index bc4d81d0e2..4e25ce7247 100644 --- a/includes/filebackend/FileBackendStore.php +++ b/includes/filebackend/FileBackendStore.php @@ -106,19 +106,19 @@ abstract class FileBackendStore extends FileBackend { * - content : the raw file contents * - dst : destination storage path * - headers : HTTP header name/value map - * - async : Status will be returned immediately if supported. - * If the status is OK, then its value field will be + * - async : StatusValue will be returned immediately if supported. + * If the StatusValue is OK, then its value field will be * set to a FileBackendStoreOpHandle object. * - dstExists : Whether a file exists at the destination (optimization). * Callers can use "false" if no existing file is being changed. * * @param array $params - * @return Status + * @return StatusValue */ final public function createInternal( array $params ) { $ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" ); if ( strlen( $params['content'] ) > $this->maxFileSizeInternal() ) { - $status = Status::newFatal( 'backend-fail-maxsize', + $status = $this->newStatus( 'backend-fail-maxsize', $params['dst'], $this->maxFileSizeInternal() ); } else { $status = $this->doCreateInternal( $params ); @@ -134,7 +134,7 @@ abstract class FileBackendStore extends FileBackend { /** * @see FileBackendStore::createInternal() * @param array $params - * @return Status + * @return StatusValue */ abstract protected function doCreateInternal( array $params ); @@ -147,19 +147,19 @@ abstract class FileBackendStore extends FileBackend { * - src : source path on disk * - dst : destination storage path * - headers : HTTP header name/value map - * - async : Status will be returned immediately if supported. - * If the status is OK, then its value field will be + * - async : StatusValue will be returned immediately if supported. + * If the StatusValue is OK, then its value field will be * set to a FileBackendStoreOpHandle object. * - dstExists : Whether a file exists at the destination (optimization). * Callers can use "false" if no existing file is being changed. * * @param array $params - * @return Status + * @return StatusValue */ final public function storeInternal( array $params ) { $ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" ); if ( filesize( $params['src'] ) > $this->maxFileSizeInternal() ) { - $status = Status::newFatal( 'backend-fail-maxsize', + $status = $this->newStatus( 'backend-fail-maxsize', $params['dst'], $this->maxFileSizeInternal() ); } else { $status = $this->doStoreInternal( $params ); @@ -175,7 +175,7 @@ abstract class FileBackendStore extends FileBackend { /** * @see FileBackendStore::storeInternal() * @param array $params - * @return Status + * @return StatusValue */ abstract protected function doStoreInternal( array $params ); @@ -189,14 +189,14 @@ abstract class FileBackendStore extends FileBackend { * - dst : destination storage path * - ignoreMissingSource : do nothing if the source file does not exist * - headers : HTTP header name/value map - * - async : Status will be returned immediately if supported. - * If the status is OK, then its value field will be + * - async : StatusValue will be returned immediately if supported. + * If the StatusValue is OK, then its value field will be * set to a FileBackendStoreOpHandle object. * - dstExists : Whether a file exists at the destination (optimization). * Callers can use "false" if no existing file is being changed. * * @param array $params - * @return Status + * @return StatusValue */ final public function copyInternal( array $params ) { $ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" ); @@ -212,7 +212,7 @@ abstract class FileBackendStore extends FileBackend { /** * @see FileBackendStore::copyInternal() * @param array $params - * @return Status + * @return StatusValue */ abstract protected function doCopyInternal( array $params ); @@ -223,12 +223,12 @@ abstract class FileBackendStore extends FileBackend { * $params include: * - src : source storage path * - ignoreMissingSource : do nothing if the source file does not exist - * - async : Status will be returned immediately if supported. - * If the status is OK, then its value field will be + * - async : StatusValue will be returned immediately if supported. + * If the StatusValue is OK, then its value field will be * set to a FileBackendStoreOpHandle object. * * @param array $params - * @return Status + * @return StatusValue */ final public function deleteInternal( array $params ) { $ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" ); @@ -241,7 +241,7 @@ abstract class FileBackendStore extends FileBackend { /** * @see FileBackendStore::deleteInternal() * @param array $params - * @return Status + * @return StatusValue */ abstract protected function doDeleteInternal( array $params ); @@ -255,14 +255,14 @@ abstract class FileBackendStore extends FileBackend { * - dst : destination storage path * - ignoreMissingSource : do nothing if the source file does not exist * - headers : HTTP header name/value map - * - async : Status will be returned immediately if supported. - * If the status is OK, then its value field will be + * - async : StatusValue will be returned immediately if supported. + * If the StatusValue is OK, then its value field will be * set to a FileBackendStoreOpHandle object. * - dstExists : Whether a file exists at the destination (optimization). * Callers can use "false" if no existing file is being changed. * * @param array $params - * @return Status + * @return StatusValue */ final public function moveInternal( array $params ) { $ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" ); @@ -279,7 +279,7 @@ abstract class FileBackendStore extends FileBackend { /** * @see FileBackendStore::moveInternal() * @param array $params - * @return Status + * @return StatusValue */ protected function doMoveInternal( array $params ) { unset( $params['async'] ); // two steps, won't work here :) @@ -303,12 +303,12 @@ abstract class FileBackendStore extends FileBackend { * $params include: * - src : source storage path * - headers : HTTP header name/value map - * - async : Status will be returned immediately if supported. - * If the status is OK, then its value field will be + * - async : StatusValue will be returned immediately if supported. + * If the StatusValue is OK, then its value field will be * set to a FileBackendStoreOpHandle object. * * @param array $params - * @return Status + * @return StatusValue */ final public function describeInternal( array $params ) { $ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" ); @@ -317,7 +317,7 @@ abstract class FileBackendStore extends FileBackend { $this->clearCache( [ $params['src'] ] ); $this->deleteFileCache( $params['src'] ); // persistent cache } else { - $status = Status::newGood(); // nothing to do + $status = $this->newStatus(); // nothing to do } return $status; @@ -326,10 +326,10 @@ abstract class FileBackendStore extends FileBackend { /** * @see FileBackendStore::describeInternal() * @param array $params - * @return Status + * @return StatusValue */ protected function doDescribeInternal( array $params ) { - return Status::newGood(); + return $this->newStatus(); } /** @@ -337,15 +337,15 @@ abstract class FileBackendStore extends FileBackend { * Do not call this function from places outside FileBackend and FileOp. * * @param array $params - * @return Status + * @return StatusValue */ final public function nullInternal( array $params ) { - return Status::newGood(); + return $this->newStatus(); } final public function concatenate( array $params ) { $ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" ); - $status = Status::newGood(); + $status = $this->newStatus(); // Try to lock the source files for the scope of this function $scopeLockS = $this->getScopedFileLocks( $params['srcs'], LockManager::LOCK_UW, $status ); @@ -366,10 +366,10 @@ abstract class FileBackendStore extends FileBackend { /** * @see FileBackendStore::concatenate() * @param array $params - * @return Status + * @return StatusValue */ protected function doConcatenate( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); $tmpPath = $params['dst']; // convenience unset( $params['latest'] ); // sanity @@ -438,7 +438,7 @@ abstract class FileBackendStore extends FileBackend { final protected function doPrepare( array $params ) { $ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" ); - $status = Status::newGood(); + $status = $this->newStatus(); list( $fullCont, $dir, $shard ) = $this->resolveStoragePath( $params['dir'] ); if ( $dir === null ) { @@ -465,15 +465,15 @@ abstract class FileBackendStore extends FileBackend { * @param string $container * @param string $dir * @param array $params - * @return Status + * @return StatusValue */ protected function doPrepareInternal( $container, $dir, array $params ) { - return Status::newGood(); + return $this->newStatus(); } final protected function doSecure( array $params ) { $ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" ); - $status = Status::newGood(); + $status = $this->newStatus(); list( $fullCont, $dir, $shard ) = $this->resolveStoragePath( $params['dir'] ); if ( $dir === null ) { @@ -500,15 +500,15 @@ abstract class FileBackendStore extends FileBackend { * @param string $container * @param string $dir * @param array $params - * @return Status + * @return StatusValue */ protected function doSecureInternal( $container, $dir, array $params ) { - return Status::newGood(); + return $this->newStatus(); } final protected function doPublish( array $params ) { $ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" ); - $status = Status::newGood(); + $status = $this->newStatus(); list( $fullCont, $dir, $shard ) = $this->resolveStoragePath( $params['dir'] ); if ( $dir === null ) { @@ -535,15 +535,15 @@ abstract class FileBackendStore extends FileBackend { * @param string $container * @param string $dir * @param array $params - * @return Status + * @return StatusValue */ protected function doPublishInternal( $container, $dir, array $params ) { - return Status::newGood(); + return $this->newStatus(); } final protected function doClean( array $params ) { $ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" ); - $status = Status::newGood(); + $status = $this->newStatus(); // Recursive: first delete all empty subdirs recursively if ( !empty( $params['recursive'] ) && !$this->directoriesAreVirtual() ) { @@ -591,10 +591,10 @@ abstract class FileBackendStore extends FileBackend { * @param string $container * @param string $dir * @param array $params - * @return Status + * @return StatusValue */ protected function doCleanInternal( $container, $dir, array $params ) { - return Status::newGood(); + return $this->newStatus(); } final public function fileExists( array $params ) { @@ -842,7 +842,7 @@ abstract class FileBackendStore extends FileBackend { final public function streamFile( array $params ) { $ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" ); - $status = Status::newGood(); + $status = $this->newStatus(); // Always set some fields for subclass convenience $params['options'] = isset( $params['options'] ) ? $params['options'] : []; @@ -863,10 +863,10 @@ abstract class FileBackendStore extends FileBackend { /** * @see FileBackendStore::streamFile() * @param array $params - * @return Status + * @return StatusValue */ protected function doStreamFile( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); $flags = 0; $flags |= !empty( $params['headless'] ) ? StreamFile::STREAM_HEADLESS : 0; @@ -992,7 +992,7 @@ abstract class FileBackendStore extends FileBackend { * An exception is thrown if an unsupported operation is requested. * * @param array $ops Same format as doOperations() - * @return array List of FileOp objects + * @return FileOp[] List of FileOp objects * @throws FileBackendError */ final public function getOperationsInternal( array $ops ) { @@ -1052,7 +1052,7 @@ abstract class FileBackendStore extends FileBackend { ]; } - public function getScopedLocksForOps( array $ops, Status $status ) { + public function getScopedLocksForOps( array $ops, StatusValue $status ) { $paths = $this->getPathsToLockForOpsInternal( $this->getOperationsInternal( $ops ) ); return $this->getScopedFileLocks( $paths, 'mixed', $status ); @@ -1060,7 +1060,7 @@ abstract class FileBackendStore extends FileBackend { final protected function doOperationsInternal( array $ops, array $opts ) { $ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" ); - $status = Status::newGood(); + $status = $this->newStatus(); // Fix up custom header name/value pairs... $ops = array_map( [ $this, 'sanitizeOpHeaders' ], $ops ); @@ -1106,7 +1106,7 @@ abstract class FileBackendStore extends FileBackend { $subStatus = FileOpBatch::attempt( $performOps, $opts, $this->fileJournal ); } else { // If we could not even stat some files, then bail out... - $subStatus = Status::newFatal( 'backend-fail-internal', $this->name ); + $subStatus = $this->newStatus( 'backend-fail-internal', $this->name ); foreach ( $ops as $i => $op ) { // mark each op as failed $subStatus->success[$i] = false; ++$subStatus->failCount; @@ -1115,7 +1115,7 @@ abstract class FileBackendStore extends FileBackend { " stat failure; aborted operations: " . FormatJson::encode( $ops ) ); } - // Merge errors into status fields + // Merge errors into StatusValue fields $status->merge( $subStatus ); $status->success = $subStatus->success; // not done in merge() @@ -1127,7 +1127,7 @@ abstract class FileBackendStore extends FileBackend { final protected function doQuickOperationsInternal( array $ops ) { $ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" ); - $status = Status::newGood(); + $status = $this->newStatus(); // Fix up custom header name/value pairs... $ops = array_map( [ $this, 'sanitizeOpHeaders' ], $ops ); @@ -1139,8 +1139,8 @@ abstract class FileBackendStore extends FileBackend { // Parallel ops may be disabled in config due to dependencies (e.g. needing popen()) $async = ( $this->parallelize === 'implicit' && count( $ops ) > 1 ); $maxConcurrency = $this->concurrency; // throttle - - $statuses = []; // array of (index => Status) + /** @var StatusValue[] $statuses */ + $statuses = []; // array of (index => StatusValue) $fileOpHandles = []; // list of (index => handle) arrays $curFileOpHandles = []; // current handle batch // Perform the sync-only ops and build up op handles for the async ops... @@ -1184,13 +1184,13 @@ abstract class FileBackendStore extends FileBackend { /** * Execute a list of FileBackendStoreOpHandle handles in parallel. - * The resulting Status object fields will correspond + * The resulting StatusValue object fields will correspond * to the order in which the handles where given. * * @param FileBackendStoreOpHandle[] $fileOpHandles * * @throws FileBackendError - * @return array Map of Status objects + * @return StatusValue[] Map of StatusValue objects */ final public function executeOpHandlesInternal( array $fileOpHandles ) { $ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" ); @@ -1216,7 +1216,7 @@ abstract class FileBackendStore extends FileBackend { * @param FileBackendStoreOpHandle[] $fileOpHandles * * @throws FileBackendError - * @return Status[] List of corresponding Status objects + * @return StatusValue[] List of corresponding StatusValue objects */ protected function doExecuteOpHandlesInternal( array $fileOpHandles ) { if ( count( $fileOpHandles ) ) { @@ -1844,7 +1844,7 @@ abstract class FileBackendStore extends FileBackend { * FileBackendStore helper class for performing asynchronous file operations. * * For example, calling FileBackendStore::createInternal() with the "async" - * param flag may result in a Status that contains this object as a value. + * param flag may result in a StatusValue that contains this object as a value. * This class is largely backend-specific and is mostly just "magic" to be * passed to FileBackendStore::executeOpHandlesInternal(). */ diff --git a/includes/filebackend/FileOp.php b/includes/filebackend/FileOp.php index 56a40738e6..916366c8db 100644 --- a/includes/filebackend/FileOp.php +++ b/includes/filebackend/FileOp.php @@ -239,14 +239,14 @@ abstract class FileOp { /** * Check preconditions of the operation without writing anything. * This must update $predicates for each path that the op can change - * except when a failing status object is returned. + * except when a failing StatusValue object is returned. * * @param array $predicates - * @return Status + * @return StatusValue */ final public function precheck( array &$predicates ) { if ( $this->state !== self::STATE_NEW ) { - return Status::newFatal( 'fileop-fail-state', self::STATE_NEW, $this->state ); + return StatusValue::newFatal( 'fileop-fail-state', self::STATE_NEW, $this->state ); } $this->state = self::STATE_CHECKED; $status = $this->doPrecheck( $predicates ); @@ -259,22 +259,22 @@ abstract class FileOp { /** * @param array $predicates - * @return Status + * @return StatusValue */ protected function doPrecheck( array &$predicates ) { - return Status::newGood(); + return StatusValue::newGood(); } /** * Attempt the operation * - * @return Status + * @return StatusValue */ final public function attempt() { if ( $this->state !== self::STATE_CHECKED ) { - return Status::newFatal( 'fileop-fail-state', self::STATE_CHECKED, $this->state ); + return StatusValue::newFatal( 'fileop-fail-state', self::STATE_CHECKED, $this->state ); } elseif ( $this->failed ) { // failed precheck - return Status::newFatal( 'fileop-fail-attempt-precheck' ); + return StatusValue::newFatal( 'fileop-fail-attempt-precheck' ); } $this->state = self::STATE_ATTEMPTED; if ( $this->doOperation ) { @@ -284,23 +284,23 @@ abstract class FileOp { $this->logFailure( 'attempt' ); } } else { // no-op - $status = Status::newGood(); + $status = StatusValue::newGood(); } return $status; } /** - * @return Status + * @return StatusValue */ protected function doAttempt() { - return Status::newGood(); + return StatusValue::newGood(); } /** * Attempt the operation in the background * - * @return Status + * @return StatusValue */ final public function attemptAsync() { $this->async = true; @@ -350,13 +350,13 @@ abstract class FileOp { /** * Check for errors with regards to the destination file already existing. * Also set the destExists, overwriteSameCase and sourceSha1 member variables. - * A bad status will be returned if there is no chance it can be overwritten. + * A bad StatusValue will be returned if there is no chance it can be overwritten. * * @param array $predicates - * @return Status + * @return StatusValue */ protected function precheckDestExistence( array $predicates ) { - $status = Status::newGood(); + $status = StatusValue::newGood(); // Get hash of source file/string and the destination file $this->sourceSha1 = $this->getSourceSha1Base36(); // FS file or data string if ( $this->sourceSha1 === null ) { // file in storage? @@ -476,7 +476,7 @@ class CreateFileOp extends FileOp { } protected function doPrecheck( array &$predicates ) { - $status = Status::newGood(); + $status = StatusValue::newGood(); // Check if the source data is too big if ( strlen( $this->getParam( 'content' ) ) > $this->backend->maxFileSizeInternal() ) { $status->fatal( 'backend-fail-maxsize', @@ -509,7 +509,7 @@ class CreateFileOp extends FileOp { return $this->backend->createInternal( $this->setFlags( $this->params ) ); } - return Status::newGood(); + return StatusValue::newGood(); } protected function getSourceSha1Base36() { @@ -535,7 +535,7 @@ class StoreFileOp extends FileOp { } protected function doPrecheck( array &$predicates ) { - $status = Status::newGood(); + $status = StatusValue::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'] ); @@ -573,7 +573,7 @@ class StoreFileOp extends FileOp { return $this->backend->storeInternal( $this->setFlags( $this->params ) ); } - return Status::newGood(); + return StatusValue::newGood(); } protected function getSourceSha1Base36() { @@ -606,7 +606,7 @@ class CopyFileOp extends FileOp { } protected function doPrecheck( array &$predicates ) { - $status = Status::newGood(); + $status = StatusValue::newGood(); // Check if the source file exists if ( !$this->fileExists( $this->params['src'], $predicates ) ) { if ( $this->getParam( 'ignoreMissingSource' ) ) { @@ -642,7 +642,7 @@ class CopyFileOp extends FileOp { protected function doAttempt() { if ( $this->overwriteSameCase ) { - $status = Status::newGood(); // nothing to do + $status = StatusValue::newGood(); // nothing to do } elseif ( $this->params['src'] === $this->params['dst'] ) { // Just update the destination file headers $headers = $this->getParam( 'headers' ) ?: []; @@ -680,7 +680,7 @@ class MoveFileOp extends FileOp { } protected function doPrecheck( array &$predicates ) { - $status = Status::newGood(); + $status = StatusValue::newGood(); // Check if the source file exists if ( !$this->fileExists( $this->params['src'], $predicates ) ) { if ( $this->getParam( 'ignoreMissingSource' ) ) { @@ -720,7 +720,7 @@ class MoveFileOp extends FileOp { if ( $this->overwriteSameCase ) { if ( $this->params['src'] === $this->params['dst'] ) { // Do nothing to the destination (which is also the source) - $status = Status::newGood(); + $status = StatusValue::newGood(); } else { // Just delete the source as the destination file needs no changes $status = $this->backend->deleteInternal( $this->setFlags( @@ -760,7 +760,7 @@ class DeleteFileOp extends FileOp { } protected function doPrecheck( array &$predicates ) { - $status = Status::newGood(); + $status = StatusValue::newGood(); // Check if the source file exists if ( !$this->fileExists( $this->params['src'], $predicates ) ) { if ( $this->getParam( 'ignoreMissingSource' ) ) { @@ -809,7 +809,7 @@ class DescribeFileOp extends FileOp { } protected function doPrecheck( array &$predicates ) { - $status = Status::newGood(); + $status = StatusValue::newGood(); // Check if the source file exists if ( !$this->fileExists( $this->params['src'], $predicates ) ) { $status->fatal( 'backend-fail-notexists', $this->params['src'] ); diff --git a/includes/filebackend/FileOpBatch.php b/includes/filebackend/FileOpBatch.php index 78209d8bf8..e34ad8ccb4 100644 --- a/includes/filebackend/FileOpBatch.php +++ b/includes/filebackend/FileOpBatch.php @@ -45,17 +45,17 @@ class FileOpBatch { * - nonJournaled : Don't log this operation batch in the file journal. * - concurrency : Try to do this many operations in parallel when possible. * - * The resulting Status will be "OK" unless: + * The resulting StatusValue will be "OK" unless: * - a) unexpected operation errors occurred (network partitions, disk full...) * - b) significant operation errors occurred and 'force' was not set * * @param FileOp[] $performOps List of FileOp operations * @param array $opts Batch operation options * @param FileJournal $journal Journal to log operations to - * @return Status + * @return StatusValue */ public static function attempt( array $performOps, array $opts, FileJournal $journal ) { - $status = Status::newGood(); + $status = StatusValue::newGood(); $n = count( $performOps ); if ( $n > self::MAX_BATCH_SIZE ) { @@ -119,7 +119,9 @@ class FileOpBatch { if ( count( $entries ) ) { $subStatus = $journal->logChangeBatch( $entries, $batchId ); if ( !$subStatus->isOK() ) { - return $subStatus; // abort + $status->merge( $subStatus ); + + return $status; // abort } } @@ -142,9 +144,9 @@ class FileOpBatch { * This will abort remaining ops on failure. * * @param array $pPerformOps Batches of file ops (batches use original indexes) - * @param Status $status + * @param StatusValue $status */ - protected static function runParallelBatches( array $pPerformOps, Status $status ) { + protected static function runParallelBatches( array $pPerformOps, StatusValue $status ) { $aborted = false; // set to true on unexpected errors foreach ( $pPerformOps as $performOpsBatch ) { /** @var FileOp[] $performOpsBatch */ @@ -158,13 +160,13 @@ class FileOpBatch { } continue; } - /** @var Status[] $statuses */ + /** @var StatusValue[] $statuses */ $statuses = []; $opHandles = []; // Get the backend; all sub-batch ops belong to a single backend $backend = reset( $performOpsBatch )->getBackend(); // Get the operation handles or actually do it if there is just one. - // If attemptAsync() returns a Status, it was either due to an error + // If attemptAsync() returns a StatusValue, it was either due to an error // or the backend does not support async ops and did it synchronously. foreach ( $performOpsBatch as $i => $fileOp ) { if ( !isset( $status->success[$i] ) ) { // didn't already fail in precheck() diff --git a/includes/filebackend/MemoryFileBackend.php b/includes/filebackend/MemoryFileBackend.php index e2c1ede46d..74a0068fac 100644 --- a/includes/filebackend/MemoryFileBackend.php +++ b/includes/filebackend/MemoryFileBackend.php @@ -44,7 +44,7 @@ class MemoryFileBackend extends FileBackendStore { } protected function doCreateInternal( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); $dst = $this->resolveHashKey( $params['dst'] ); if ( $dst === null ) { @@ -62,7 +62,7 @@ class MemoryFileBackend extends FileBackendStore { } protected function doStoreInternal( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); $dst = $this->resolveHashKey( $params['dst'] ); if ( $dst === null ) { @@ -89,7 +89,7 @@ class MemoryFileBackend extends FileBackendStore { } protected function doCopyInternal( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); $src = $this->resolveHashKey( $params['src'] ); if ( $src === null ) { @@ -122,7 +122,7 @@ class MemoryFileBackend extends FileBackendStore { } protected function doDeleteInternal( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); $src = $this->resolveHashKey( $params['src'] ); if ( $src === null ) { diff --git a/includes/filebackend/SwiftFileBackend.php b/includes/filebackend/SwiftFileBackend.php index 2adf934a55..a0027e4ff7 100644 --- a/includes/filebackend/SwiftFileBackend.php +++ b/includes/filebackend/SwiftFileBackend.php @@ -26,7 +26,7 @@ /** * @brief Class for an OpenStack Swift (or Ceph RGW) based file backend. * - * Status messages should avoid mentioning the Swift account name. + * StatusValue messages should avoid mentioning the Swift account name. * Likewise, error suppression should be used to avoid path disclosure. * * @ingroup FileBackend @@ -252,7 +252,7 @@ class SwiftFileBackend extends FileBackendStore { } protected function doCreateInternal( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); list( $dstCont, $dstRel ) = $this->resolveStoragePathReal( $params['dst'] ); if ( $dstRel === null ) { @@ -279,7 +279,7 @@ class SwiftFileBackend extends FileBackendStore { ] ]; $method = __METHOD__; - $handler = function ( array $request, Status $status ) use ( $method, $params ) { + $handler = function ( array $request, StatusValue $status ) use ( $method, $params ) { list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response']; if ( $rcode === 201 ) { // good @@ -301,7 +301,7 @@ class SwiftFileBackend extends FileBackendStore { } protected function doStoreInternal( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); list( $dstCont, $dstRel ) = $this->resolveStoragePathReal( $params['dst'] ); if ( $dstRel === null ) { @@ -343,7 +343,7 @@ class SwiftFileBackend extends FileBackendStore { ] ]; $method = __METHOD__; - $handler = function ( array $request, Status $status ) use ( $method, $params ) { + $handler = function ( array $request, StatusValue $status ) use ( $method, $params ) { list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response']; if ( $rcode === 201 ) { // good @@ -365,7 +365,7 @@ class SwiftFileBackend extends FileBackendStore { } protected function doCopyInternal( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] ); if ( $srcRel === null ) { @@ -391,7 +391,7 @@ class SwiftFileBackend extends FileBackendStore { ] ]; $method = __METHOD__; - $handler = function ( array $request, Status $status ) use ( $method, $params ) { + $handler = function ( array $request, StatusValue $status ) use ( $method, $params ) { list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response']; if ( $rcode === 201 ) { // good @@ -413,7 +413,7 @@ class SwiftFileBackend extends FileBackendStore { } protected function doMoveInternal( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] ); if ( $srcRel === null ) { @@ -448,7 +448,7 @@ class SwiftFileBackend extends FileBackendStore { } $method = __METHOD__; - $handler = function ( array $request, Status $status ) use ( $method, $params ) { + $handler = function ( array $request, StatusValue $status ) use ( $method, $params ) { list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response']; if ( $request['method'] === 'PUT' && $rcode === 201 ) { // good @@ -472,7 +472,7 @@ class SwiftFileBackend extends FileBackendStore { } protected function doDeleteInternal( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] ); if ( $srcRel === null ) { @@ -488,7 +488,7 @@ class SwiftFileBackend extends FileBackendStore { ] ]; $method = __METHOD__; - $handler = function ( array $request, Status $status ) use ( $method, $params ) { + $handler = function ( array $request, StatusValue $status ) use ( $method, $params ) { list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response']; if ( $rcode === 204 ) { // good @@ -512,7 +512,7 @@ class SwiftFileBackend extends FileBackendStore { } protected function doDescribeInternal( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] ); if ( $srcRel === null ) { @@ -546,7 +546,7 @@ class SwiftFileBackend extends FileBackendStore { ] ]; $method = __METHOD__; - $handler = function ( array $request, Status $status ) use ( $method, $params ) { + $handler = function ( array $request, StatusValue $status ) use ( $method, $params ) { list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response']; if ( $rcode === 202 ) { // good @@ -568,7 +568,7 @@ class SwiftFileBackend extends FileBackendStore { } protected function doPrepareInternal( $fullCont, $dir, array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); // (a) Check if container already exists $stat = $this->getContainerStat( $fullCont ); @@ -591,7 +591,7 @@ class SwiftFileBackend extends FileBackendStore { } protected function doSecureInternal( $fullCont, $dir, array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); if ( empty( $params['noAccess'] ) ) { return $status; // nothing to do } @@ -615,7 +615,7 @@ class SwiftFileBackend extends FileBackendStore { } protected function doPublishInternal( $fullCont, $dir, array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); $stat = $this->getContainerStat( $fullCont ); if ( is_array( $stat ) ) { @@ -636,7 +636,7 @@ class SwiftFileBackend extends FileBackendStore { } protected function doCleanInternal( $fullCont, $dir, array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); // Only containers themselves can be removed, all else is virtual if ( $dir != '' ) { @@ -719,7 +719,7 @@ class SwiftFileBackend extends FileBackendStore { // Find prior metadata headers $postHeaders += $this->getMetadataHeaders( $objHdrs ); - $status = Status::newGood(); + $status = $this->newStatus(); /** @noinspection PhpUnusedLocalVariableInspection */ $scopeLockS = $this->getScopedFileLocks( [ $path ], LockManager::LOCK_UW, $status ); if ( $status->isOK() ) { @@ -1043,7 +1043,7 @@ class SwiftFileBackend extends FileBackendStore { } protected function doStreamFile( array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); $flags = !empty( $params['headless'] ) ? StreamFile::STREAM_HEADLESS : 0; @@ -1254,7 +1254,7 @@ class SwiftFileBackend extends FileBackendStore { /** * @param FileBackendStoreOpHandle[] $fileOpHandles * - * @return Status[] + * @return StatusValue[] */ protected function doExecuteOpHandlesInternal( array $fileOpHandles ) { $statuses = []; @@ -1262,7 +1262,7 @@ class SwiftFileBackend extends FileBackendStore { $auth = $this->getAuthentication(); if ( !$auth ) { foreach ( $fileOpHandles as $index => $fileOpHandle ) { - $statuses[$index] = Status::newFatal( 'backend-fail-connect', $this->name ); + $statuses[$index] = $this->newStatus( 'backend-fail-connect', $this->name ); } return $statuses; @@ -1280,7 +1280,7 @@ class SwiftFileBackend extends FileBackendStore { $req['headers'] = $this->authTokenHeaders( $auth ) + $req['headers']; $httpReqsByStage[$stage][$index] = $req; } - $statuses[$index] = Status::newGood(); + $statuses[$index] = $this->newStatus(); } // Run all requests for the first stage, then the next, and so on @@ -1325,10 +1325,10 @@ class SwiftFileBackend extends FileBackendStore { * @param array $writeGrps A list of the possible criteria for a request to have * access to write to a container. Each item is of the following format: * - account:user : Grants access if the request is by the given user - * @return Status + * @return StatusValue */ protected function setContainerAccess( $container, array $readGrps, array $writeGrps ) { - $status = Status::newGood(); + $status = $this->newStatus(); $auth = $this->getAuthentication(); if ( !$auth ) { @@ -1411,10 +1411,10 @@ class SwiftFileBackend extends FileBackendStore { * * @param string $container Container name * @param array $params - * @return Status + * @return StatusValue */ protected function createContainer( $container, array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); $auth = $this->getAuthentication(); if ( !$auth ) { @@ -1456,10 +1456,10 @@ class SwiftFileBackend extends FileBackendStore { * * @param string $container Container name * @param array $params - * @return Status + * @return StatusValue */ protected function deleteContainer( $container, array $params ) { - $status = Status::newGood(); + $status = $this->newStatus(); $auth = $this->getAuthentication(); if ( !$auth ) { @@ -1497,12 +1497,12 @@ class SwiftFileBackend extends FileBackendStore { * @param string|null $after * @param string|null $prefix * @param string|null $delim - * @return Status With the list as value + * @return StatusValue With the list as value */ private function objectListing( $fullCont, $type, $limit, $after = null, $prefix = null, $delim = null ) { - $status = Status::newGood(); + $status = $this->newStatus(); $auth = $this->getAuthentication(); if ( !$auth ) { @@ -1739,17 +1739,17 @@ class SwiftFileBackend extends FileBackendStore { /** * Log an unexpected exception for this backend. - * This also sets the Status object to have a fatal error. + * This also sets the StatusValue object to have a fatal error. * - * @param Status|null $status + * @param StatusValue|null $status * @param string $func * @param array $params * @param string $err Error string * @param int $code HTTP status - * @param string $desc HTTP status description + * @param string $desc HTTP StatusValue description */ public function onError( $status, $func, array $params, $err = '', $code = 0, $desc = '' ) { - if ( $status instanceof Status ) { + if ( $status instanceof StatusValue ) { $status->fatal( 'backend-fail-internal', $this->name ); } if ( $code == 401 ) { // possibly a stale token diff --git a/includes/filebackend/filejournal/DBFileJournal.php b/includes/filebackend/filejournal/DBFileJournal.php index 7efb3a15c1..2e06c40f72 100644 --- a/includes/filebackend/filejournal/DBFileJournal.php +++ b/includes/filebackend/filejournal/DBFileJournal.php @@ -48,10 +48,10 @@ class DBFileJournal extends FileJournal { * @see FileJournal::logChangeBatch() * @param array $entries * @param string $batchId - * @return Status + * @return StatusValue */ protected function doLogChangeBatch( array $entries, $batchId ) { - $status = Status::newGood(); + $status = StatusValue::newGood(); try { $dbw = $this->getMasterDB(); @@ -151,11 +151,11 @@ class DBFileJournal extends FileJournal { /** * @see FileJournal::purgeOldLogs() - * @return Status + * @return StatusValue * @throws DBError */ protected function doPurgeOldLogs() { - $status = Status::newGood(); + $status = StatusValue::newGood(); if ( $this->ttlDays <= 0 ) { return $status; // nothing to do } diff --git a/includes/filebackend/filejournal/FileJournal.php b/includes/filebackend/filejournal/FileJournal.php index b84e195989..f0bb92da34 100644 --- a/includes/filebackend/filejournal/FileJournal.php +++ b/includes/filebackend/filejournal/FileJournal.php @@ -95,11 +95,11 @@ abstract class FileJournal { * newSha1 : The final base 36 SHA-1 of the file * Note that 'false' should be used as the SHA-1 for non-existing files. * @param string $batchId UUID string that identifies the operation batch - * @return Status + * @return StatusValue */ final public function logChangeBatch( array $entries, $batchId ) { if ( !count( $entries ) ) { - return Status::newGood(); + return StatusValue::newGood(); } return $this->doLogChangeBatch( $entries, $batchId ); @@ -110,7 +110,7 @@ abstract class FileJournal { * * @param array $entries List of file operations (each an array of parameters) * @param string $batchId UUID string that identifies the operation batch - * @return Status + * @return StatusValue */ abstract protected function doLogChangeBatch( array $entries, $batchId ); @@ -186,7 +186,7 @@ abstract class FileJournal { /** * Purge any old log entries * - * @return Status + * @return StatusValue */ final public function purgeOldLogs() { return $this->doPurgeOldLogs(); @@ -194,7 +194,7 @@ abstract class FileJournal { /** * @see FileJournal::purgeOldLogs() - * @return Status + * @return StatusValue */ abstract protected function doPurgeOldLogs(); } @@ -208,10 +208,10 @@ class NullFileJournal extends FileJournal { * @see FileJournal::doLogChangeBatch() * @param array $entries * @param string $batchId - * @return Status + * @return StatusValue */ protected function doLogChangeBatch( array $entries, $batchId ) { - return Status::newGood(); + return StatusValue::newGood(); } /** @@ -243,9 +243,9 @@ class NullFileJournal extends FileJournal { /** * @see FileJournal::doPurgeOldLogs() - * @return Status + * @return StatusValue */ protected function doPurgeOldLogs() { - return Status::newGood(); + return StatusValue::newGood(); } } diff --git a/includes/filebackend/lockmanager/FSLockManager.php b/includes/filebackend/lockmanager/FSLockManager.php index 2b660ec77e..8e149d6380 100644 --- a/includes/filebackend/lockmanager/FSLockManager.php +++ b/includes/filebackend/lockmanager/FSLockManager.php @@ -62,7 +62,7 @@ class FSLockManager extends LockManager { * @see LockManager::doLock() * @param array $paths * @param int $type - * @return Status + * @return StatusValue */ protected function doLock( array $paths, $type ) { $status = Status::newGood(); @@ -87,7 +87,7 @@ class FSLockManager extends LockManager { * @see LockManager::doUnlock() * @param array $paths * @param int $type - * @return Status + * @return StatusValue */ protected function doUnlock( array $paths, $type ) { $status = Status::newGood(); @@ -104,7 +104,7 @@ class FSLockManager extends LockManager { * * @param string $path * @param int $type - * @return Status + * @return StatusValue */ protected function doSingleLock( $path, $type ) { $status = Status::newGood(); @@ -149,7 +149,7 @@ class FSLockManager extends LockManager { * * @param string $path * @param int $type - * @return Status + * @return StatusValue */ protected function doSingleUnlock( $path, $type ) { $status = Status::newGood(); @@ -192,7 +192,7 @@ class FSLockManager extends LockManager { /** * @param string $path * @param array $handlesToClose - * @return Status + * @return StatusValue */ private function closeLockHandles( $path, array $handlesToClose ) { $status = Status::newGood(); @@ -210,7 +210,7 @@ class FSLockManager extends LockManager { /** * @param string $path - * @return Status + * @return StatusValue */ private function pruneKeyLockFiles( $path ) { $status = Status::newGood(); diff --git a/includes/filebackend/lockmanager/LockManager.php b/includes/filebackend/lockmanager/LockManager.php index a3cb3b1986..eff031b58b 100644 --- a/includes/filebackend/lockmanager/LockManager.php +++ b/includes/filebackend/lockmanager/LockManager.php @@ -87,7 +87,7 @@ abstract class LockManager { * @param array $paths List of resource names * @param int $type LockManager::LOCK_* constant * @param int $timeout Timeout in seconds (0 means non-blocking) (since 1.21) - * @return Status + * @return StatusValue */ final public function lock( array $paths, $type = self::LOCK_EX, $timeout = 0 ) { return $this->lockByType( [ $type => $paths ], $timeout ); @@ -98,7 +98,7 @@ abstract class LockManager { * * @param array $pathsByType Map of LockManager::LOCK_* constants to lists of paths * @param int $timeout Timeout in seconds (0 means non-blocking) (since 1.21) - * @return Status + * @return StatusValue * @since 1.22 */ final public function lockByType( array $pathsByType, $timeout = 0 ) { @@ -123,7 +123,7 @@ abstract class LockManager { * * @param array $paths List of paths * @param int $type LockManager::LOCK_* constant - * @return Status + * @return StatusValue */ final public function unlock( array $paths, $type = self::LOCK_EX ) { return $this->unlockByType( [ $type => $paths ] ); @@ -133,7 +133,7 @@ abstract class LockManager { * Unlock the resources at the given abstract paths * * @param array $pathsByType Map of LockManager::LOCK_* constants to lists of paths - * @return Status + * @return StatusValue * @since 1.22 */ final public function unlockByType( array $pathsByType ) { @@ -187,7 +187,7 @@ abstract class LockManager { /** * @see LockManager::lockByType() * @param array $pathsByType Map of LockManager::LOCK_* constants to lists of paths - * @return Status + * @return StatusValue * @since 1.22 */ protected function doLockByType( array $pathsByType ) { @@ -214,14 +214,14 @@ abstract class LockManager { * * @param array $paths List of paths * @param int $type LockManager::LOCK_* constant - * @return Status + * @return StatusValue */ abstract protected function doLock( array $paths, $type ); /** * @see LockManager::unlockByType() * @param array $pathsByType Map of LockManager::LOCK_* constants to lists of paths - * @return Status + * @return StatusValue * @since 1.22 */ protected function doUnlockByType( array $pathsByType ) { @@ -238,7 +238,7 @@ abstract class LockManager { * * @param array $paths List of paths * @param int $type LockManager::LOCK_* constant - * @return Status + * @return StatusValue */ abstract protected function doUnlock( array $paths, $type ); } diff --git a/includes/filebackend/lockmanager/MemcLockManager.php b/includes/filebackend/lockmanager/MemcLockManager.php index 2f17e2722c..2e2d0a3533 100644 --- a/includes/filebackend/lockmanager/MemcLockManager.php +++ b/includes/filebackend/lockmanager/MemcLockManager.php @@ -126,7 +126,7 @@ class MemcLockManager extends QuorumLockManager { * @param string $lockSrv * @param array $paths * @param string $type - * @return Status + * @return StatusValue */ protected function doGetLocksOnServer( $lockSrv, array $paths, $type ) { $status = Status::newGood(); @@ -202,7 +202,7 @@ class MemcLockManager extends QuorumLockManager { * @param string $lockSrv * @param array $paths * @param string $type - * @return Status + * @return StatusValue */ protected function doFreeLocksOnServer( $lockSrv, array $paths, $type ) { $status = Status::newGood(); @@ -254,7 +254,7 @@ class MemcLockManager extends QuorumLockManager { /** * @see QuorumLockManager::releaseAllLocks() - * @return Status + * @return StatusValue */ protected function releaseAllLocks() { return Status::newGood(); // not supported diff --git a/includes/filebackend/lockmanager/MySqlLockManager.php b/includes/filebackend/lockmanager/MySqlLockManager.php index 0536091bc4..896e0ffd64 100644 --- a/includes/filebackend/lockmanager/MySqlLockManager.php +++ b/includes/filebackend/lockmanager/MySqlLockManager.php @@ -35,7 +35,7 @@ class MySqlLockManager extends DBLockManager { * @param string $lockSrv * @param array $paths * @param string $type - * @return Status + * @return StatusValue */ protected function doGetLocksOnServer( $lockSrv, array $paths, $type ) { $status = Status::newGood(); @@ -105,7 +105,7 @@ class MySqlLockManager extends DBLockManager { /** * @see QuorumLockManager::releaseAllLocks() - * @return Status + * @return StatusValue */ protected function releaseAllLocks() { $status = Status::newGood(); diff --git a/includes/filebackend/lockmanager/PostgreSqlLockManager.php b/includes/filebackend/lockmanager/PostgreSqlLockManager.php index d55b5ae060..307c16447e 100644 --- a/includes/filebackend/lockmanager/PostgreSqlLockManager.php +++ b/includes/filebackend/lockmanager/PostgreSqlLockManager.php @@ -61,7 +61,7 @@ class PostgreSqlLockManager extends DBLockManager { /** * @see QuorumLockManager::releaseAllLocks() - * @return Status + * @return StatusValue */ protected function releaseAllLocks() { $status = Status::newGood(); diff --git a/includes/filebackend/lockmanager/QuorumLockManager.php b/includes/filebackend/lockmanager/QuorumLockManager.php index 108b8465cf..0db9e815fe 100644 --- a/includes/filebackend/lockmanager/QuorumLockManager.php +++ b/includes/filebackend/lockmanager/QuorumLockManager.php @@ -124,7 +124,7 @@ abstract class QuorumLockManager extends LockManager { * * @param int $bucket * @param array $pathsByType Map of LockManager::LOCK_* constants to lists of paths - * @return Status + * @return StatusValue */ final protected function doLockingRequestBucket( $bucket, array $pathsByType ) { $status = Status::newGood(); @@ -166,7 +166,7 @@ abstract class QuorumLockManager extends LockManager { * * @param int $bucket * @param array $pathsByType Map of LockManager::LOCK_* constants to lists of paths - * @return Status + * @return StatusValue */ final protected function doUnlockingRequestBucket( $bucket, array $pathsByType ) { $status = Status::newGood(); @@ -189,7 +189,7 @@ abstract class QuorumLockManager extends LockManager { } } } - // Set a bad status if the quorum was not met. + // Set a bad StatusValue if the quorum was not met. // Assumes the same "up" servers as during the acquire step. $status->setResult( $yesVotes >= $quorum ); @@ -222,7 +222,7 @@ abstract class QuorumLockManager extends LockManager { * * @param string $lockSrv * @param array $pathsByType Map of LockManager::LOCK_* constants to lists of paths - * @return Status + * @return StatusValue */ abstract protected function getLocksOnServer( $lockSrv, array $pathsByType ); @@ -233,7 +233,7 @@ abstract class QuorumLockManager extends LockManager { * * @param string $lockSrv * @param array $pathsByType Map of LockManager::LOCK_* constants to lists of paths - * @return Status + * @return StatusValue */ abstract protected function freeLocksOnServer( $lockSrv, array $pathsByType ); @@ -242,7 +242,7 @@ abstract class QuorumLockManager extends LockManager { * * Subclasses must effectively implement this or freeLocksOnServer(). * - * @return Status + * @return StatusValue */ abstract protected function releaseAllLocks(); } diff --git a/includes/filebackend/lockmanager/ScopedLock.php b/includes/filebackend/lockmanager/ScopedLock.php index e1a600ce11..05ab289dd6 100644 --- a/includes/filebackend/lockmanager/ScopedLock.php +++ b/includes/filebackend/lockmanager/ScopedLock.php @@ -35,7 +35,7 @@ class ScopedLock { /** @var LockManager */ protected $manager; - /** @var Status */ + /** @var StatusValue */ protected $status; /** @var array Map of lock types to resource paths */ @@ -44,9 +44,9 @@ class ScopedLock { /** * @param LockManager $manager * @param array $pathsByType Map of lock types to path lists - * @param Status $status + * @param StatusValue $status */ - protected function __construct( LockManager $manager, array $pathsByType, Status $status ) { + protected function __construct( LockManager $manager, array $pathsByType, StatusValue $status ) { $this->manager = $manager; $this->pathsByType = $pathsByType; $this->status = $status; @@ -55,19 +55,19 @@ class ScopedLock { /** * Get a ScopedLock object representing a lock on resource paths. * Any locks are released once this object goes out of scope. - * The status object is updated with any errors or warnings. + * The StatusValue object is updated with any errors or warnings. * * @param LockManager $manager * @param array $paths List of storage paths or map of lock types to path lists * @param int|string $type LockManager::LOCK_* constant or "mixed" and $paths * can be a map of types to paths (since 1.22). Otherwise $type should be an * integer and $paths should be a list of paths. - * @param Status $status + * @param StatusValue $status * @param int $timeout Timeout in seconds (0 means non-blocking) (since 1.22) * @return ScopedLock|null Returns null on failure */ public static function factory( - LockManager $manager, array $paths, $type, Status $status, $timeout = 0 + LockManager $manager, array $paths, $type, StatusValue $status, $timeout = 0 ) { $pathsByType = is_integer( $type ) ? [ $type => $paths ] : $paths; $lockStatus = $manager->lockByType( $pathsByType, $timeout ); @@ -80,7 +80,7 @@ class ScopedLock { } /** - * Release a scoped lock and set any errors in the attatched Status object. + * Release a scoped lock and set any errors in the attatched StatusValue object. * This is useful for early release of locks before function scope is destroyed. * This is the same as setting the lock object to null. * @@ -98,7 +98,7 @@ class ScopedLock { $wasOk = $this->status->isOK(); $this->status->merge( $this->manager->unlockByType( $this->pathsByType ) ); if ( $wasOk ) { - // Make sure status is OK, despite any unlockFiles() fatals + // Make sure StatusValue is OK, despite any unlockFiles() fatals $this->status->setResult( true, $this->status->value ); } } diff --git a/includes/filerepo/FileBackendDBRepoWrapper.php b/includes/filerepo/FileBackendDBRepoWrapper.php index 596dbded92..5bc60a0e0a 100644 --- a/includes/filerepo/FileBackendDBRepoWrapper.php +++ b/includes/filerepo/FileBackendDBRepoWrapper.php @@ -50,8 +50,10 @@ class FileBackendDBRepoWrapper extends FileBackend { protected $dbs; public function __construct( array $config ) { - $config['name'] = $config['backend']->getName(); - $config['wikiId'] = $config['backend']->getWikiId(); + /** @var FileBackend $backend */ + $backend = $config['backend']; + $config['name'] = $backend->getName(); + $config['wikiId'] = $backend->getWikiId(); parent::__construct( $config ); $this->backend = $config['backend']; $this->repoName = $config['repoName']; @@ -256,7 +258,7 @@ class FileBackendDBRepoWrapper extends FileBackend { return $this->translateSrcParams( __FUNCTION__, $params ); } - public function getScopedLocksForOps( array $ops, Status $status ) { + public function getScopedLocksForOps( array $ops, StatusValue $status ) { return $this->backend->getScopedLocksForOps( $ops, $status ); } diff --git a/includes/libs/StatusValue.php b/includes/libs/StatusValue.php index 7f41f55cf5..45185c5130 100644 --- a/includes/libs/StatusValue.php +++ b/includes/libs/StatusValue.php @@ -83,10 +83,10 @@ class StatusValue { * Splits this StatusValue object into two new StatusValue objects, one which contains only * the error messages, and one that contains the warnings, only. The returned array is * defined as: - * array( - * 0 => object(StatusValue) # the StatusValue with error messages, only - * 1 => object(StatusValue) # The StatusValue with warning messages, only - * ) + * [ + * 0 => object(StatusValue) # the StatusValue with error messages, only + * 1 => object(StatusValue) # The StatusValue with warning messages, only + * ] * * @return array */