Failed Conditions
Push — master ( ebb1ea...d49c03 )
by Bernhard
06:05
created

PackageFileStorage::decode()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 9

Duplication

Lines 12
Ratio 100 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 12
loc 12
ccs 7
cts 7
cp 1
rs 9.4285
cc 2
eloc 9
nc 2
nop 2
crap 2
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\Package;
13
14
use Puli\Manager\Api\Config\Config;
15
use Puli\Manager\Api\Factory\FactoryManager;
16
use Puli\Manager\Api\FileNotFoundException;
17
use Puli\Manager\Api\InvalidConfigException;
18
use Puli\Manager\Api\Package\PackageFile;
19
use Puli\Manager\Api\Package\RootPackageFile;
20
use Puli\Manager\Api\Storage\ReadException;
21
use Puli\Manager\Api\Storage\Storage;
22
use Puli\Manager\Api\Storage\WriteException;
23
use stdClass;
24
use Webmozart\Json\Conversion\ConversionFailedException;
25
use Webmozart\Json\Conversion\JsonConverter;
26
use Webmozart\Json\DecodingFailedException;
27
use Webmozart\Json\EncodingFailedException;
28
use Webmozart\Json\JsonDecoder;
29
use Webmozart\Json\JsonEncoder;
30
31
/**
32
 * Loads and saves package files.
33
 *
34
 * @since  1.0
35
 *
36
 * @author Bernhard Schussek <[email protected]>
37
 */
38
class PackageFileStorage
39
{
40
    /**
41
     * @var Storage
42
     */
43
    private $storage;
44
45
    /**
46
     * @var JsonConverter
47
     */
48
    private $packageFileConverter;
49
50
    /**
51
     * @var JsonConverter
52
     */
53
    private $rootPackageFileConverter;
54
55
    /**
56
     * @var JsonEncoder
57
     */
58
    private $jsonEncoder;
59
60
    /**
61
     * @var JsonDecoder
62
     */
63
    private $jsonDecoder;
64
65
    /**
66
     * @var FactoryManager
67
     */
68
    private $factoryManager;
69
70
    /**
71
     * Creates a new storage.
72
     *
73
     * @param Storage             $storage                  The file storage.
74
     * @param JsonConverter       $packageFileConverter     The JSON converter for
75
     *                                                      {@link PackageFile}
76
     *                                                      instances.
77
     * @param JsonConverter       $rootPackageFileConverter The JSON converter
78
     *                                                      for {@link RootPackageFile}
79
     *                                                      instances.
80
     * @param JsonEncoder         $jsonEncoder              The JSON encoder.
81
     * @param JsonDecoder         $jsonDecoder              The JSON decoder.
82
     * @param FactoryManager|null $factoryManager           The manager used to
83
     *                                                      regenerate the factory
84
     *                                                      class after saving
85
     *                                                      the root package file.
86
     */
87 40 View Code Duplication
    public function __construct(
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...
88
        Storage $storage,
89
        JsonConverter $packageFileConverter,
90
        JsonConverter $rootPackageFileConverter,
91
        JsonEncoder $jsonEncoder,
92
        JsonDecoder $jsonDecoder,
93
        FactoryManager $factoryManager = null
94
    ) {
95 40
        $this->storage = $storage;
96 40
        $this->packageFileConverter = $packageFileConverter;
97 40
        $this->rootPackageFileConverter = $rootPackageFileConverter;
98 40
        $this->jsonEncoder = $jsonEncoder;
99 40
        $this->jsonDecoder = $jsonDecoder;
100 40
        $this->factoryManager = $factoryManager;
101 40
    }
102
103
    /**
104
     * Loads a package file from a file path.
105
     *
106
     * If the file does not exist, an empty configuration is returned.
107
     *
108
     * Loaded package files must have a package name set. If none is set, an
109
     * exception is thrown.
110
     *
111
     * @param string $path The path to the package file.
112
     *
113
     * @return PackageFile The loaded package file.
114
     *
115
     * @throws FileNotFoundException  If the file does not exist.
116
     * @throws ReadException          If the file cannot be read.
117
     * @throws InvalidConfigException If the file contains invalid configuration.
118
     */
119 17 View Code Duplication
    public function loadPackageFile($path)
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...
120
    {
121 17
        $json = $this->storage->read($path);
122 17
        $jsonData = $this->decode($json, $path);
123
124
        try {
125 16
            return $this->packageFileConverter->fromJson($jsonData, array(
126 16
                'path' => $path,
127
            ));
128 1
        } catch (ConversionFailedException $e) {
129 1
            throw new InvalidConfigException(sprintf(
130 1
                'The JSON in %s could not be converted: %s',
131
                $path,
132 1
                $e->getMessage()
133 1
            ), 0, $e);
134
        }
135
    }
136
137
    /**
138
     * Saves a package file.
139
     *
140
     * The package file is saved to the same path that it was read from.
141
     *
142
     * @param PackageFile $packageFile The package file to save.
143
     *
144
     * @throws WriteException         If the file cannot be written.
145
     * @throws InvalidConfigException If the file contains invalid configuration.
146
     */
147 3
    public function savePackageFile(PackageFile $packageFile)
148
    {
149
        try {
150 3
            $jsonData = $this->packageFileConverter->toJson($packageFile, array(
151 3
                'targetVersion' => $packageFile->getVersion(),
152
            ));
153 1
        } catch (ConversionFailedException $e) {
154 1
            throw new InvalidConfigException(sprintf(
155 1
                'The data written to %s could not be converted: %s',
156 1
                $packageFile->getPath(),
157 1
                $e->getMessage()
158 1
            ), 0, $e);
159
        }
160
161 2
        $json = $this->encode($jsonData, $packageFile->getPath());
162
163 1
        $this->storage->write($packageFile->getPath(), $json);
164 1
    }
165
166
    /**
167
     * Loads a root package file from a file path.
168
     *
169
     * If the file does not exist, an empty configuration is returned.
170
     *
171
     * @param string $path       The path to the package configuration file.
172
     * @param Config $baseConfig The configuration that the package will inherit
173
     *                           its configuration values from.
174
     *
175
     * @return RootPackageFile The loaded package file.
176
     *
177
     * @throws FileNotFoundException  If the file does not exist.
178
     * @throws ReadException          If the file cannot be read.
179
     * @throws InvalidConfigException If the file contains invalid configuration.
180
     */
181 30 View Code Duplication
    public function loadRootPackageFile($path, Config $baseConfig)
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...
182
    {
183 30
        $json = $this->storage->read($path);
184 29
        $jsonData = $this->decode($json, $path);
185
186
        try {
187 28
            return $this->rootPackageFileConverter->fromJson($jsonData, array(
188 28
                'path' => $path,
189 28
                'baseConfig' => $baseConfig,
190
            ));
191 1
        } catch (ConversionFailedException $e) {
192 1
            throw new InvalidConfigException(sprintf(
193 1
                'The JSON in %s could not be converted: %s',
194
                $path,
195 1
                $e->getMessage()
196 1
            ), 0, $e);
197
        }
198
    }
199
200
    /**
201
     * Saves a root package file.
202
     *
203
     * The package file is saved to the same path that it was read from.
204
     *
205
     * @param RootPackageFile $packageFile The package file to save.
206
     *
207
     * @throws WriteException         If the file cannot be written.
208
     * @throws InvalidConfigException If the file contains invalid configuration.
209
     */
210 4 View Code Duplication
    public function saveRootPackageFile(RootPackageFile $packageFile)
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...
211
    {
212
        try {
213 4
            $jsonData = $this->rootPackageFileConverter->toJson($packageFile, array(
214 4
                'targetVersion' => $packageFile->getVersion(),
215
            ));
216 1
        } catch (ConversionFailedException $e) {
217 1
            throw new InvalidConfigException(sprintf(
218 1
                'The data written to %s could not be converted: %s',
219 1
                $packageFile->getPath(),
220 1
                $e->getMessage()
221 1
            ), 0, $e);
222
        }
223
224 3
        $json = $this->encode($jsonData, $packageFile->getPath());
225
226 2
        $this->storage->write($packageFile->getPath(), $json);
227
228 2
        if ($this->factoryManager) {
229 1
            $this->factoryManager->autoGenerateFactoryClass();
230
        }
231 2
    }
232
233 5 View Code Duplication
    private function encode(stdClass $jsonData, $path)
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...
234
    {
235
        try {
236 5
            return $this->jsonEncoder->encode($jsonData);
237 2
        } catch (EncodingFailedException $e) {
238 2
            throw new InvalidConfigException(sprintf(
239 2
                'The configuration in %s could not be encoded: %s',
240
                $path,
241 2
                $e->getMessage()
242 2
            ), 0, $e);
243
        }
244
    }
245
246 32 View Code Duplication
    private function decode($json, $path)
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...
247
    {
248
        try {
249 32
            return $this->jsonDecoder->decode($json);
250 2
        } catch (DecodingFailedException $e) {
251 2
            throw new InvalidConfigException(sprintf(
252 2
                'The configuration in %s could not be decoded: %s',
253
                $path,
254 2
                $e->getMessage()
255 2
            ), 0, $e);
256
        }
257
    }
258
}
259