StatusValue: Allow passing arbitrary data to augment result

This allows extensions and hooks to pass around additional data
about the operation result arbitrarily to supplement value and errors.

When two StatusValue instances are to be merged, it's responsibility
of the caller to ensure either only one has this extra data or none,
but never both (since the type is unrestricted). If necessary, the
caller should merge them before invoking StatusValue::merge.

Bug: T326479
Change-Id: Ibe3f1f8b81bcfcb18551d3ca4cda464e4bdbcbce
This commit is contained in:
Ammarpad 2023-11-28 12:54:20 +01:00
parent c41990cb2e
commit 42e166dd83
5 changed files with 17 additions and 6 deletions

View file

@ -107,6 +107,9 @@ because of Phabricator reports.
in the future without further notice.
* MediaWikiIntegrationTestCase::$tablesUsed has been deprecated. The framework
now detects these automatically.
* Support for setting dynamic property on StatusValue object has been removed.
To pass your arbitrary data along the object, use StatusValue::statusData
property (which is always declared).
* …
=== Deprecations in 1.42 ===

View file

@ -83,6 +83,7 @@ class Status extends StatusValue {
$result->successCount =& $sv->successCount;
$result->failCount =& $sv->failCount;
$result->success =& $sv->success;
$result->statusData =& $sv->statusData;
return $result;
}
@ -116,9 +117,6 @@ class Status extends StatusValue {
public 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." );
}

View file

@ -539,8 +539,8 @@ class ApiEditPage extends ApiBase {
switch ( $statusValue ) {
case EditPage::AS_HOOK_ERROR:
case EditPage::AS_HOOK_ERROR_EXPECTED:
if ( isset( $status->apiHookResult ) ) {
$r = $status->apiHookResult;
if ( $status->statusData !== null ) {
$r = $status->statusData;
$r['result'] = 'Failure';
$apiResult->addValue( null, $this->getModuleName(), $r );
return;

View file

@ -63,6 +63,9 @@ class StatusValue {
/** @var int Counter for batch operations */
public $failCount = 0;
/** @var mixed arbitrary extra data about the operation */
public $statusData;
/**
* Factory function for fatal errors
*
@ -285,6 +288,12 @@ class StatusValue {
* @return $this
*/
public function merge( $other, $overwriteValue = false ) {
if ( $this->statusData !== null && $other->statusData !== null ) {
throw new RuntimeException( "Status cannot be merged, because they both have \$statusData" );
} else {
$this->statusData ??= $other->statusData;
}
foreach ( $other->errors as $error ) {
$this->addError( $error );
}
@ -294,6 +303,7 @@ class StatusValue {
}
$this->successCount += $other->successCount;
$this->failCount += $other->failCount;
return $this;
}

View file

@ -1558,7 +1558,7 @@ class ApiEditPageTest extends ApiTestCase {
$this->setTemporaryHook( 'EditFilterMergedContent',
static function ( $unused1, $unused2, Status $status ) {
$status->apiHookResult = [ 'msg' => 'A message for you!' ];
$status->statusData = [ 'msg' => 'A message for you!' ];
return false;
} );