mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/TemplateData
synced 2024-11-15 03:34:44 +00:00
Merge "Make extension data JSON-serializable #1 - forward-compat."
This commit is contained in:
commit
5edb1fd72a
|
@ -68,7 +68,7 @@ class TemplateDataHooks {
|
|||
$format = $content->getContentHandler()->getDefaultFormat();
|
||||
$editInfo = $page->prepareContentForEdit( $content, null, $user, $format );
|
||||
|
||||
$templateDataStatus = $editInfo->output->getExtensionData( 'TemplateDataStatus' );
|
||||
$templateDataStatus = self::getStatusFromParserOutput( $editInfo->output );
|
||||
if ( $templateDataStatus instanceof Status && !$templateDataStatus->isOK() ) {
|
||||
// Abort edit, show error message from TemplateDataBlob::getStatus
|
||||
$status->merge( $templateDataStatus );
|
||||
|
@ -110,7 +110,7 @@ class TemplateDataHooks {
|
|||
|
||||
$status = $ti->getStatus();
|
||||
if ( !$status->isOK() ) {
|
||||
$parser->getOutput()->setExtensionData( 'TemplateDataStatus', $status );
|
||||
self::setStatusToParserOutput( $parser->getOutput(), $status );
|
||||
return '<div class="errorbox">' . $status->getHTML() . '</div>';
|
||||
}
|
||||
|
||||
|
@ -212,4 +212,69 @@ class TemplateDataHooks {
|
|||
$tplData[$tplTitle] = $tdb->getData();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the status to ParserOutput object.
|
||||
* @param ParserOutput $parserOutput
|
||||
* @param Status $status
|
||||
*/
|
||||
public static function setStatusToParserOutput( ParserOutput $parserOutput, Status $status ) {
|
||||
$parserOutput->setExtensionData( 'TemplateDataStatus', $status );
|
||||
// TODO: make JSON serializable. See T266252.
|
||||
// $parserOutput->setExtensionData( 'TemplateDataStatus',
|
||||
// self::jsonSerializeStatus( $status ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ParserOutput $parserOutput
|
||||
* @return Status|null
|
||||
*/
|
||||
public static function getStatusFromParserOutput( ParserOutput $parserOutput ) {
|
||||
$status = $parserOutput->getExtensionData( 'TemplateDataStatus' );
|
||||
if ( is_array( $status ) ) {
|
||||
return self::newStatusFromJson( $status );
|
||||
}
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $status contains StatusValue ok and errors fields (does not serialize value)
|
||||
* @return Status
|
||||
*/
|
||||
public static function newStatusFromJson( array $status ) : Status {
|
||||
if ( $status['ok'] ) {
|
||||
return Status::newGood();
|
||||
} else {
|
||||
$statusObj = new Status();
|
||||
$errors = $status['errors'];
|
||||
foreach ( $errors as $error ) {
|
||||
$statusObj->fatal( $error['message'], ...$error['params'] );
|
||||
}
|
||||
$warnings = $status['warnings'];
|
||||
foreach ( $warnings as $warning ) {
|
||||
$statusObj->warning( $warning['message'], ...$warning['params'] );
|
||||
}
|
||||
return $statusObj;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Status $status
|
||||
* @return array contains StatusValue ok and errors fields (does not serialize value)
|
||||
*/
|
||||
public static function jsonSerializeStatus( Status $status ) : array {
|
||||
if ( $status->isOK() ) {
|
||||
return [
|
||||
'ok' => true
|
||||
];
|
||||
} else {
|
||||
list( $errorsOnlyStatus, $warningsOnlyStatus ) = $status->splitByErrorType();
|
||||
// note that non-scalar values are not supported in errors or warnings
|
||||
return [
|
||||
'ok' => false,
|
||||
'errors' => $errorsOnlyStatus->getErrors(),
|
||||
'warnings' => $warningsOnlyStatus->getErrors()
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
73
tests/phpunit/SerializationTest.php
Normal file
73
tests/phpunit/SerializationTest.php
Normal file
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @group TemplateData
|
||||
* @covers \TemplateDataHooks::setStatusToParserOutput
|
||||
* @covers \TemplateDataHooks::getStatusFromParserOutput
|
||||
*/
|
||||
class SerializationTest extends MediaWikiTestCase {
|
||||
public function testParserOutputPersistenceForwardCompatibility() {
|
||||
$output = new ParserOutput();
|
||||
|
||||
$status = Status::newFatal( 'a', 'b', 'c' );
|
||||
$status->fatal( 'f' );
|
||||
$status->warning( 'd', 'e' );
|
||||
|
||||
// Set JSONified state. Should work before we set JSON-serializable data,
|
||||
// to be robust against old code reading new data after a rollback.
|
||||
$output->setExtensionData( 'TemplateDataStatus',
|
||||
TemplateDataHooks::jsonSerializeStatus( $status ) );
|
||||
|
||||
$result = TemplateDataHooks::getStatusFromParserOutput( $output );
|
||||
$this->assertEquals( $status->getStatusValue(), $result->getStatusValue() );
|
||||
$this->assertEquals( $status->__toString(), $result->__toString() );
|
||||
}
|
||||
|
||||
public function testParserOutputPersistenceBackwardCompatibility() {
|
||||
$output = new ParserOutput();
|
||||
|
||||
$status = Status::newFatal( 'a', 'b', 'c' );
|
||||
$status->fatal( 'f' );
|
||||
$status->warning( 'd', 'e' );
|
||||
|
||||
// Set the object directly. Should still work once we normally set JSON-serializable data.
|
||||
$output->setExtensionData( 'TemplateDataStatus', $status );
|
||||
|
||||
$result = TemplateDataHooks::getStatusFromParserOutput( $output );
|
||||
$this->assertEquals( $status->getStatusValue(), $result->getStatusValue() );
|
||||
$this->assertEquals( $status->__toString(), $result->__toString() );
|
||||
}
|
||||
|
||||
public function provideStatus() {
|
||||
yield [ Status::newGood() ];
|
||||
$status = Status::newFatal( 'a', 'b', 'c' );
|
||||
$status->fatal( 'f' );
|
||||
$status->warning( 'd', 'e' );
|
||||
yield [ $status ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideStatus
|
||||
* @covers \TemplateDataHooks::setStatusToParserOutput
|
||||
* @covers \TemplateDataHooks::getStatusFromParserOutput
|
||||
*/
|
||||
public function testParserOutputPersistenceRoundTrip( Status $status ) {
|
||||
$parserOutput = new ParserOutput();
|
||||
TemplateDataHooks::setStatusToParserOutput( $parserOutput, $status );
|
||||
$result = TemplateDataHooks::getStatusFromParserOutput( $parserOutput );
|
||||
$this->assertEquals( $status->getStatusValue(), $result->getStatusValue() );
|
||||
$this->assertEquals( $status->__toString(), $result->__toString() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideStatus
|
||||
* @covers \TemplateDataHooks::jsonSerializeStatus
|
||||
* @covers \TemplateDataHooks::newStatusFromJson
|
||||
*/
|
||||
public function testJsonRoundTrip( Status $status ) {
|
||||
$json = TemplateDataHooks::jsonSerializeStatus( $status );
|
||||
$result = TemplateDataHooks::newStatusFromJson( $json );
|
||||
$this->assertEquals( $status->getStatusValue(), $result->getStatusValue() );
|
||||
$this->assertEquals( $status->__toString(), $result->__toString() );
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue