Test Failed
Push — master ( ca159c...8f4401 )
by Sebastian
03:00
created

JSONFile::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * File containing the class {@see \AppUtils\FileHelper\JSONFile}.
4
 *
5
 * @package AppUtils
6
 * @subpackage FileHelper
7
 * @see \AppUtils\FileHelper\JSONFile
8
 */
9
10
declare(strict_types=1);
11
12
namespace AppUtils\FileHelper;
13
14
use AppUtils\FileHelper;
15
use AppUtils\FileHelper_Exception;
16
use JsonException;
17
use SplFileInfo;
18
use function AppUtils\sb;
19
20
/**
21
 * Specialized file handler for JSON encoded files.
22
 *
23
 * @package AppUtils
24
 * @subpackage FileHelper
25
 * @author Sebastian Mordziol <[email protected]>
26
 */
27
class JSONFile extends FileInfo
28
{
29
    /**
30
     * @var string
31
     */
32
    private string $targetEncoding = '';
33
34
    /**
35
     * @var string|string[]|NULL
36
     */
37
    private $sourceEncodings = '';
38
39
    /**
40
     * @param string|PathInfoInterface|SplFileInfo $path
41
     * @return JSONFile
42
     * @throws FileHelper_Exception
43
     */
44
    public static function factory($path) : JSONFile
45
    {
46
        if($path instanceof self) {
47
            return $path;
48
        }
49
50
        $instance = self::createInstance($path);
51
52
        if($instance instanceof self) {
53
            return $instance;
54
        }
55
56
        throw new FileHelper_Exception(
57
            'Invalid class.'
58
        );
59
    }
60
61
    /**
62
     * @param string $targetEncoding
63
     * @return $this
64
     */
65
    public function setTargetEncoding(string $targetEncoding) : self
66
    {
67
        $this->targetEncoding = $targetEncoding;
68
        return $this;
69
    }
70
71
    /**
72
     * @param string|string[]|NULL $sourceEncodings
73
     * @return $this
74
     */
75
    public function setSourceEncodings($sourceEncodings) : self
76
    {
77
        $this->sourceEncodings = $sourceEncodings;
78
        return $this;
79
    }
80
81
    /**
82
     * Opens a serialized file and returns the unserialized data.
83
     * Only supports serialized arrays - classes are not allowed.
84
     *
85
     * @return array<int|string,mixed>
86
     * @throws FileHelper_Exception
87
     * @throws JsonException
88
     * @see FileHelper::parseSerializedFile()
89
     *
90
     * @see FileHelper::ERROR_FILE_DOES_NOT_EXIST
91
     * @see FileHelper::ERROR_SERIALIZED_FILE_CANNOT_BE_READ
92
     * @see FileHelper::ERROR_SERIALIZED_FILE_UNSERIALZE_FAILED
93
     */
94
    public function parse() : array
95
    {
96
        try
97
        {
98
            return json_decode(
99
                $this->getContents(),
100
                true,
101
                512,
102
                JSON_THROW_ON_ERROR
103
            );
104
        }
105
        catch (JsonException $e)
106
        {
107
            throw new FileHelper_Exception(
108
                'Cannot decode json data',
109
                (string)sb()
110
                    ->sf(
111
                        'Loaded the contents of file [%s] successfully, but decoding it as JSON failed.',
112
                        $this->getPath()
113
                    )
114
                    ->eol()
115
                    ->sf('Source encodings: [%s]', json_encode($this->sourceEncodings, JSON_THROW_ON_ERROR))
116
                    ->eol()
117
                    ->sf('Target encoding: [%s]', $this->targetEncoding),
118
                FileHelper::ERROR_CANNOT_DECODE_JSON_FILE,
119
                $e
120
            );
121
        }
122
    }
123
124
    public function getContents() : string
125
    {
126
        return $this->convertEncoding(parent::getContents());
127
    }
128
129
    private function convertEncoding(string $contents) : string
130
    {
131
        if(!empty($this->targetEncoding))
132
        {
133
            return (string)mb_convert_encoding(
134
                $contents,
135
                $this->targetEncoding,
136
                $this->sourceEncodings
137
            );
138
        }
139
140
        return $contents;
141
    }
142
143
    /**
144
     * @param mixed $data
145
     * @param bool $pretty
146
     * @return $this
147
     * @throws FileHelper_Exception
148
     */
149
    public function putData($data, bool $pretty) : self
150
    {
151
        $options = null;
152
153
        if($pretty)
154
        {
155
            $options = JSON_PRETTY_PRINT;
156
        }
157
158
        try
159
        {
160
            $json = json_encode($data, JSON_THROW_ON_ERROR | $options);
161
162
            $this->putContents($json);
163
164
            return $this;
165
        }
166
        catch (JsonException $e)
167
        {
168
            throw new FileHelper_Exception(
169
                'An error occurred while encoding a data set to JSON.',
170
                sprintf('Tried saving to file: [%s].', $this->getPath()),
171
                FileHelper::ERROR_JSON_ENCODE_ERROR,
172
                $e
173
            );
174
        }
175
    }
176
}
177