ConfigFileLoader   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 184
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 4

Importance

Changes 0
Metric Value
wmc 23
lcom 2
cbo 4
dl 0
loc 184
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getLocation() 0 12 3
A setCurrentDir() 0 4 1
A getLocator() 0 4 1
A setLoaderResolver() 0 4 1
A getLoaderResolver() 0 4 1
A isDistExtension() 0 4 1
B parseImports() 0 30 7
A hasResourceExtension() 0 4 1
A readFile() 0 12 3
A import() 0 14 3
1
<?php
2
3
/*
4
 * This file is part of the Yosymfony Config-loader.
5
 *
6
 * (c) YoSymfony <http://github.com/yosymfony>
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 Yosymfony\ConfigLoader;
13
14
use Yosymfony\ConfigLoader\Exception;
15
16
/**
17
 * Abstract class used by built-in loaders.
18
 *
19
 * @author Victor Puertas <[email protected]>
20
 */
21
abstract class ConfigFileLoader implements LoaderInterface
22
{
23
    private const DIST_EXTENSION = 'dist';
24
    private const IMPORT_KEY = 'imports';
25
26
    /** @var LoaderResolverInterface */
27
    private $loaderResolver;
28
    /** @var FileLocatorInterface */
29
    private $locator;
30
    /** @var string */
31
    private $currentDir;
32
33
    public function __construct(FileLocatorInterface $locator)
34
    {
35
        $this->locator = $locator;
36
    }
37
38
    /**
39
     * Resolve the location of a file following the hierarchy:
40
     *    1. filename.ext
41
     *    2. filename.ext.dist (if filename.ext does not exist).
42
     *
43
     *    or
44
     *
45
     *    filename.ext.dist if the .dist is included in the resource.
46
     *
47
     * @param string $resource Filename path
48
     *
49
     * @return string The filename location
50
     *
51
     * @throws \InvalidArgumentException When the file is not found
52
     */
53
    public function getLocation(string $resource) : string
54
    {
55
        if (!$this->isDistExtension($resource)) {
56
            try {
57
                return $this->getLocator()->locateFirst($resource, $this->currentDir);
58
            } catch (\InvalidArgumentException $ex) {
59
                $resource = $resource.'.'.self::DIST_EXTENSION;
60
            }
61
        }
62
63
        return  $this->getLocator()->locateFirst($resource, null);
64
    }
65
66
    /**
67
     * Sets the current directory.
68
     *
69
     * @param string $dir
70
     */
71
    public function setCurrentDir($dir)
72
    {
73
        $this->currentDir = $dir;
74
    }
75
76
    /**
77
     * Returns the file locator used by this loader.
78
     *
79
     * @return FileLocatorInterface
80
     */
81
    public function getLocator() : FileLocatorInterface
82
    {
83
        return $this->locator;
84
    }
85
86
    public function setLoaderResolver(LoaderResolverInterface $loaderResolver) : void
87
    {
88
        $this->loaderResolver = $loaderResolver;
89
    }
90
91
    /**
92
     * Returns the Loader Resolver implementation
93
     *
94
     * @return LoaderResolverInterface
95
     */
96
    protected function getLoaderResolver() : LoaderResolverInterface
97
    {
98
        return $this->loaderResolver;
99
    }
100
101
    /**
102
     * Has the file resource a ".dist" extension?
103
     *
104
     * @param string $resource The filename
105
     *
106
     * @return bool
107
     */
108
    protected function isDistExtension(string $resource) : bool
109
    {
110
        return pathinfo($resource, PATHINFO_EXTENSION) === self::DIST_EXTENSION;
111
    }
112
113
    /**
114
     * Parses the repositories in "imports" key
115
     *
116
     * @param Repository $repository
117
     * @param string     $file
118
     *
119
     * @return RepositoryInterface
120
     *
121
     * @throws InvalidArgumentException If error with "imports" key
122
     */
123
    protected function parseImports(RepositoryInterface $repository, string $file) : RepositoryInterface
124
    {
125
        if (!isset($repository[self::IMPORT_KEY])) {
126
            return $repository;
127
        }
128
129
        if (!is_array($repository[self::IMPORT_KEY])) {
130
            $keyName = self::IMPORT_KEY;
131
            $message = "The \"{$keyName}\" key should contain an array in {$file}. Check your YAML syntax.";
132
            throw new \InvalidArgumentException($message);
133
        }
134
135
        foreach ($repository[self::IMPORT_KEY] as $import) {
136
            if (!is_array($import)) {
137
                $import = ['resource' => $import];
138
            }
139
            
140
            $ignoreErrors = isset($import['ignore_errors']) ? (bool) $import['ignore_errors'] : false;
141
142
            $importedResource = $this->import($import['resource'], null, $ignoreErrors, $file);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $importedResource is correct as $this->import($import['r..., $ignoreErrors, $file) (which targets Yosymfony\ConfigLoader\ConfigFileLoader::import()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
143
144
            if ($importedResource) {
145
                $repository = $repository->union($importedResource);
146
            }
147
        }
148
149
        $repository->del(self::IMPORT_KEY);
150
151
        return $repository;
152
    }
153
154
    /**
155
     * Checks if the file has the extension passed as argument. This method
156
     * is aware about "dist" files
157
     *
158
     * @param string $file
159
     * @param string $extension Extension to check without dot. e.g: "json"
160
     *
161
     * @return bool
162
     */
163
    protected function hasResourceExtension(string $file, string $extension) : bool
164
    {
165
        return preg_match("#\.{$extension}(\.dist)?$#", $file) === 1;
166
    }
167
168
    /**
169
     * Reads a file
170
     *
171
     * @param string $file The name of the file
172
     *
173
     * @return string The file's content
174
     *
175
     * @throws BadFileException If the file is not a file or it is not readable
176
     */
177
    protected function readFile(string $file) : string
178
    {
179
        if (is_file($file) === false) {
180
            throw new BadFileException("The file \"{$file}\" is not a file.", $file);
181
        }
182
183
        if (is_readable($file) === false) {
184
            throw new BadFileException("Unable to open \"{$file}\" as the file is not readable.", $file);
185
        }
186
187
        return file_get_contents($file);
188
    }
189
190
    private function import(string $resource, string $type = null, bool $ignoreErrors = false, string $sourceResource = null) : ?RepositoryInterface
0 ignored issues
show
Unused Code introduced by
The parameter $sourceResource is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
191
    {
192
        $loader = $this->getLoaderResolver()->resolveLoader($resource, $type);
193
194
        if ($loader === null) {
195
            if (!$ignoreErrors) {
196
                throw new LoaderLoadException($resource, $type);
197
            }
198
199
            return null;
200
        }
201
202
        return $loader->load($resource, $type);
203
    }
204
}
205