1
votes

I have noticed that in the config.yml file of symfony2, the import feature is used as below

imports:
- { resource: security.yml }
- { resource: services.yml }

I am using some YAML file in my own bundle to init some read only entities. However, they are all jam-packed in this one single YAML file. I am using Symfony\Component\Yaml\Parser; component to read this file.

However, if I try to copy this nice feature of import, the parser only reads it normally and it doesn't interpret the import nor the resource keyword.

imports:
- { resource: test.yml }

That is the var_dump is simply the node tree without interpretation. Test is not loaded.

How can I use this same feature as in the config.yml file ?

2

2 Answers

1
votes

Well as suggested by Anthon, I created my own implementation using some symfony components, here is the class for people that are interested ( it's a basic implementation, do whatever you want with it)

use Symfony\Component\Yaml\Parser;
use Symfony\Component\Filesystem\Filesystem;

class MyYmlParser {

protected $parser;
protected $finder;
protected $currentDir;
protected $ymlPath;
protected $data;

public function __construct($rootDir) {
    $this->rootDir = $rootDir;
    $this->parser = new Parser();
    $this->fs = new Filesystem;
}

public function setYmlPath($ymlPath) {
    $this->ymlPath = $ymlPath;
    $this->currentDir = dirname($this->ymlPath) . "/";
    return $this;
}

public function getYmlPath() {
    return $this->ymlPath;
}

private function parseFile($path) {
    if ($this->fs->exists($path)):
        return $this->parser->parse(file_get_contents($path));
    else:
        throw new \Exception("$path Do not exsist");
    endif;
}

private function buildPathFromImport($fileName) {
    return $this->currentDir . $fileName;
}

public function parse($ymlPath) {
    $this->setYmlPath($ymlPath);
    $this->data = $this->parseFile($this->ymlPath);
    if (isset($this->data["imports"])):
        foreach ($this->data["imports"] as $array):
            $importData = $this->parseFile($this->buildPathFromImport($array["resource"]));
            $this->data = array_merge($this->data, $importData);
        endforeach;
        unset($this->data['imports']);
    endif;
    #dump($this->data); exit();
    return $this->data;
}
}

Usage is quite simple:

//Follow symfony syntax for imports that is:
 imports:
  - { resource: test.yml }
  - { resource: nested/dir/test2.yml }

$myYmlParser = new MyYmlParser();
$parsedData = $myYmlParser->parse($path); //the path to your yml file
//thats it, you got an array with the data form other files and the original file.

 //dont forget to add it to your services for the rootDir
 AmceBundle.ymlParser:
    class: OP\AcmeBundle\Services\MyYmlParser
    arguments: ["%kernel.root_dir%"]
0
votes

The YAML parser reads it normally in all cases. Only for the config.yml the program processing the represented instances "expands' the values for the mapping key import by taking from the list that is the associated value and replacing the nodes with the value associated with theresource.

This is not a feature of YAML, but an interpretation of the data handed to the program by the parser. If your program doesn't apply this feature recursively, you should patch the program to do so.