8000 feature #18626 [Yaml] Added support for parsing PHP constants (HeahDude) · symfony/symfony@6e03a42 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6e03a42

Browse files
committed
feature #18626 [Yaml] Added support for parsing PHP constants (HeahDude)
This PR was merged into the 3.2-dev branch. Discussion ---------- [Yaml] Added support for parsing PHP constants | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | ~ | License | MIT | Doc PR | TODO Commits ------- 17ec26e [DI] added support for PHP constants in yaml configuration files 02d1dea [Yaml] added support for parsing PHP constants
2 parents 4223997 + 17ec26e commit 6e03a42

File tree

9 files changed

+73
-4
lines changed

9 files changed

+73
-4
lines changed

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
-----
66

77
* allowed to prioritize compiler passes by introducing a third argument to `PassConfig::addPass()`, to `Compiler::addPass` and to `ContainerBuilder::addCompilerPass()`
8+
* added support for PHP constants in YAML configuration files
89

910
3.0.0
1011
-----

src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Symfony\Component\Config\Resource\FileResource;
2222
use Symfony\Component\Yaml\Exception\ParseException;
2323
use Symfony\Component\Yaml\Parser as YamlParser;
24+
use Symfony\Component\Yaml\Yaml;
2425
use Symfony\Component\ExpressionLanguage\Expression;
2526

2627
/**
@@ -366,7 +367,7 @@ protected function loadFile($file)
366367
}
367368

368369
try {
369-
$configuration = $this->yamlParser->parse(file_get_contents($file));
370+
$configuration = $this->yamlParser->parse(file_get_contents($file), Yaml::PARSE_CONSTANT);
370371
} catch (ParseException $e) {
371372
throw new InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $file), 0, $e);
372373
}

src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services2.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ parameters:
55
- false
66
- 0
77
- 1000.3
8+
- !php/const:PHP_INT_MAX
89
bar: foo
910
escape: '@@escapeme'
1011
foo_bar: '@foo_bar'

src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public function testLoadParameters()
9797
$container = new ContainerBuilder();
9898
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
9999
$loader->load('services2.yml');
100-
$this->assertEquals(array('foo' => 'bar', 'mixedcase' => array('MixedCaseKey' => 'value'), 'values' => array(true, false, 0, 1000.3), 'bar' => 'foo', 'escape' => '@escapeme', 'foo_bar' => new Reference('foo_bar')), $container->getParameterBag()->all(), '->load() converts YAML keys to lowercase');
100+
$this->assertEquals(array('foo' => 'bar', 'mixedcase' => array('MixedCaseKey' => 'value'), 'values' => array(true, false, 0, 1000.3, PHP_INT_MAX), 'bar' => 'foo', 'escape' => '@escapeme', 'foo_bar' => new Reference('foo_bar')), $container->getParameterBag()->all(), '->load() converts YAML keys to lowercase');
101101
}
102102

103103
public function testLoadImports()
@@ -113,7 +113,7 @@ public function testLoadImports()
113113
$loader->load('services4.yml');
114114

115115
$actual = $container->getParameterBag()->all();
116-
$expected = array('foo' => 'bar', 'values' => array(true, false), 'bar' => '%foo%', 'escape' => '@escapeme', 'foo_bar' => new Reference('foo_bar'), 'mixedcase' => array('MixedCaseKey' => 'value'), 'imported_from_ini' => true, 'imported_from_xml' => true);
116+
$expected = array('foo' => 'bar', 'values' => array(true, false, PHP_INT_MAX), 'bar' => '%foo%', 'escape' => '@escapeme', 'foo_bar' => new Reference('foo_bar'), 'mixedcase' => array('MixedCaseKey' => 'value'), 'imported_from_ini' => true, 'imported_from_xml' => true);
117117
$this->assertEquals(array_keys($expected), array_keys($actual), '->load() imports and merges imported files');
118118

119119
// Bad import throws no exception due to ignore_errors value.

src/Symfony/Component/DependencyInjection/composer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"php": ">=5.5.9"
2020
},
2121
"require-dev": {
22-
"symfony/yaml": "~2.8|~3.0",
22+
"symfony/yaml": "~3.2",
2323
"symfony/config": "~2.8|~3.0",
2424
"symfony/expression-language": "~2.8|~3.0"
2525
},
@@ -29,6 +29,9 @@
2929
"symfony/expression-language": "For using expressions in service container configuration",
3030
"symfony/proxy-manager-bridge": "Generate service proxies to lazy load them"
3131
},
32+
"conflict": {
33+
"symfony/yaml": "<3.2"
34+
},
3235
"autoload": {
3336
"psr-4": { "Symfony\\Component\\DependencyInjection\\": "" },
3437
"exclude-from-classmap": [

src/Symfony/Component/Yaml/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
CHANGELOG
22
=========
33

4+
3.2.0
5+
-----
6+
7+
* Added support for parsing PHP constants:
8+
9+
```php
10+
Yaml::parse('!php/const:PHP_INT_MAX', Yaml::PARSE_CONSTANT);
11+
```
12+
413
3.1.0
514
-----
615

src/Symfony/Component/Yaml/Inline.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Inline
2828
private static $exceptionOnInvalidType = false;
2929
private static $objectSupport = false;
3030
private static $objectForMap = false;
31+
private static $constantSupport = false;
3132

3233
/**
3334
* Converts a YAML string to a PHP array.
@@ -77,6 +78,7 @@ public static function parse($value, $flags = 0, $references = array())
7778
self::$exceptionOnInvalidType = (bool) (Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE & $flags);
7879
self::$objectSupport = (bool) (Yaml::PARSE_OBJECT & $flags);
7980
self::$objectForMap = (bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags);
81+
self::$constantSupport = (bool) (Yaml::PARSE_CONSTANT & $flags);
8082

8183
$value = trim($value);
8284

@@ -580,6 +582,19 @@ private static function evaluateScalar($scalar, $flags, $references = array())
580582
throw new ParseException('Object support when parsing a YAML file has been disabled.');
581583
}
582584

585+
return;
586+
case 0 === strpos($scalar, '!php/const:'):
587+
if (self::$constantSupport) {
588+
if (defined($const = substr($scalar, 11))) {
589+
return constant($const);
590+
}
591+
592+
throw new ParseException(sprintf('The constant "%s" is not defined.', $const));
593+
}
594+
if (self::$exceptionOnInvalidType) {
595+
throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Have you forgotten to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar));
596+
}
597+
583598
return;
584599
case 0 === strpos($scalar, '!!float '):
585600
return (float) substr($scalar, 8);

src/Symfony/Component/Yaml/Tests/InlineTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,44 @@ public function testParseWithMapObjects($yaml, $value)
3535
$this->assertSame(serialize($value), serialize($actual));
3636
}
3737

38+
/**
39+
* @dataProvider getTestsForParsePhpConstants
40+
*/
41+
public function testParsePhpConstants($yaml, $value)
42+
{
43+
$actual = Inline::parse($yaml, Yaml::PARSE_CONSTANT);
44+
45+
$this->assertSame($value, $actual);
46+
}
47+
48+
public function getTestsForParsePhpConstants()
49+
{
50+
return array(
51+
array('!php/const:Symfony\Component\Yaml\Yaml::PARSE_CONSTANT', Yaml::PARSE_CONSTANT),
52+
array('!php/const:PHP_INT_MAX', PHP_INT_MAX),
53+
array('[!php/const:PHP_INT_MAX]', array(PHP_INT_MAX)),
54+
array('{ foo: !php/const:PHP_INT_MAX }', array('foo' => PHP_INT_MAX)),
55+
);
56+
}
57+
58+
/**
59+
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
60+
* @expectedExceptionMessage The constant "WRONG_CONSTANT" is not defined
61+
*/
62+
public function testParsePhpConstantThrowsExceptionWhenUndefined()
63+
{
64+
Inline::parse('!php/const:WRONG_CONSTANT', Yaml::PARSE_CONSTANT);
65+
}
66+
67+
/**
68+
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
69+
* @expectedExceptionMessageRegExp #The string "!php/const:PHP_INT_MAX" could not be parsed as a constant.*#
70+
*/
71+
public function testParsePhpConstantThrowsExceptionOnInvalidType()
72+
{
73+
Inline::parse('!php/const:PHP_INT_MAX', Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE);
74+
}
75+
3876
/**
3977
* @group legacy
4078
* @dataProvider getTestsForParseWithMapObjects

src/Symfony/Component/Yaml/Yaml.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Yaml
2828
const PARSE_DATETIME = 32;
2929
const DUMP_OBJECT_AS_MAP = 64;
3030
const DUMP_MULTI_LINE_LITERAL_BLOCK = 128;
31+
const PARSE_CONSTANT = 256;
3132

3233
/**
3334
* Parses YAML into a PHP value.

0 commit comments

Comments
 (0)
0