feature #22382 [config] Add abbitily to deprecate a node (Nyholm, fabpot, sanpii)
This PR was merged into the 4.0-dev branch. Discussion ---------- [config] Add abbitily to deprecate a node | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | no | New feature? | yes | BC breaks? | maybe | Deprecations? | no | Tests pass? | yes | Fixed tickets | n/a | License | MIT | Doc PR | https://github.com/symfony/symfony-docs/pull/7794 For BC breaks, I don’t know if modifying the Xml and Yaml dumper output is considering as a BC break (it’s just a comment). Commits -------31d2250f4c
[config] Add abbitily to deprecate a node3b6442f8b2
feature #23947 [Translation] Adding the ability do load <notes> in xliff2.0 (Nyholm)b0cdb53d67
[Translation] Adding the ability do load <notes> in xliff2.0
This commit is contained in:
commit
9a6d3e5557
@ -1,6 +1,11 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
3.4.0
|
||||
-----
|
||||
|
||||
* added `setDeprecated()` method to indicate a deprecated node
|
||||
|
||||
3.3.0
|
||||
-----
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -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()));
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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=""
|
||||
|
@ -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"
|
||||
|
@ -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()
|
||||
|
@ -13,6 +13,7 @@ CHANGELOG
|
||||
* Added `TranslationExtractorPass`
|
||||
* Added `TranslatorPass`
|
||||
* Added <notes> section to the Xliff 2.0 dumper.
|
||||
* Improved Xliff 2.0 loader to load <notes> section.
|
||||
* Added `TranslationWriterInterface`
|
||||
* Deprecated `TranslationWriter::writeTranslations` in favor of `TranslationWriter::write`
|
||||
|
||||
|
@ -127,7 +127,8 @@ class XliffFileLoader implements LoaderInterface
|
||||
|
||||
$xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:2.0');
|
||||
|
||||
foreach ($xml->xpath('//xliff:unit/xliff:segment') as $segment) {
|
||||
foreach ($xml->xpath('//xliff:unit') as $unit) {
|
||||
$segment = $unit->segment;
|
||||
$source = $segment->source;
|
||||
|
||||
// If the xlf file has another encoding specified, try to convert it because
|
||||
@ -144,6 +145,18 @@ class XliffFileLoader implements LoaderInterface
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($unit->notes)) {
|
||||
$metadata['notes'] = array();
|
||||
foreach ($unit->notes->note as $noteNode) {
|
||||
$note = array();
|
||||
foreach ($noteNode->attributes() as $key => $value) {
|
||||
$note[$key] = (string) $value;
|
||||
}
|
||||
$note['content'] = (string) $noteNode;
|
||||
$metadata['notes'][] = $note;
|
||||
}
|
||||
}
|
||||
|
||||
$catalogue->setMetadata((string) $source, $metadata, $domain);
|
||||
}
|
||||
}
|
||||
|
@ -93,12 +93,17 @@ class XliffFileDumperTest extends TestCase
|
||||
$catalogue = new MessageCatalogue('en_US');
|
||||
$catalogue->add(array(
|
||||
'foo' => 'bar',
|
||||
'baz' => 'biz',
|
||||
));
|
||||
$catalogue->setMetadata('foo', array('notes' => array(
|
||||
array('category' => 'state', 'content' => 'new'),
|
||||
array('category' => 'approved', 'content' => 'true'),
|
||||
array('category' => 'section', 'content' => 'user login', 'priority' => '1'),
|
||||
)));
|
||||
$catalogue->setMetadata('baz', array('notes' => array(
|
||||
array('id' => 'x', 'content' => 'x_content'),
|
||||
array('appliesTo' => 'target', 'category' => 'quality', 'content' => 'Fuzzy'),
|
||||
)));
|
||||
|
||||
$dumper = new XliffFileDumper();
|
||||
|
||||
|
@ -188,4 +188,44 @@ class XliffFileLoaderTest extends TestCase
|
||||
// target attributes
|
||||
$this->assertEquals(array('target-attributes' => array('order' => 1)), $catalogue->getMetadata('bar', 'domain1'));
|
||||
}
|
||||
|
||||
public function testLoadVersion2WithNoteMeta()
|
||||
{
|
||||
$loader = new XliffFileLoader();
|
||||
$resource = __DIR__.'/../fixtures/resources-notes-meta.xlf';
|
||||
$catalogue = $loader->load($resource, 'en', 'domain1');
|
||||
|
||||
$this->assertEquals('en', $catalogue->getLocale());
|
||||
$this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
|
||||
$this->assertSame(array(), libxml_get_errors());
|
||||
|
||||
// test for "foo" metadata
|
||||
$this->assertTrue($catalogue->defines('foo', 'domain1'));
|
||||
$metadata = $catalogue->getMetadata('foo', 'domain1');
|
||||
$this->assertNotEmpty($metadata);
|
||||
$this->assertCount(3, $metadata['notes']);
|
||||
|
||||
$this->assertEquals('state', $metadata['notes'][0]['category']);
|
||||
$this->assertEquals('new', $metadata['notes'][0]['content']);
|
||||
|
||||
$this->assertEquals('approved', $metadata['notes'][1]['category']);
|
||||
$this->assertEquals('true', $metadata['notes'][1]['content']);
|
||||
|
||||
$this->assertEquals('section', $metadata['notes'][2]['category']);
|
||||
$this->assertEquals('1', $metadata['notes'][2]['priority']);
|
||||
$this->assertEquals('user login', $metadata['notes'][2]['content']);
|
||||
|
||||
// test for "baz" metadata
|
||||
$this->assertTrue($catalogue->defines('baz', 'domain1'));
|
||||
$metadata = $catalogue->getMetadata('baz', 'domain1');
|
||||
$this->assertNotEmpty($metadata);
|
||||
$this->assertCount(2, $metadata['notes']);
|
||||
|
||||
$this->assertEquals('x', $metadata['notes'][0]['id']);
|
||||
$this->assertEquals('x_content', $metadata['notes'][0]['content']);
|
||||
|
||||
$this->assertEquals('target', $metadata['notes'][1]['appliesTo']);
|
||||
$this->assertEquals('quality', $metadata['notes'][1]['category']);
|
||||
$this->assertEquals('Fuzzy', $metadata['notes'][1]['content']);
|
||||
}
|
||||
}
|
||||
|
@ -12,5 +12,15 @@
|
||||
<target>bar</target>
|
||||
</segment>
|
||||
</unit>
|
||||
<unit id="uqWglk0">
|
||||
<notes>
|
||||
<note id="x">x_content</note>
|
||||
<note appliesTo="target" category="quality">Fuzzy</note>
|
||||
</notes>
|
||||
<segment>
|
||||
<source>baz</source>
|
||||
<target>biz</target>
|
||||
</segment>
|
||||
</unit>
|
||||
</file>
|
||||
</xliff>
|
||||
|
Reference in New Issue
Block a user