mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/TemplateData
synced 2024-11-23 23:43:54 +00:00
7a32cba3ef
This makes it possible to use these steps independent from each other. For example, a future patch can get rid of the re-validation that's done over and over again when the API is called. A significant change is that this gets rid of an expensive deep clone. It was necessary before exactly because validation and normalization was intertwined. Normalized properties would mess with the later inheritance. Strictly splitting validation and normalization (and executing them in this order) solved this. The only downside of this is that inherited properties are validated twice. But this is much less of a problem, compared to the deep clone, I would like to argue. This was always covered by tests. You can still see the tests fail when you flip the execution order of inheritance and parameter validation. Bug: T301337 Change-Id: Ie5728094f9ed813f53b709d8b5283c4b99dc7d63
101 lines
2.6 KiB
PHP
101 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace MediaWiki\Extension\TemplateData;
|
|
|
|
use stdClass;
|
|
|
|
class TemplateDataNormalizer {
|
|
|
|
public const DEPRECATED_PARAMETER_TYPES = [
|
|
'string/line' => 'line',
|
|
'string/wiki-page-name' => 'wiki-page-name',
|
|
'string/wiki-user-name' => 'wiki-user-name',
|
|
'string/wiki-file-name' => 'wiki-file-name',
|
|
];
|
|
|
|
/** @var string */
|
|
private string $contentLanguageCode;
|
|
|
|
/**
|
|
* @param string $contentLanguageCode
|
|
*/
|
|
public function __construct( string $contentLanguageCode ) {
|
|
$this->contentLanguageCode = $contentLanguageCode;
|
|
}
|
|
|
|
/**
|
|
* @param stdClass $data Expected to be valid according to the {@see TemplateDataValidator}
|
|
*/
|
|
public function normalize( stdClass $data ) {
|
|
$data->description ??= null;
|
|
$data->sets ??= [];
|
|
$data->maps ??= (object)[];
|
|
$data->format ??= null;
|
|
|
|
$this->normaliseInterfaceText( $data->description );
|
|
foreach ( $data->sets as $setObj ) {
|
|
$this->normaliseInterfaceText( $setObj->label );
|
|
}
|
|
|
|
if ( isset( $data->params ) ) {
|
|
foreach ( $data->params as $param ) {
|
|
if ( isset( $param->inherits ) && isset( $data->params->{ $param->inherits } ) ) {
|
|
$parent = $data->params->{ $param->inherits };
|
|
foreach ( $parent as $key => $value ) {
|
|
if ( !isset( $param->$key ) ) {
|
|
$param->$key = is_object( $parent->$key ) ?
|
|
clone $parent->$key :
|
|
$parent->$key;
|
|
}
|
|
}
|
|
unset( $param->inherits );
|
|
}
|
|
$this->normalizeParameter( $param );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param stdClass $paramObj
|
|
*/
|
|
private function normalizeParameter( stdClass $paramObj ) {
|
|
$paramObj->label ??= null;
|
|
$paramObj->description ??= null;
|
|
$paramObj->required ??= false;
|
|
$paramObj->suggested ??= false;
|
|
$paramObj->deprecated ??= false;
|
|
$paramObj->aliases ??= [];
|
|
$paramObj->type ??= 'unknown';
|
|
$paramObj->autovalue ??= null;
|
|
$paramObj->default ??= null;
|
|
$paramObj->suggestedvalues ??= [];
|
|
$paramObj->example ??= null;
|
|
|
|
$this->normaliseInterfaceText( $paramObj->label );
|
|
$this->normaliseInterfaceText( $paramObj->description );
|
|
$this->normaliseInterfaceText( $paramObj->default );
|
|
$this->normaliseInterfaceText( $paramObj->example );
|
|
|
|
foreach ( $paramObj->aliases as &$alias ) {
|
|
if ( is_int( $alias ) ) {
|
|
$alias = (string)$alias;
|
|
}
|
|
}
|
|
|
|
// Map deprecated types to newer versions
|
|
if ( isset( self::DEPRECATED_PARAMETER_TYPES[$paramObj->type] ) ) {
|
|
$paramObj->type = self::DEPRECATED_PARAMETER_TYPES[$paramObj->type];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string|stdClass &$text
|
|
*/
|
|
private function normaliseInterfaceText( &$text ) {
|
|
if ( is_string( $text ) ) {
|
|
$text = (object)[ $this->contentLanguageCode => $text ];
|
|
}
|
|
}
|
|
|
|
}
|