Browse Source

Fix configuration exporting

microsub
J. King 5 years ago
parent
commit
5335d331f7
  1. 42
      lib/Conf.php
  2. 2
      tests/cases/Conf/TestConf.php

42
lib/Conf.php

@ -184,17 +184,23 @@ class Conf {
/** Outputs configuration settings, either non-default ones or all, as an associative array /** Outputs configuration settings, either non-default ones or all, as an associative array
* @param bool $full Whether to output all configuration options rather than only changed ones */ * @param bool $full Whether to output all configuration options rather than only changed ones */
public function export(bool $full = false): array { public function export(bool $full = false): array {
$ref = new self;
$out = [];
$conf = new \ReflectionObject($this); $conf = new \ReflectionObject($this);
$ref = (new \ReflectionClass($this))->getDefaultProperties();
$out = [];
foreach ($conf->getProperties(\ReflectionProperty::IS_PUBLIC) as $prop) { foreach ($conf->getProperties(\ReflectionProperty::IS_PUBLIC) as $prop) {
$name = $prop->name; $name = $prop->name;
// add the property to the output if the value is of a supported type and either: $value = $prop->getValue($this);
// 1. full output has been requested if ($prop->isDefault()) {
// 2. the property is not defined in the class $default = $ref[$name];
// 3. it differs from the default // if the property is a known property (rather than one added by a hypothetical plug-in)
if ((is_scalar($this->$name) || is_null($this->$name)) && ($full || !$prop->isDefault() || $this->$name !== $ref->$name)) { // we convert intervals to strings and then export anything which doesn't match the default value
$out[$name] = $this->$name; $value = $this->propertyExport($name, $value);
if ((is_scalar($value) || is_null($value)) && ($full || $value !== $ref[$name])) {
$out[$name] = $value;
}
} elseif (is_scalar($value) || is_null($value)) {
// otherwise export the property only if it is scalar
$out[$name] = $value;
} }
} }
return $out; return $out;
@ -213,13 +219,11 @@ class Conf {
// retrieve the property's docblock, if it exists // retrieve the property's docblock, if it exists
try { try {
$doc = (new \ReflectionProperty(self::class, $prop))->getDocComment(); $doc = (new \ReflectionProperty(self::class, $prop))->getDocComment();
} catch (\ReflectionException $e) {
}
if ($doc) {
// parse the docblock to extract the property description // parse the docblock to extract the property description
if (preg_match("<@var\s+\S+\s+(.+?)(?:\s*\*/)?$>m", $doc, $match)) { if (preg_match("<@var\s+\S+\s+(.+?)(?:\s*\*/)?\s*$>m", $doc, $match)) {
$comment = $match[1]; $comment = $match[1];
} }
} catch (\ReflectionException $e) {
} }
// append the docblock description if there is one, or an empty comment otherwise // append the docblock description if there is one, or an empty comment otherwise
$out .= " // ".$comment.PHP_EOL; $out .= " // ".$comment.PHP_EOL;
@ -310,4 +314,18 @@ class Conf {
throw new Conf\Exception("typeMismatch", ['param' => $key, 'type' => self::TYPE_NAMES[$type], 'file' => $file, 'nullable' => $nullable]); throw new Conf\Exception("typeMismatch", ['param' => $key, 'type' => self::TYPE_NAMES[$type], 'file' => $file, 'nullable' => $nullable]);
} }
} }
protected function propertyExport(string $key, $value) {
$value = ($value instanceof \DateInterval) ? Value::normalize($value, Value::T_STRING) : $value;
switch ($key) {
case "dbDriver":
return array_flip(Database::DRIVER_NAMES)[$value] ?? $value;
case "userDriver":
return array_flip(User::DRIVER_NAMES)[$value] ?? $value;
case "serviceDriver":
return array_flip(Service::DRIVER_NAMES)[$value] ?? $value;
default:
return $value;
}
}
} }

2
tests/cases/Conf/TestConf.php

@ -122,10 +122,12 @@ class TestConf extends \JKingWeb\Arsse\Test\AbstractTest {
$conf->lang = ["en", "fr"]; // should not be exported: not scalar $conf->lang = ["en", "fr"]; // should not be exported: not scalar
$conf->dbSQLite3File = "test.db"; // should be exported: value changed $conf->dbSQLite3File = "test.db"; // should be exported: value changed
$conf->userDriver = null; // should be exported: changed value, even when null $conf->userDriver = null; // should be exported: changed value, even when null
$conf->serviceFrequency = new \DateInterval("PT1H"); // should be exported (as string): value changed
$conf->someCustomProperty = "Look at me!"; // should be exported: unknown property $conf->someCustomProperty = "Look at me!"; // should be exported: unknown property
$exp = [ $exp = [
'dbSQLite3File' => "test.db", 'dbSQLite3File' => "test.db",
'userDriver' => null, 'userDriver' => null,
'serviceFrequency' => "PT1H",
'someCustomProperty' => "Look at me!", 'someCustomProperty' => "Look at me!",
]; ];
$this->assertSame($exp, $conf->export()); $this->assertSame($exp, $conf->export());

Loading…
Cancel
Save