Completed
Pull Request — master (#47)
by Mateusz
05:19
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