[config] Add ability to deprecate a node

This commit is contained in:
Sanpi 2017-04-11 21:49:38 +02:00 committed by Nicolas Grekas
parent 660feccb20
commit a00a4ffb04
10 changed files with 82 additions and 0 deletions

View File

@ -1,6 +1,11 @@
CHANGELOG
=========
3.4.0
-----
* added `setDeprecated()` method to indicate a deprecated node
3.3.0
-----

View File

@ -234,6 +234,10 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
}
foreach ($this->children as $name => $child) {
if ($child->isDeprecated()) {
@trigger_error($child->getDeprecationMessage($name, $this->getPath()), E_USER_DEPRECATED);
}
if (!array_key_exists($name, $value)) {
if ($child->isRequired()) {
$msg = sprintf('The child node "%s" at path "%s" must be configured.', $name, $this->getPath());

View File

@ -29,6 +29,7 @@ abstract class BaseNode implements NodeInterface
protected $finalValidationClosures = array();
protected $allowOverwrite = true;
protected $required = false;
protected $deprecationMessage = null;
protected $equivalentValues = array();
protected $attributes = array();
@ -141,6 +142,19 @@ abstract class BaseNode implements NodeInterface
$this->required = (bool) $boolean;
}
/**
* Sets this node as deprecated.
*
* You can use %node% and %path% placeholders in your message to display,
* respectively, the node name and its complete path.
*
* @param string|null $message Deprecated message
*/
public function setDeprecated($message)
{
$this->deprecationMessage = $message;
}
/**
* Sets if this node can be overridden.
*
@ -181,6 +195,29 @@ abstract class BaseNode implements NodeInterface
return $this->required;
}
/**
* Checks if this node is deprecated.
*
* @return bool
*/
public function isDeprecated()
{
return null !== $this->deprecationMessage;
}
/**
* Returns the deprecated message.
*
* @param string $node the configuration node name
* @param string $path the path of the node
*
* @return string
*/
public function getDeprecationMessage($node, $path)
{
return strtr($this->deprecationMessage, array('%node%' => $node, '%path%' => $path));
}
/**
* Returns the name of this node.
*

View File

@ -27,6 +27,7 @@ abstract class NodeDefinition implements NodeParentInterface
protected $defaultValue;
protected $default = false;
protected $required = false;
protected $deprecationMessage = null;
protected $merge;
protected $allowEmptyValue = true;
protected $nullEquivalent;
@ -168,6 +169,23 @@ abstract class NodeDefinition implements NodeParentInterface
return $this;
}
/**
* Sets the node as deprecated.
*
* You can use %node% and %path% placeholders in your message to display,
* respectively, the node name and its complete path.
*
* @param string $message Deprecation message
*
* @return $this
*/
public function setDeprecated($message = 'The child node "%node%" at path "%path%" is deprecated.')
{
$this->deprecationMessage = $message;
return $this;
}
/**
* Sets the equivalent value used when the node contains null.
*

View File

@ -54,6 +54,7 @@ class VariableNodeDefinition extends NodeDefinition
$node->addEquivalentValue(true, $this->trueEquivalent);
$node->addEquivalentValue(false, $this->falseEquivalent);
$node->setRequired($this->required);
$node->setDeprecated($this->deprecationMessage);
if (null !== $this->validation) {
$node->setFinalValidationClosures($this->validation->rules);

View File

@ -153,6 +153,10 @@ class XmlReferenceDumper
$comments[] = 'Required';
}
if ($child->isDeprecated()) {
$comments[] = sprintf('Deprecated (%s)', $child->getDeprecationMessage($child->getName(), $child->getPath()));
}
if ($child instanceof EnumNode) {
$comments[] = 'One of '.implode('; ', array_map('json_encode', $child->getValues()));
}

View File

@ -123,6 +123,11 @@ class YamlReferenceDumper
$comments[] = 'Required';
}
// deprecated?
if ($node->isDeprecated()) {
$comments[] = sprintf('Deprecated (%s)', $node->getDeprecationMessage($node->getName(), $node->getPath()));
}
// example
if ($example && !is_array($example)) {
$comments[] = 'Example: '.$example;

View File

@ -38,6 +38,8 @@ class XmlReferenceDumperTest extends TestCase
return str_replace("\n", PHP_EOL, <<<'EOL'
<!-- Namespace: http://example.org/schema/dic/acme_root -->
<!-- scalar-required: Required -->
<!-- scalar-deprecated: Deprecated (The child node "scalar_deprecated" at path "acme_root.scalar_deprecated" is deprecated.) -->
<!-- scalar-deprecated-with-message: Deprecated (Deprecation custom message for "scalar_deprecated_with_message" at "acme_root.scalar_deprecated_with_message") -->
<!-- enum-with-default: One of "this"; "that" -->
<!-- enum: One of "this"; "that" -->
<config
@ -50,6 +52,8 @@ class XmlReferenceDumperTest extends TestCase
scalar-array-empty=""
scalar-array-defaults="elem1,elem2"
scalar-required=""
scalar-deprecated=""
scalar-deprecated-with-message=""
node-with-a-looong-name=""
enum-with-default="this"
enum=""

View File

@ -98,6 +98,8 @@ acme_root:
- elem1
- elem2
scalar_required: ~ # Required
scalar_deprecated: ~ # Deprecated (The child node "scalar_deprecated" at path "acme_root.scalar_deprecated" is deprecated.)
scalar_deprecated_with_message: ~ # Deprecated (Deprecation custom message for "scalar_deprecated_with_message" at "acme_root.scalar_deprecated_with_message")
node_with_a_looong_name: ~
enum_with_default: this # One of "this"; "that"
enum: ~ # One of "this"; "that"

View File

@ -35,6 +35,8 @@ class ExampleConfiguration implements ConfigurationInterface
->scalarNode('scalar_array_empty')->defaultValue(array())->end()
->scalarNode('scalar_array_defaults')->defaultValue(array('elem1', 'elem2'))->end()
->scalarNode('scalar_required')->isRequired()->end()
->scalarNode('scalar_deprecated')->setDeprecated()->end()
->scalarNode('scalar_deprecated_with_message')->setDeprecated('Deprecation custom message for "%node%" at "%path%"')->end()
->scalarNode('node_with_a_looong_name')->end()
->enumNode('enum_with_default')->values(array('this', 'that'))->defaultValue('this')->end()
->enumNode('enum')->values(array('this', 'that'))->end()