JsonLoader   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 2
dl 0
loc 66
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A load() 0 22 4
A supports() 0 4 2
A parseJson() 0 4 1
A getLastErrorMessage() 0 17 2
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\Loaders;
13
14
use Yosymfony\ConfigLoader\ConfigFileLoader;
15
use Yosymfony\ConfigLoader\Repository;
16
use Yosymfony\ConfigLoader\RepositoryInterface;
17
18
/**
19
 * JSON file loader
20
 *
21
 * @author Victor Puertas <[email protected]>
22
 */
23
class JsonLoader extends ConfigFileLoader
24
{
25
    public const TYPE = "json";
26
27
    /**
28
     * {@inheritdoc}
29
     *
30
     * @throws RuntimeException If JSON parse error
31
     */
32
    public function load(string $resource, string $type = null) : RepositoryInterface
33
    {
34
        $resourceContent = $resource;
35
36
        if (empty($type)) {
37
            $file = $this->getLocation($resource);
38
            $resourceContent = $this->readFile($file);
39
        }
40
41
        $parsedResource = $this->parseJson($resourceContent);
42
        $errorMsg = $this->getLastErrorMessage(json_last_error());
43
44
        if ($errorMsg) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $errorMsg of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
45
            $msg = $type ? sprintf('JSON parse error: %s.', $errorMsg) : sprintf('JSON parse error: %s at %s', $errorMsg, $resource);
46
47
            throw new \RuntimeException($msg);
48
        }
49
50
        $repository = new Repository($parsedResource ?? []);
51
52
        return $this->parseImports($repository, $resource);
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58
    public function supports(string $resource, string $type = null) : bool
59
    {
60
        return $type === self::TYPE || $this->hasResourceExtension($resource, 'json');
61
    }
62
63
    /**
64
     * @return mixed
65
     */
66
    private function parseJson(string $resource)
67
    {
68
        return json_decode($resource, true);
69
    }
70
71
    private function getLastErrorMessage(int $errorCode) : ?string
72
    {
73
        $errors = [
74
            JSON_ERROR_NONE => null,
75
            JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
76
            JSON_ERROR_STATE_MISMATCH => 'Underflow or the modes mismatch',
77
            JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
78
            JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON',
79
            JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded',
80
        ];
81
82
        if (array_key_exists($errorCode, $errors)) {
83
            return $errors[$errorCode];
84
        }
85
86
        return sprintf('Unknown error code: "%s"', $errorCode);
87
    }
88
}
89