wiki.techinc.nl/includes/Settings/Source/ReflectionSchemaSource.php
daniel 2fe23d6860 Use class constants to define config schema, rather than config-schema.yaml
Instead of maintaining the config schema as a yaml file, we
maintain it as a set of constants in a class. From the information in
these constants, we can generate a JSON schema (yaml) file, and an
php file containing optimized arrays for fast loading.

Advantages:
- PHP doc available to IDEs. The generated markdown file is no longer
  needed.
- Can use PHP constants when defining default values.

NOTE: needs backport to 1.38

Change-Id: I663c08b8a200644cbe7e5f65c20f1592a4f3974d
2022-03-17 21:20:03 +01:00

97 lines
1.8 KiB
PHP

<?php
namespace MediaWiki\Settings\Source;
use MediaWiki\Settings\SettingsBuilderException;
use ReflectionClass;
use ReflectionException;
/**
* Constructs a settings array based on a PHP class by inspecting class
* members to construct a schema.
*
* @since 1.38
*/
class ReflectionSchemaSource implements SettingsSource {
/**
* Name of a PHP class
* @var string
*/
private $class;
/**
* @var bool
*/
private $includeDoc;
/**
* @param string $class
* @param bool $includeDoc
*/
public function __construct( string $class, bool $includeDoc = false ) {
$this->class = $class;
$this->includeDoc = $includeDoc;
}
/**
* @throws SettingsBuilderException
* @return array
*/
public function load(): array {
$schemas = [];
try {
$class = new ReflectionClass( $this->class );
foreach ( $class->getReflectionConstants() as $const ) {
if ( !$const->isPublic() ) {
continue;
}
$name = $const->getName();
$value = $const->getValue();
if ( !is_array( $value ) ) {
continue;
}
if ( $this->includeDoc ) {
$doc = $const->getDocComment();
if ( $doc ) {
$value['description'] = $this->normalizeComment( $doc );
}
}
$schemas[ $name ] = $value;
}
} catch ( ReflectionException $e ) {
throw new SettingsBuilderException(
'Failed to load schema from class {class}',
[ 'class' => $this->class ],
0,
$e
);
}
return [
'config-schema' => $schemas
];
}
/**
* Returns this file source as a string.
*
* @return string
*/
public function __toString(): string {
return 'class ' . $this->class;
}
private function normalizeComment( string $doc ) {
$doc = preg_replace( '/^\s*\/\*+\s*|\s*\*+\/\s*$/s', '', $doc );
$doc = preg_replace( '/^\s*\**$/m', " ", $doc );
$doc = preg_replace( '/^\s*\**[ \t]?/m', '', $doc );
return $doc;
}
}