wiki.techinc.nl/tests/phpunit/includes/parser/ParserCacheSerializationTestCases.php
James D. Forrester 19f4e6945a Rename JsonUnserial… to JsonDeserial…
This is to make it clearer that they're related to converting serialized
content back into JSON, rather than stating that things are not
representable in JSON.

Change-Id: Ic440ac2d05b5ac238a1c0e4821d3f2d858bc3d76
2024-06-12 14:50:58 -04:00

521 lines
22 KiB
PHP

<?php
namespace MediaWiki\Tests\Parser;
use CacheTime;
use JsonSerializable;
use MediaWiki\Debug\MWDebug;
use MediaWiki\Json\JsonCodec;
use MediaWiki\Parser\ParserOutput;
use MediaWiki\Title\Title;
use MediaWiki\Title\TitleValue;
use MediaWiki\Utils\MWTimestamp;
use MediaWikiIntegrationTestCase;
use Wikimedia\TestingAccessWrapper;
use Wikimedia\Tests\SerializationTestUtils;
/**
* A collection of serialization test cases for parser cache.
*
* Contains a set of acceptance tests for CacheTime and ParserOutput objects.
* The acceptance tests will be run on instances created by the current code,
* as well as instances deserialized from stored serializations for various MW
* versions.
*
* Since backwards compatibility for objects stored in ParserCache is necessary,
* failure of a deserialization test most likely indicates an error in the code.
* However, since the serialization format may change, thus if proper compatibility
* logic was added but a serialization test is still failing, you might want to
* update stored serialized data using validateParserCacheSerializationTestData.php
* script. The same script should be run when more acceptance tests are added
* to generate and save serialized object, which would be used for acceptance
* deserialization tests.
*
* @see SerializationTestTrait
* @see SerializationTestUtils
* @see ValidateParserCacheSerializationTestData
*/
abstract class ParserCacheSerializationTestCases {
public const FAKE_TIME = 123456789;
public const FAKE_CACHE_EXPIRY = 42;
private const MOCK_EXT_DATA = [
'boolean' => true,
'null' => null,
'number' => 42,
'string' => 'string',
'array' => [ 1, 2, 3 ],
'map' => [ 'key' => 'value' ]
];
private const MOCK_FALSY_PROPERTIES = [
'boolean' => false,
'null' => null,
'number' => 0,
'string' => '',
'numstring' => '0',
'array' => [],
];
private const MOCK_BINARY_PROPERTIES = [
'empty' => '',
'\x00' => "\x00",
'gzip' => "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\xcb\x48\xcd\xc9\xc9\x57\x28\xcf\x2f'
. '\xca\x49\x01\x00\x85\x11\x4a\x0d\x0b\x00\x00\x00",
];
private const SECTIONS = [
[
'toclevel' => 0,
'line' => 'heading_1',
'level' => 1,
'number' => '1.0',
'index' => 'T-1',
'fromtitle' => '',
'byteoffset' => null,
'anchor' => 'heading_1',
'linkAnchor' => '#heading_1',
],
[
'toclevel' => 1,
'line' => 'heading_2',
'level' => 2,
'number' => '2.0',
'index' => 'T-2',
'fromtitle' => '',
'byteoffset' => null,
'anchor' => 'heading_2',
'linkAnchor' => '#heading_2'
],
];
private const CACHE_TIME = '20010419042521';
/**
* Get acceptance test cases for CacheTime class.
* @see SerializationTestTrait::getTestInstancesAndAssertions()
* @return array[]
*/
public static function getCacheTimeTestCases(): array {
$cacheTimeWithUsedOptions = new CacheTime();
$cacheTimeWithUsedOptions->recordOptions( [ 'optA', 'optX' ] );
$cacheTimeWithTime = new CacheTime();
$cacheTimeWithTime->setCacheTime( self::CACHE_TIME );
$cacheExpiry = 10;
$cacheTimeWithExpiry = new CacheTime();
$cacheTimeWithExpiry->updateCacheExpiry( $cacheExpiry );
$cacheRevisionId = 1234;
$cacheTimeWithRevId = new CacheTime();
$cacheTimeWithRevId->setCacheRevisionId( $cacheRevisionId );
return [
'empty' => [
'instance' => new CacheTime(),
'assertions' => static function ( MediaWikiIntegrationTestCase $testCase, CacheTime $object ) {
$testCase->assertSame( self::FAKE_CACHE_EXPIRY, $object->getCacheExpiry() );
$testCase->assertNull( $object->getCacheRevisionId() );
$testCase->assertSame(
MWTimestamp::convert( TS_MW, self::FAKE_TIME ),
$object->getCacheTime()
);
// When the cacheRevisionId is not set, this method always returns true.
$testCase->assertFalse( $object->isDifferentRevision( 29 ) );
$testCase->assertFalse( $object->isDifferentRevision( 31 ) );
$testCase->assertTrue( $object->isCacheable() );
$testCase->assertSame(
$object->getCacheTime(),
MWTimestamp::convert( TS_MW, self::FAKE_TIME )
);
}
],
'usedOptions' => [
'instance' => $cacheTimeWithUsedOptions,
'assertions' => static function ( MediaWikiIntegrationTestCase $testCase, CacheTime $object ) {
$testCase->assertArrayEquals( [ 'optA', 'optX' ], $object->getUsedOptions() );
}
],
'cacheTime' => [
'instance' => $cacheTimeWithTime,
'assertions' => static function (
MediaWikiIntegrationTestCase $testCase, CacheTime $object
) {
$testCase->assertSame( self::CACHE_TIME, $object->getCacheTime() );
}
],
'cacheExpiry' => [
'instance' => $cacheTimeWithExpiry,
'assertions' => static function (
MediaWikiIntegrationTestCase $testCase, CacheTime $object
) use ( $cacheExpiry ) {
$testCase->assertSame( $cacheExpiry, $object->getCacheExpiry() );
}
],
'cacheRevisionId' => [
'instance' => $cacheTimeWithRevId,
'assertions' => static function (
MediaWikiIntegrationTestCase $testCase, CacheTime $object
) use ( $cacheRevisionId ) {
$testCase->assertSame( $cacheRevisionId, $object->getCacheRevisionId() );
}
]
];
}
/**
* Get acceptance test cases for ParserOutput class.
* @see SerializationTestTrait::getTestInstancesAndAssertions()
* @return array[]
*/
public static function getParserOutputTestCases() {
MWDebug::filterDeprecationForTest( '/::setPageProperty with non-scalar value/' );
$parserOutputWithCacheTimeProps = new ParserOutput( 'CacheTime' );
$parserOutputWithCacheTimeProps->setCacheTime( self::CACHE_TIME );
$parserOutputWithCacheTimeProps->updateCacheExpiry( 10 );
$parserOutputWithCacheTimeProps->setCacheRevisionId( 42 );
$parserOutputWithUsedOptions = new ParserOutput( 'Dummy' );
$parserOutputWithUsedOptions->recordOption( 'optA' );
$parserOutputWithUsedOptions->recordOption( 'optX' );
$parserOutputWithExtensionData = new ParserOutput( '' );
foreach ( self::MOCK_EXT_DATA as $key => $value ) {
$parserOutputWithExtensionData->setExtensionData( $key, $value );
}
$parserOutputWithProperties = new ParserOutput( '' );
foreach ( self::MOCK_EXT_DATA as $key => $value ) {
$parserOutputWithProperties->setPageProperty( $key, $value );
}
$parserOutputWithFalsyProperties = new ParserOutput( '' );
foreach ( self::MOCK_FALSY_PROPERTIES as $key => $value ) {
$parserOutputWithFalsyProperties->setPageProperty( $key, $value );
}
$parserOutputWithBinaryProperties = new ParserOutput( '' );
foreach ( self::MOCK_BINARY_PROPERTIES as $key => $value ) {
$parserOutputWithBinaryProperties->setPageProperty( $key, $value );
}
$parserOutputWithMetadata = new ParserOutput( '' );
$parserOutputWithMetadata->setSpeculativeRevIdUsed( 42 );
$parserOutputWithMetadata->addLanguageLink( Title::makeTitle( NS_MAIN, 'link1' ) );
$parserOutputWithMetadata->addLanguageLink( Title::makeTItle( NS_MAIN, 'link2' ) );
$parserOutputWithMetadata->addInterwikiLink( Title::makeTitle( NS_MAIN, 'interwiki1', '', 'enwiki' ) );
$parserOutputWithMetadata->addInterwikiLink( Title::makeTitle( NS_MAIN, 'interwiki2', '', 'enwiki' ) );
$parserOutputWithMetadata->addCategory( Title::makeTitle( NS_CATEGORY, 'category2' ), '1' );
$parserOutputWithMetadata->addCategory( Title::makeTitle( NS_CATEGORY, 'category1' ), '2' );
$parserOutputWithMetadata->setIndicator( 'indicator1', 'indicator1_value' );
$parserOutputWithMetadata->setTitleText( 'title_text1' );
$parserOutputWithMetadata->setSections( self::SECTIONS );
$parserOutputWithMetadata->addLink( Title::makeTitle( NS_MAIN, 'Link1' ), 42 );
$parserOutputWithMetadata->addLink( Title::makeTitle( NS_USER, 'Link2' ), 43 );
$parserOutputWithMetadata->addTemplate(
Title::makeTitle( NS_TEMPLATE, 'Template1' ),
42,
4242
);
$parserOutputWithMetadata->addImage(
new TitleValue( NS_FILE, 'Image1' ),
MWTimestamp::convert( TS_MW, 123456789 ),
'test_sha1'
);
$parserOutputWithMetadata->addExternalLink( 'https://test.org' );
$parserOutputWithMetadata->addHeadItem( 'head_item1', 'tag1' );
$parserOutputWithMetadata->addModules( [ 'module1' ] );
$parserOutputWithMetadata->addModuleStyles( [ 'module_style1' ] );
$parserOutputWithMetadata->setJsConfigVar( 'key1', 'value1' );
$parserOutputWithMetadata->addWarningMsg( 'rawmessage', 'warning1' );
$parserOutputWithMetadata->setIndexPolicy( 'noindex' );
$parserOutputWithMetadata->setRevisionTimestamp( MWTimestamp::convert( TS_MW, 987654321 ) );
$parserOutputWithMetadata->setLimitReportData( 'limit_report_key1', 'value1' );
$parserOutputWithMetadata->setEnableOOUI( true );
$parserOutputWithMetadata->setHideNewSection( true );
$parserOutputWithMetadata->setNewSection( true );
$parserOutputWithMetadata->setOutputFlag( 'test' );
// For compatibility with older serialized objects, clear out the
// $mWarningMsgs array, which is not currently stored.
// See T343050 for the steps required to remove this workaround in
// the future.
TestingAccessWrapper::newFromObject(
$parserOutputWithMetadata
)->mWarningMsgs = [];
$parserOutputWithSections = new ParserOutput( '' );
$parserOutputWithSections->setSections( self::SECTIONS );
$parserOutputWithMetadataPost1_31 = new ParserOutput( '' );
$parserOutputWithMetadataPost1_31->addWrapperDivClass( 'test_wrapper' );
$parserOutputWithMetadataPost1_31->setSpeculativePageIdUsed( 4242 );
$parserOutputWithMetadataPost1_31->setRevisionTimestampUsed(
MWTimestamp::convert( TS_MW, 123456789 )
);
$parserOutputWithMetadataPost1_31->setRevisionUsedSha1Base36( 'test_hash' );
$parserOutputWithMetadataPost1_31->setNoGallery( true );
$parserOutputWithMetadataPost1_34 = new ParserOutput( '' );
$parserOutputWithMetadataPost1_34->addExtraCSPStyleSrc( 'style1' );
$parserOutputWithMetadataPost1_34->addExtraCSPDefaultSrc( 'default1' );
$parserOutputWithMetadataPost1_34->addExtraCSPScriptSrc( 'script1' );
$parserOutputWithMetadataPost1_34->addLink( Title::makeTitle( NS_SPECIAL, 'Link3' ) );
MWDebug::clearDeprecationFilters();
return [
'empty' => [
'instance' => new ParserOutput( '' ),
'assertions' => static function ( MediaWikiIntegrationTestCase $testCase, ParserOutput $object ) {
// Empty CacheTime assertions
self::getCacheTimeTestCases()['empty']['assertions']( $testCase, $object );
// Empty string text is counted as having text.
$testCase->assertTrue( $object->hasText() );
$testCase->assertSame( '', $object->getText() );
$testCase->assertSame( '', $object->getWrapperDivClass() );
$testCase->assertNull( $object->getSpeculativeRevIdUsed() );
$testCase->assertNull( $object->getSpeculativePageIdUsed() );
$testCase->assertNull( $object->getRevisionTimestampUsed() );
$testCase->assertNull( $object->getRevisionUsedSha1Base36() );
$testCase->assertArrayEquals( [], $object->getLanguageLinks() );
$testCase->assertArrayEquals( [], $object->getInterwikiLinks() );
$testCase->assertArrayEquals( [], $object->getCategoryNames() );
$testCase->assertArrayEquals( [], $object->getCategoryMap() );
$testCase->assertArrayEquals( [], $object->getIndicators() );
$testCase->assertSame( '', $object->getTitleText() );
$testCase->assertArrayEquals( [], $object->getSections() );
$testCase->assertArrayEquals( [], $object->getLinks() );
$testCase->assertArrayEquals( [], $object->getLinksSpecial() );
$testCase->assertArrayEquals( [], $object->getTemplates() );
$testCase->assertArrayEquals( [], $object->getTemplateIds() );
$testCase->assertArrayEquals( [], $object->getImages() );
$testCase->assertArrayEquals( [], $object->getFileSearchOptions() );
$testCase->assertArrayEquals( [], $object->getExternalLinks() );
$testCase->assertFalse( $object->getNoGallery() );
$testCase->assertArrayEquals( [], $object->getHeadItems() );
$testCase->assertArrayEquals( [], $object->getModules() );
$testCase->assertArrayEquals( [], $object->getModuleStyles() );
$testCase->assertArrayEquals( [], $object->getJsConfigVars() );
$testCase->assertArrayEquals( [], $object->getWarnings() );
$testCase->assertSame( '', $object->getIndexPolicy() );
$testCase->assertNull( $object->getRevisionTimestamp() );
$testCase->assertArrayEquals( [], $object->getLimitReportData() );
$testCase->assertArrayEquals( [], $object->getLimitReportJSData() );
$testCase->assertFalse( $object->getEnableOOUI() );
$testCase->assertArrayEquals( [], $object->getExtraCSPDefaultSrcs() );
$testCase->assertArrayEquals( [], $object->getExtraCSPScriptSrcs() );
$testCase->assertArrayEquals( [], $object->getExtraCSPStyleSrcs() );
$testCase->assertFalse( $object->getHideNewSection() );
$testCase->assertFalse( $object->getNewSection() );
$testCase->assertFalse( $object->getDisplayTitle() );
$testCase->assertFalse( $object->getOutputFlag( 'test' ) );
$testCase->assertArrayEquals( [], $object->getAllFlags() );
$testCase->assertNull( $object->getPageProperty( 'test_prop' ) );
$testCase->assertArrayEquals( [], $object->getPageProperties() );
$testCase->assertArrayEquals( [], $object->getUsedOptions() );
$testCase->assertNull( $object->getExtensionData( 'test_ext_data' ) );
$testCase->assertNull( $object->getTimeProfile( 'wall' ) );
}
],
'cacheTime' => [
'instance' => $parserOutputWithCacheTimeProps,
'assertions' => static function ( MediaWikiIntegrationTestCase $testCase, ParserOutput $object ) {
$testCase->assertSame( self::CACHE_TIME, $object->getCacheTime() );
$testCase->assertSame( 10, $object->getCacheExpiry() );
$testCase->assertSame( 42, $object->getCacheRevisionId() );
}
],
'text' => [
'instance' => new ParserOutput( 'Lorem Ipsum' ),
'assertions' => static function ( MediaWikiIntegrationTestCase $testCase, ParserOutput $object ) {
$testCase->assertTrue( $object->hasText() );
$testCase->assertSame( 'Lorem Ipsum', $object->getRawText() );
$testCase->assertSame( 'Lorem Ipsum', $object->getText() );
}
],
'usedOptions' => [
'instance' => $parserOutputWithUsedOptions,
'assertions' => static function ( MediaWikiIntegrationTestCase $testCase, ParserOutput $object ) {
$testCase->assertArrayEquals( [ 'optA', 'optX' ], $object->getUsedOptions() );
}
],
'extensionData' => [
'instance' => $parserOutputWithExtensionData,
'assertions' => static function ( MediaWikiIntegrationTestCase $testCase, ParserOutput $object ) {
$testCase->assertSame( self::MOCK_EXT_DATA['boolean'], $object->getExtensionData( 'boolean' ) );
$testCase->assertSame( self::MOCK_EXT_DATA['null'], $object->getExtensionData( 'null' ) );
$testCase->assertSame( self::MOCK_EXT_DATA['number'], $object->getExtensionData( 'number' ) );
$testCase->assertSame( self::MOCK_EXT_DATA['string'], $object->getExtensionData( 'string' ) );
$testCase->assertArrayEquals( self::MOCK_EXT_DATA['array'], $object->getExtensionData( 'array' ) );
$testCase->assertSame( self::MOCK_EXT_DATA['map'], $object->getExtensionData( 'map' ) );
}
],
'pageProperties' => [
'instance' => $parserOutputWithProperties,
'assertions' => static function ( MediaWikiIntegrationTestCase $testCase, ParserOutput $object ) {
$testCase->assertSame( self::MOCK_EXT_DATA['boolean'], $object->getPageProperty( 'boolean' ) );
$testCase->assertSame( self::MOCK_EXT_DATA['null'], $object->getPageProperty( 'null' ) );
$testCase->assertSame( self::MOCK_EXT_DATA['number'], $object->getPageProperty( 'number' ) );
$testCase->assertSame( self::MOCK_EXT_DATA['string'], $object->getPageProperty( 'string' ) );
$testCase->assertArrayEquals( self::MOCK_EXT_DATA['array'], $object->getPageProperty( 'array' ) );
$testCase->assertSame( self::MOCK_EXT_DATA['map'], $object->getPageProperty( 'map' ) );
$testCase->assertArrayEquals( self::MOCK_EXT_DATA, $object->getPageProperties() );
}
],
'binaryPageProperties' => [
'instance' => $parserOutputWithBinaryProperties,
'assertions' => static function ( MediaWikiIntegrationTestCase $testCase, ParserOutput $object ) {
$testCase->assertSame( self::MOCK_BINARY_PROPERTIES['empty'], $object->getPageProperty( 'empty' ) );
$testCase->assertSame( self::MOCK_BINARY_PROPERTIES['\x00'], $object->getPageProperty( '\x00' ) );
$testCase->assertSame( self::MOCK_BINARY_PROPERTIES['gzip'], $object->getPageProperty( 'gzip' ) );
$testCase->assertArrayEquals( self::MOCK_BINARY_PROPERTIES, $object->getPageProperties() );
}
],
'withMetadata' => [
'instance' => $parserOutputWithMetadata,
'assertions' => static function ( MediaWikiIntegrationTestCase $testCase, ParserOutput $object ) {
$testCase->assertSame( 42, $object->getSpeculativeRevIdUsed() );
$testCase->assertArrayEquals( [ 'link1', 'link2' ], $object->getLanguageLinks() );
$testCase->assertArrayEquals( [ 'enwiki' => [
'interwiki1' => 1,
'interwiki2' => 1
] ], $object->getInterwikiLinks() );
$testCase->assertArrayEquals( [ 'category1', 'category2' ], $object->getCategoryNames() );
$testCase->assertArrayEquals( [
'category1' => '2',
'category2' => '1'
], $object->getCategoryMap() );
$testCase->assertArrayEquals( [ 'indicator1' => 'indicator1_value' ], $object->getIndicators() );
$testCase->assertSame( 'title_text1', $object->getTitleText() );
$testCase->assertArrayEquals( self::SECTIONS, $object->getSections() );
$testCase->assertArrayEquals( [
NS_MAIN => [ 'Link1' => 42 ],
NS_USER => [ 'Link2' => 43 ]
], $object->getLinks() );
$testCase->assertArrayEquals( [
NS_SPECIAL => [ 'Template1' => 42 ]
], $object->getTemplates() );
$testCase->assertArrayEquals( [
NS_SPECIAL => [ 'Template1' => 4242 ]
], $object->getTemplateIds() );
$testCase->assertArrayEquals( [ 'Image1' => 1 ], $object->getImages() );
$testCase->assertArrayEquals( [ 'Image1' => [
'time' => MWTimestamp::convert( TS_MW, 123456789 ), 'sha1' => 'test_sha1'
] ], $object->getFileSearchOptions() );
$testCase->assertArrayEquals( [ 'https://test.com' => 1 ], $object->getExternalLinks() );
$testCase->assertArrayEquals( [ 'tag1' => 'head_item1' ], $object->getHeadItems() );
$testCase->assertArrayEquals( [ 'module1' ], $object->getModules() );
$testCase->assertArrayEquals( [ 'module_style1' ], $object->getModuleStyles() );
$testCase->assertArrayEquals( [ 'key1' => 'value1' ], $object->getJsConfigVars() );
$testCase->assertArrayEquals( [ 'warning1' ], $object->getWarnings() );
$testCase->assertSame( 'noindex', $object->getIndexPolicy() );
$testCase->assertSame( MWTimestamp::convert( TS_MW, 987654321 ), $object->getRevisionTimestamp() );
$testCase->assertArrayEquals(
[ 'limit_report_key1' => 'value1' ],
$object->getLimitReportData()
);
$testCase->assertArrayEquals(
[ 'limit_report_key1' => 'value1' ],
$object->getLimitReportJSData()
);
$testCase->assertTrue( $object->getEnableOOUI() );
$testCase->assertTrue( $object->getHideNewSection() );
$testCase->assertTrue( $object->getNewSection() );
$testCase->assertTrue( $object->getOutputFlag( 'test' ) );
$testCase->assertArrayEquals( [ 'test' ], $object->getAllFlags() );
}
],
'withSections' => [
'instance' => $parserOutputWithSections,
'assertions' => static function ( MediaWikiIntegrationTestCase $testCase, ParserOutput $object ) {
$testCase->assertArrayEquals( self::SECTIONS, $object->getSections() );
}
],
'withMetadataPost1_31' => [
'instance' => $parserOutputWithMetadataPost1_31,
'assertions' => static function ( MediaWikiIntegrationTestCase $testCase, ParserOutput $object ) {
$testCase->assertSame( 'test_wrapper', $object->getWrapperDivClass() );
$testCase->assertSame( 4242, $object->getSpeculativePageIdUsed() );
$testCase->assertSame(
MWTimestamp::convert( TS_MW, 123456789 ),
$object->getRevisionTimestampUsed()
);
$testCase->assertSame( 'test_hash', $object->getRevisionUsedSha1Base36() );
$testCase->assertTrue( $object->getNoGallery() );
}
],
'withMetadataPost1_34' => [
'instance' => $parserOutputWithMetadataPost1_34,
'assertions' => static function ( MediaWikiIntegrationTestCase $testCase, ParserOutput $object ) {
$testCase->assertArrayEquals( [ 'default1' ], $object->getExtraCSPDefaultSrcs() );
$testCase->assertArrayEquals( [ 'script1' ], $object->getExtraCSPScriptSrcs() );
$testCase->assertArrayEquals( [ 'style1' ], $object->getExtraCSPStyleSrcs() );
$testCase->assertArrayEquals( [ 'Link3' => 1 ], $object->getLinksSpecial() );
}
],
'withFalsyProperties' => [
'instance' => $parserOutputWithFalsyProperties,
'assertions' => static function ( MediaWikiIntegrationTestCase $testCase, ParserOutput $object ) {
$testCase->assertSame(
self::MOCK_FALSY_PROPERTIES['boolean'],
$object->getPageProperty( 'boolean' )
);
$testCase->assertSame(
self::MOCK_FALSY_PROPERTIES['null'],
$object->getPageProperty( 'null' )
);
$testCase->assertSame(
self::MOCK_FALSY_PROPERTIES['number'],
$object->getPageProperty( 'number' )
);
$testCase->assertSame(
self::MOCK_FALSY_PROPERTIES['string'],
$object->getPageProperty( 'string' )
);
$testCase->assertSame(
self::MOCK_FALSY_PROPERTIES['numstring'],
$object->getPageProperty( 'numstring' )
);
$testCase->assertArrayEquals(
self::MOCK_FALSY_PROPERTIES['array'],
$object->getPageProperty( 'array' )
);
}
],
];
}
/**
* @param string $class the class name
* @return string[][] a list of supported serialization formats info
* in the following format:
* 'ext' => string file extension for stored serializations
* 'serializer' => callable to serialize objects
* 'deserializer' => callable to deserialize objects
*/
public static function getSupportedSerializationFormats( string $class ): array {
$serializationFormats = [ [
'ext' => 'serialized',
'serializer' => 'serialize',
'deserializer' => 'unserialize'
] ];
if ( is_subclass_of( $class, JsonSerializable::class ) ) {
$jsonCodec = new JsonCodec();
$serializationFormats[] = [
'ext' => 'json',
'serializer' => static function ( JsonSerializable $obj ) use ( $jsonCodec ) {
return $jsonCodec->serialize( $obj );
},
'deserializer' => static function ( $data ) use ( $jsonCodec ) {
return $jsonCodec->deserialize( $data );
}
];
}
return $serializationFormats;
}
}