Completed
Pull Request — master (#47)
by Mateusz
05:43
created

JsonStorage::loadCacheFile()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
/*
4
 * This file is part of the puli/manager package.
5
 *
6
 * (c) Bernhard Schussek <[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
12
namespace Puli\Manager\Json;
13
14
use Puli\Manager\Api\Cache\CacheFile;
15
use Puli\Manager\Api\Config\Config;
16
use Puli\Manager\Api\Config\ConfigFile;
17
use Puli\Manager\Api\Factory\FactoryManager;
18
use Puli\Manager\Api\FileNotFoundException;
19
use Puli\Manager\Api\InvalidConfigException;
20
use Puli\Manager\Api\Module\ModuleFile;
21
use Puli\Manager\Api\Module\RootModuleFile;
22
use Puli\Manager\Api\Storage\ReadException;
23
use Puli\Manager\Api\Storage\Storage;
24
use Puli\Manager\Api\Storage\WriteException;
25
use stdClass;
26
use Webmozart\Json\Conversion\ConversionFailedException;
27
use Webmozart\Json\DecodingFailedException;
28
use Webmozart\Json\EncodingFailedException;
29
use Webmozart\Json\JsonDecoder;
30
use Webmozart\Json\JsonEncoder;
31
32
/**
33
 * Loads and saves JSON files.
34
 *
35
 * @since  1.0
36
 *
37
 * @author Bernhard Schussek <[email protected]>
38
 */
39
class JsonStorage
40
{
41
    /**
42
     * @var Storage
43
     */
44
    private $storage;
45
46
    /**
47
     * @var JsonConverterProvider
48
     */
49
    private $converterProvider;
50
51
    /**
52
     * @var JsonEncoder
53
     */
54
    private $jsonEncoder;
55
56
    /**
57
     * @var JsonDecoder
58
     */
59
    private $jsonDecoder;
60
61
    /**
62
     * @var FactoryManager
63
     */
64
    private $factoryManager;
65
66
    /**
67
     * Creates a new storage.
68
     *
69
     * @param Storage               $storage           The file storage
70
     * @param JsonConverterProvider $converterProvider The provider for the JSON
71
     *                                                 converters
72
     * @param JsonEncoder           $jsonEncoder       The JSON encoder
73
     * @param JsonDecoder           $jsonDecoder       The JSON decoder
74
     * @param FactoryManager|null   $factoryManager    The manager used to
75
     *                                                 regenerate the factory
76
     *                                                 class after saving a file
77
     */
78 78
    public function __construct(
79
        Storage $storage,
80
        JsonConverterProvider $converterProvider,
81
        JsonEncoder $jsonEncoder,
82
        JsonDecoder $jsonDecoder,
83
        FactoryManager $factoryManager = null
84
    ) {
85 78
        $this->storage = $storage;
86 78
        $this->converterProvider = $converterProvider;
87 78
        $this->jsonEncoder = $jsonEncoder;
88 78
        $this->jsonDecoder = $jsonDecoder;
89 78
        $this->factoryManager = $factoryManager;
90 78
    }
91
92
    /**
93
     * Loads a configuration file from a path.
94
     *
95
     * @param string      $path       The path to the configuration file
96
     * @param Config|null $baseConfig The configuration that the loaded
97
     *                                configuration will inherit its values
98
     *                                from
99
     *
100
     * @return ConfigFile The loaded configuration file
101
     *
102
     * @throws FileNotFoundException  If the file does not exist
103
     * @throws ReadException          If the file cannot be read
104
     * @throws InvalidConfigException If the file contains invalid configuration
105
     */
106 52
    public function loadConfigFile($path, Config $baseConfig = null)
107
    {
108 52
        return $this->loadFile($path, 'Puli\Manager\Api\Config\ConfigFile', array(
109 52
            'baseConfig' => $baseConfig,
110
        ));
111
    }
112
113
    /**
114
     * Saves a configuration file.
115
     *
116
     * The configuration file is saved to the same path that it was read from.
117
     *
118
     * @param ConfigFile $configFile The configuration file to save
119
     *
120
     * @throws WriteException         If the file cannot be written
121
     * @throws InvalidConfigException If the file contains invalid configuration
122
     */
123 4
    public function saveConfigFile(ConfigFile $configFile)
124
    {
125 4
        $this->saveFile($configFile, $configFile->getPath());
126
127 2
        if ($this->factoryManager) {
128 1
            $this->factoryManager->autoGenerateFactoryClass();
129
        }
130 2
    }
131
132
    /**
133
     * Loads a module file from a file path.
134
     *
135
     * @param string $path The path to the module file
136
     *
137
     * @return ModuleFile The loaded module file
138
     *
139
     * @throws FileNotFoundException  If the file does not exist
140
     * @throws ReadException          If the file cannot be read
141
     * @throws InvalidConfigException If the file contains invalid configuration
142
     */
143 18
    public function loadModuleFile($path)
144
    {
145 18
        return $this->loadFile($path, 'Puli\Manager\Api\Module\ModuleFile');
146
    }
147
148
    /**
149
     * Saves a module file.
150
     *
151
     * The module file is saved to the same path that it was read from.
152
     *
153
     * @param ModuleFile $moduleFile The module file to save
154
     *
155
     * @throws WriteException         If the file cannot be written
156
     * @throws InvalidConfigException If the file contains invalid configuration
157
     */
158 3
    public function saveModuleFile(ModuleFile $moduleFile)
159
    {
160 3
        $this->saveFile($moduleFile, $moduleFile->getPath(), array(
161 3
            'targetVersion' => $moduleFile->getVersion(),
162
        ));
163 1
    }
164
165
    /**
166
     * Loads a root module file from a file path.
167
     *
168
     * @param string $path       The path to the module configuration file
169
     * @param Config $baseConfig The configuration that the module will inherit
170
     *                           its configuration values from
171
     *
172
     * @return RootModuleFile The loaded module file
173
     *
174
     * @throws FileNotFoundException  If the file does not exist
175
     * @throws ReadException          If the file cannot be read
176
     * @throws InvalidConfigException If the file contains invalid configuration
177
     */
178 31
    public function loadRootModuleFile($path, Config $baseConfig)
179
    {
180 31
        return $this->loadFile($path, 'Puli\Manager\Api\Module\RootModuleFile', array(
181 31
            'baseConfig' => $baseConfig,
182
        ));
183
    }
184
185
    /**
186
     * Saves a root module file.
187
     *
188
     * The module file is saved to the same path that it was read from.
189
     *
190
     * @param RootModuleFile $moduleFile The module file to save
191
     *
192
     * @throws WriteException         If the file cannot be written
193
     * @throws InvalidConfigException If the file contains invalid configuration
194
     */
195 4
    public function saveRootModuleFile(RootModuleFile $moduleFile)
196
    {
197 4
        $this->saveFile($moduleFile, $moduleFile->getPath(), array(
198 4
            'targetVersion' => $moduleFile->getVersion(),
199
        ));
200
201 2
        if ($this->factoryManager) {
202 1
            $this->factoryManager->autoGenerateFactoryClass();
203
        }
204 2
    }
205
206
    /**
207
     * Loads a cache file from a file path.
208
     *
209
     * @param string $path The path to the cache file
210
     *
211
     * @return CacheFile The loaded cache file
212
     *
213
     * @throws FileNotFoundException  If the file does not exist
214
     * @throws ReadException          If the file cannot be read
215
     * @throws InvalidConfigException If the file contains invalid
216
     *                                configuration
217
     */
218 3
    public function loadCacheFile($path)
219
    {
220 3
        return $this->loadFile($path, 'Puli\Manager\Api\Cache\CacheFile', array(
221 3
            'path' => $path,
222
        ));
223
    }
224
225
    /**
226
     * Saves a cache file.
227
     *
228
     * The cache file is saved to the same path that it was read from.
229
     *
230
     * @param CacheFile $cacheFile The cache file to save
231
     *
232
     * @throws WriteException If the file cannot be written
233
     */
234 3
    public function saveCacheFile(CacheFile $cacheFile)
235
    {
236 3
        $this->saveFile($cacheFile, $cacheFile->getPath());
237 1
    }
238
239
    /**
240
     * Returns whether a file exists.
241
     *
242
     * @param string $path File path
243
     *
244
     * @return bool Returns `true` if file exists and `false` otherwise
245
     */
246 2
    public function fileExists($path)
247
    {
248 2
        return $this->storage->exists($path);
249
    }
250
251 62 View Code Duplication
    private function loadFile($path, $className, array $options = array())
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
252
    {
253 62
        $json = $this->storage->read($path);
254 61
        $jsonData = $this->decode($json, $path);
255 57
        $options['path'] = $path;
256
257
        try {
258 57
            return $this->converterProvider->getJsonConverter($className)->fromJson($jsonData, $options);
259 4
        } catch (ConversionFailedException $e) {
260 4
            throw new InvalidConfigException(sprintf(
261 4
                'The JSON in %s could not be converted: %s',
262
                $path,
263 4
                $e->getMessage()
264 4
            ), 0, $e);
265
        }
266
    }
267
268 14 View Code Duplication
    private function saveFile($file, $path, array $options = array())
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
269
    {
270 14
        $className = get_class($file);
271
272
        try {
273 14
            $jsonData = $this->converterProvider->getJsonConverter($className)->toJson($file, $options);
274 4
        } catch (ConversionFailedException $e) {
275 4
            throw new InvalidConfigException(sprintf(
276 4
                'The data written to %s could not be converted: %s',
277
                $path,
278 4
                $e->getMessage()
279 4
            ), 0, $e);
280
        }
281
282 10
        $json = $this->encode($jsonData, $path);
283
284 6
        $this->storage->write($path, $json);
285 6
    }
286
287 10
    private function encode(stdClass $jsonData, $path)
288
    {
289
        try {
290 10
            return $this->jsonEncoder->encode($jsonData);
291 4
        } catch (EncodingFailedException $e) {
292 4
            throw new InvalidConfigException(sprintf(
293 4
                'The configuration in %s could not be encoded: %s',
294
                $path,
295 4
                $e->getMessage()
296 4
            ), 0, $e);
297
        }
298
    }
299
300 61
    private function decode($json, $path)
301
    {
302
        try {
303 61
            return $this->jsonDecoder->decode($json);
304 4
        } catch (DecodingFailedException $e) {
305 4
            throw new InvalidConfigException(sprintf(
306 4
                'The configuration in %s could not be decoded: %s',
307
                $path,
308 4
                $e->getMessage()
309 4
            ), 0, $e);
310
        }
311
    }
312
}
313