GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 7dd4fa...6a3c70 )
by Miles
07:33
created

FileResource::processImport()   B

Complexity

Conditions 5
Paths 2

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 17
ccs 11
cts 11
cp 1
rs 8.8571
cc 5
eloc 10
nc 2
nop 2
crap 5
1
<?php
2
3
/**
4
 * This file is part of the m1\vars library
5
 *
6
 * Copyright (c) Miles Croxford <[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
 * @package     m1/vars
12
 * @version     0.1.0
13
 * @author      Miles Croxford <[email protected]>
14
 * @copyright   Copyright (c) Miles Croxford <[email protected]>
15
 * @license     http://github.com/m1/vars/blob/master/LICENSE
16
 * @link        http://github.com/m1/vars/blob/master/README.MD Documentation
17
 */
18
19
namespace M1\Vars\Resource;
20
21
use Symfony\Component\Filesystem\Filesystem;
22
23
/**
24
 * File Resource enables interaction with files as resources
25
 *
26
 * @since 0.1.0
27
 */
28
class FileResource extends AbstractResource
29
{
30
    /**
31
     * Basic file interaction logic
32
     */
33
    use FileTrait;
34
35
    /**
36
     * The env separator for environment replacements
37
     *
38
     * @var string
39
     */
40
    private static $env_separator = '_ENV::';
41
42
    /**
43
     * The filename of the loaded file
44
     *
45
     * @var string
46
     */
47
    private $filename;
48
49
    /**
50
     * The parent ResourceProvider
51
     *
52
     * @var \M1\Vars\Resource\ResourceProvider
53
     */
54
    private $provider;
55
56
    /**
57
     * The raw content from the passed file
58
     *
59
     * @var mixed
60
     */
61
    private $raw_content = array();
62
63
    /**
64
     * The file resource constructor to get and parse the content from files
65
     *
66
     * @param \M1\Vars\Resource\ResourceProvider $provider The parent ResourceProvider
67
     * @param string                             $file     The passed file
68
     */
69 56
    public function __construct(ResourceProvider $provider, $file)
70
    {
71 56
        $this->provider = $provider;
72 56
        $this->vars = $provider->vars;
73
74 56
        $this->makePaths($file);
75 56
        $this->validate();
76
77 56
        $content = $this->loadContent($this->file);
78 49
        $this->raw_content = $content;
79
80 49
        if ($content) {
81 46
            $this->content = $this->searchForResources($content);
82 45
        }
83 48
    }
84
85
    /**
86
     * Make the paths used for the filename variable
87
     *
88
     * @param string $file The passed file
89
     */
90 56
    private function makePaths($file)
91
    {
92 56
        $file = realpath($file);
93
94 56
        $base_path = $this->provider->vars->getBasePath();
95
96 56
        $filesystem = new Filesystem();
97 56
        $abs_path = $filesystem->makePathRelative(
98 56
            $file,
99
            $base_path
100 56
        );
101
102 56
        $this->file = $file;
103 56
        $this->filename = rtrim($abs_path, "/");
104 56
    }
105
106
    /**
107
     * Search for imports in the files and does the replacement variables
108
     *
109
     * @param mixed $content The file content received from the loader
110
     *
111
     * @return array Returns the parsed content
112
     */
113 46
    private function searchForResources($content = array())
114
    {
115 46
        $returned_content = array();
116
117 46
        foreach ($content as $ck => $cv) {
118 46
            if ($ck === 'imports' && !is_null($cv) && !empty($cv)) {
119 38
                $imported_resource = $this->useImports($cv);
120
121 37
                if ($imported_resource) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $imported_resource of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
122 35
                    $returned_content = array_replace_recursive($returned_content, $imported_resource);
123 35
                }
124
125 45
            } elseif (is_array($cv)) {
126 10
                $returned_content[$ck] = $this->searchForResources($cv);
127 10
            } else {
128 44
                $returned_content[$ck] = $this->parseText($cv);
129
            }
130 45
        }
131
132 45
        return $returned_content;
133
    }
134
135
    /**
136
     * Parses the text for option and environment replacements and replaces the text
137
     *
138
     * @param string $text The text to be parsed
139
     *
140
     * @return string|null The parsed string
141
     */
142 44
    private function parseText($text)
143
    {
144 44
        if (substr($text, 0, 6) === self::$env_separator) {
145 1
            $variable = trim(substr($text, strlen(self::$env_separator)));
146
147 1
            if ($variable) {
148 1
                $value = getenv($variable);
149
150 1
                if ($value) {
151 1
                    return $value;
152
                }
153 1
            }
154 1
        } else {
155 43
            return strtr($text, $this->vars->getVariables());
156
        }
157
158 1
        return null;
159
    }
160
161
    /**
162
     * Use the import arrays to import resources
163
     *
164
     * @param mixed $imports The resources wanting to be imported
165
     *
166
     * @return array The parsed imported resources
167
     */
168 38
    private function useImports($imports)
169
    {
170 38
        $imported_resources = array();
171
172 38
        if ((is_array($imports) && $this->isAssoc($imports)) || is_string($imports)) {
173 32
            $imports = array($imports);
174 32
        }
175
176 38
        foreach ($imports as $import) {
0 ignored issues
show
Bug introduced by
The expression $imports of type object|integer|double|null|array|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
177 38
            $imported_resources = $this->processImport($import, $imported_resources);
178 37
        }
179
180 37
        return $imported_resources;
181
    }
182
183
    /**
184
     * Processes the imports and gets individual imports and passes them off to import2Resources()
185
     *
186
     * @param mixed $imports The imports to be processed
0 ignored issues
show
Documentation introduced by
There is no parameter named $imports. Did you maybe mean $import?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
187
     * @param array $imported_resources The array of imported resourcesg
188
     *
189
     * @return array The parsed imported resources
190
     */
191 38
    private function processImport($import, array $imported_resources)
192
    {
193 38
        if (is_array($import) && array_key_exists('resource', $import) && is_array($import['resource'])) {
194 1
            foreach ($import['resource'] as $resource) {
195
                $temp = array(
196 1
                    'resource' => $resource,
197 1
                    'relative' => $this->isRelative($import)
198 1
                );
199
200 1
                $imported_resources = $this->import2Resource($temp, $imported_resources);
201 1
            }
202 1
        } else {
203 38
            $imported_resources = $this->import2Resource($import, $imported_resources);
204
        }
205
206 37
        return $imported_resources;
207
    }
208
209
    /**
210
     * Creates the resource from the import then imports it
211
     *
212
     * @param array|string $import The string|array to be converted to a resource
213
     * @param array $imported_resources The array of imported resources
214
     *
215
     * @return array The imported resources
216
     */
217 38
    private function import2Resource($import, array $imported_resources)
218
    {
219 38
        $resource = $this->createResource($import);
220
221 37
        if ($resource) {
222 37
            $imported_resources = $this->importResource($resource, $imported_resources);
223 37
        }
224
225 37
        return $imported_resources;
226
    }
227
228
    /**
229
     * Creates resource from the import
230
     *
231
     * @param array|string $import The import to create a resource from
232
     *
233
     * @return array|\M1\Vars\Resource\ResourceProvider The resource of the import
234
     */
235 38
    private function createResource($import)
236
    {
237 38
        if (is_array($import) && array_key_exists('resource', $import)) {
238 8
            $import_resource = $import;
239 8
            $import_resource['relative'] = $this->isRelative($import_resource);
240 38
        } elseif (is_string($import)) {
241 31
            $import_resource = array('resource' => $import, 'relative' => true);
242 31
        } else {
243
            return false;
244
        }
245
246 38
        $import_resource = new ResourceProvider(
247 38
            $this->provider->vars,
248 38
            sprintf('%s/%s', dirname($this->file), $import_resource['resource']),
249 38
            $import_resource['relative']
0 ignored issues
show
Bug introduced by
It seems like $import_resource['relative'] can also be of type string; however, M1\Vars\Resource\ResourceProvider::__construct() does only seem to accept boolean, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
250 38
        );
251
252 37
        return $import_resource;
253
    }
254
255
    /**
256
     * Import resource into the imported resources and merge contents
257
     *
258
     * @param ResourceProvider $provider The new imported resource
259
     * @param array            $imported_resources The imported resources
260
     *
261
     * @return array The modified imported resources
262
     */
263 37
    private function importResource(ResourceProvider $provider, $imported_resources)
264
    {
265 37
        $content = $provider->getContent();
266 37
        $parent_content = $provider->getParentContent();
267
268 37
        if (!empty($content)) {
269 35
            $imported_resources = array_replace_recursive($imported_resources, $content);
270 35
        }
271
272 37
        if (!empty($parent_content)) {
273 7
            $this->provider->addParentContent($parent_content);
274 7
        }
275
276 37
        return $imported_resources;
277
    }
278
279
    /**
280
     * Returns whether the passed array is associative
281
     *
282
     * @param array $array The passed array
283
     *
284
     * @return bool Is the passed array associative
285
     */
286 9
    private function isAssoc(array $array)
287
    {
288 9
        return array_keys($array) !== range(0, count($array) - 1);
289
    }
290
291
    /**
292
     * Checks if the passed import is wanting to be merged into the parent content or relative content
293
     *
294
     * @param mixed $import The passed import
295
     *
296
     * @return bool Returns whether wanting to be a relative import
297
     */
298 8
    public function isRelative($import)
299
    {
300 8
        if (array_key_exists('relative', $import)) {
301 7
            if (is_bool($import['relative'])) {
302 7
                return $import['relative'];
303
304 1
            } elseif (is_string($import['relative'])) {
305 1
                switch (strtolower($import['relative'])) {
306 1
                    case 'false':
307 1
                    case 'no':
308 1
                        return false;
309 1
                    case 'true':
310 1
                    case 'yes':
311 1
                    default:
312 1
                        return true;
313 1
                }
314
            }
315
        }
316
317 5
        return true;
318
    }
319
320
    /**
321
     * Returns the filename of the resource
322
     *
323
     * @return mixed The filename
324
     */
325 3
    public function getFilename()
326
    {
327 3
        return $this->filename;
328
    }
329
330
    /**
331
     * Returns the raw content of the resource
332
     *
333
     * @return array|mixed The raw content
334
     */
335 1
    public function getRawContent()
336
    {
337 1
        return $this->raw_content;
338
    }
339
}
340