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

Skip to content

Commit 6e03a42

Browse files
committed
feature symfony#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
  • Loader
  • Yaml
  • 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