Passed
Push — master ( e3946d...128872 )
by Alexander
01:23
created

Json::shouldRethrowErrors()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 7
ccs 3
cts 4
cp 0.75
crap 2.0625
rs 10
1
<?php
2
3
namespace Yiisoft\Json;
4
5
/**
6
 * Json is a helper class providing JSON data encoding and decoding.
7
 * It enhances the PHP built-in functions `json_encode()` and `json_decode()`
8
 * by throwing exceptions when decoding fails.
9
 */
10
final class Json
11
{
12
    /**
13
     * Encodes the given value into a JSON string.
14
     *
15
     * Note that data encoded as JSON must be UTF-8 encoded according to the JSON specification.
16
     * You must ensure strings passed to this method have proper encoding before passing them.
17
     *
18
     * @param mixed $value the data to be encoded.
19
     * @param int $options the encoding options. For more details please refer to
20
     * <http://www.php.net/manual/en/function.json-encode.php>. Default is `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR`.
21
     * @param int $depth the maximum depth.
22
     * @return string the encoding result.
23
     * @throws \JsonException if there is any encoding error.
24
     */
25 18
    public static function encode(
26
        $value,
27
        int $options = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR,
28
        int $depth = 512
29
    ): string {
30 18
        $value = self::processData($value);
31 18
        return json_encode($value, JSON_THROW_ON_ERROR | $options, $depth);
32
    }
33
34
    /**
35
     * Encodes the given value into a JSON string HTML-escaping entities so it is safe to be embedded in HTML code.
36
     *
37
     * Note that data encoded as JSON must be UTF-8 encoded according to the JSON specification.
38
     * You must ensure strings passed to this method have proper encoding before passing them.
39
     *
40
     * @param mixed $value the data to be encoded
41
     * @return string the encoding result
42
     * @throws \JsonException if there is any encoding error
43
     */
44 6
    public static function htmlEncode($value): string
45
    {
46 6
        return self::encode(
47 6
            $value,
48 6
            JSON_UNESCAPED_UNICODE | JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_THROW_ON_ERROR
49
        );
50
    }
51
52
    /**
53
     * Decodes the given JSON string into a PHP data structure.
54
     * @param string $json the JSON string to be decoded
55
     * @param bool $asArray whether to return objects in terms of associative arrays.
56
     * @param int $depth the recursion depth.
57
     * @param int $options the decode options.
58
     * @return mixed the PHP data
59
     * @throws \JsonException if there is any decoding error
60
     */
61 5
    public static function decode(
62
        string $json,
63
        bool $asArray = true,
64
        int $depth = 512,
65
        int $options = JSON_THROW_ON_ERROR
66
    ) {
67 5
        if ($json === '') {
68 1
            return null;
69
        }
70 4
        return json_decode($json, $asArray, $depth, JSON_THROW_ON_ERROR | $options);
71
    }
72
73
    /**
74
     * Pre-processes the data before sending it to `json_encode()`.
75
     * @param mixed $data the data to be processed
76
     * @return mixed the processed data
77
     */
78 18
    private static function processData($data)
79
    {
80 18
        if (is_object($data)) {
81 12
            if ($data instanceof \JsonSerializable) {
82 5
                return self::processData($data->jsonSerialize());
83
            }
84
85 9
            if ($data instanceof \DateTimeInterface) {
86 1
                return static::processData((array)$data);
87
            }
88
89 8
            if ($data instanceof \SimpleXMLElement) {
90 1
                $data = (array)$data;
91
            } else {
92 7
                $result = [];
93 7
                foreach ($data as $name => $value) {
94 3
                    $result[$name] = $value;
95
                }
96 7
                $data = $result;
97
            }
98 8
            if ($data === []) {
99 4
                return new \stdClass();
100
            }
101
        }
102 15
        if (is_array($data)) {
103 12
            foreach ($data as $key => $value) {
104 10
                if (is_array($value) || is_object($value)) {
105 2
                    $data[$key] = self::processData($value);
106
                }
107
            }
108
        }
109 15
        return $data;
110
    }
111
}
112