Completed
Push — master ( e9d1ee...cb5c09 )
by Théo
06:38
created

YamlFileLoader::load()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 2

Importance

Changes 2
Bugs 1 Features 1
Metric Value
dl 0
loc 15
ccs 10
cts 10
cp 1
rs 9.4285
c 2
b 1
f 1
cc 2
eloc 9
nc 2
nop 1
crap 2
1
<?php
2
3
/*
4
 * This file is part of the LaravelYaml package.
5
 *
6
 * (c) Théo FIDRY <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Fidry\LaravelYaml\FileLoader\Yaml;
13
14
use Fidry\LaravelYaml\DependencyInjection\Builder\ContainerBuilder;
15
use Fidry\LaravelYaml\Exception\FileLoader\Exception;
16
use Fidry\LaravelYaml\Exception\FileLoader\InvalidArgumentException;
17
use Fidry\LaravelYaml\FileLoader\FileLoaderInterface;
18
use Fidry\LaravelYaml\FileLoader\Parser\ParserInterface;
19
use Fidry\LaravelYaml\FileLoader\Parser\Yaml\DefinitionsParser;
20
use Fidry\LaravelYaml\FileLoader\Parser\Yaml\ImportsParser;
21
use Fidry\LaravelYaml\FileLoader\Parser\Yaml\ParametersParser;
22
use Symfony\Component\Config\FileLocatorInterface;
23
use Symfony\Component\Yaml\Exception\ParseException;
24
use Symfony\Component\Yaml\Parser as YamlParser;
25
26
/**
27
 * This loader is able to load YAML files. Parsed values are interpreted and added to the {@see ContainerBuilder} to be
28
 * loaded to the Application later on.
29
 *
30
 * @author Théo FIDRY <[email protected]>
31
 */
32
final class YamlFileLoader implements FileLoaderInterface
33
{
34
    /**
35
     * @var ContainerBuilder
36
     */
37
    private $container;
38
39
    /**
40
     * @var ParserInterface
41
     */
42
    private $definitionsParser;
43
44
    /**
45
     * @var FileLocatorInterface
46
     */
47
    private $fileLocator;
48
49
    /**
50
     * @var ParserInterface
51
     */
52
    private $importsParser;
53
54
    /**
55
     * @var ParserInterface
56
     */
57
    private $parametersParser;
58
59
    /**
60
     * @var YamlParser
61
     */
62
    private $yamlParser;
63
64
    /**
65
     * @var YamlValidator
66
     */
67
    private $yamlValidator;
68
69 15
    public function __construct(
70
        ContainerBuilder $container,
71
        FileLocatorInterface $fileLocator,
72
        ParserInterface $definitionsParser = null,
73
        ParserInterface $parametersParser = null,
74
        ParserInterface $importsParser = null,
75
        YamlParser $yamlParser = null,
76
        YamlValidator $yamlValidator = null
77
    ) {
78 15
        $this->container = $container;
79 15
        $this->fileLocator = $fileLocator;
80
81 15
        $this->definitionsParser = (null === $definitionsParser) ? new DefinitionsParser() : $definitionsParser;
82 15
        $this->parametersParser = (null === $parametersParser) ? new ParametersParser() : $parametersParser;
83 15
        $this->importsParser = (null === $importsParser) ? new ImportsParser() : $importsParser;
84 15
        $this->yamlParser = (null === $yamlParser) ? new YamlParser() : $yamlParser;
85 15
        $this->yamlValidator = (null === $yamlValidator) ? new YamlValidator() : $yamlValidator;
86 15
    }
87
88
    /**
89
     * {@inheritdoc}
90
     *
91
     * @param string $resource file name
92
     *
93
     * @example
94
     *  ::load('services.yml')
95
     *
96
     * @throws InvalidArgumentException
97
     * @throws Exception
98
     * @return $this
99
     */
100 12
    public function load($resource)
101
    {
102
        /* @var string|null $path */
103 12
        $path = $this->fileLocator->locate($resource, null, true);
104 12
        $content = $this->loadFile($path);
105
106 6
        $imports = $this->importsParser->parse($this->container, $content, $resource);
107 6
        foreach ($imports as $importedResource) {
108 3
            $this->load($importedResource);
109 2
        }
110 6
        $this->parametersParser->parse($this->container, $content, $resource);
111 6
        $this->definitionsParser->parse($this->container, $content, $resource);
112
113 6
        return $this;
114
    }
115
116
    /**
117
     * @param string $filePath
118
     *
119
     * @return array The file content
120
     * @throws InvalidArgumentException
121
     */
122 12
    private function loadFile($filePath)
123
    {
124 12
        if (false === stream_is_local($filePath)) {
125
            throw new InvalidArgumentException(sprintf('This is not a local file "%s".', $filePath));
126
        }
127
128 12
        if (false === file_exists($filePath)) {
129 3
            throw new InvalidArgumentException(sprintf('The service file "%s" is not valid.', $filePath));
130
        }
131
132
        try {
133 9
            $configuration = $this->yamlParser->parse(file_get_contents($filePath));
134 5
        } catch (ParseException $exception) {
135 3
            throw new InvalidArgumentException(
136 3
                sprintf('The file "%s" does not contain valid YAML.', $filePath), 0, $exception
137 1
            );
138
        }
139
140 6
        return $this->yamlValidator->validate($configuration, $filePath);
141
    }
142
}
143