Completed
Push — master ( 5d3bf9...5839aa )
by Sebastian
03:18
created

Json::setLoggers()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
c 0
b 0
f 0
rs 8.8571
cc 6
eloc 12
nc 7
nop 1
1
<?php
2
namespace phpbu\App\Configuration\Loader;
3
4
use phpbu\App\Configuration;
5
use phpbu\App\Configuration\Loader;
6
use phpbu\App\Exception;
7
use phpbu\App\Util\Arr;
8
9
/**
10
 *
11
 * Loader class for a phpbu JSON configuration file.
12
 *
13
 * Example JSON configuration file:
14
 * <code>
15
 * {
16
 *   "verbose": true,
17
 *   "colors": true,
18
 *   "debug": false,
19
 *   "logging": [
20
 *     {
21
 *       "type": "json",
22
 *       "target": "backup/json.log"
23
 *     }
24
 *   ],
25
 *   "backups": [
26
 *     {
27
 *       "name": "some dir",
28
 *       "source": {
29
 *         "type": "tar",
30
 *         "options": {
31
 *             "path": "some/path"
32
 *         }
33
 *       },
34
 *       "target": {
35
 *         "dirname": "backup",
36
 *         "filename": "tarball-%Y%m%d-%H%i.tar",
37
 *         "compress": "bzip2"
38
 *       },
39
 *       "checks": [
40
 *         {
41
 *           "type": "sizemin",
42
 *           "value": "1B"
43
 *         }
44
 *       ],
45
 *       "cleanup": {
46
 *         "type": "Capacity",
47
 *         "options": {
48
 *           "size": "5M"
49
 *         }
50
 *       }
51
 *     }
52
 *   ]
53
 * }
54
 * </code>
55
 *
56
 * @package    phpbu
57
 * @subpackage App
58
 * @author     Sebastian Feldmann <[email protected]>
59
 * @copyright  Sebastian Feldmann <[email protected]>
60
 * @license    https://opensource.org/licenses/MIT The MIT License (MIT)
61
 * @link       http://phpbu.de/
62
 * @since      Class available since Release 2.1.2
63
 */
64
class Json extends File implements Loader
65
{
66
    /**
67
     * Config file.
68
     *
69
     * @var array
70
     */
71
    private $json;
72
73
    /**
74
     * Constructor.
75
     *
76
     * @param  string $file
77
     * @throws \phpbu\App\Exception
78
     */
79
    public function __construct($file)
80
    {
81
        parent::__construct($file);
82
        $this->json = $this->loadJsonFile($file);
83
    }
84
85
    /**
86
     * Return list of adapter configs.
87
     *
88
     * @return array
89
     * @throws \phpbu\App\Exception
90
     */
91
    protected function getAdapterConfigs()
92
    {
93
        $adapters = [];
94
        if (isset($this->json['adapters'])) {
95
            foreach ($this->json['adapters'] as $a) {
96
                if (!isset($a['type'])) {
97
                    throw new Exception('invalid adapter configuration: type missing');
98
                }
99
                if (!isset($a['name'])) {
100
                    throw new Exception('invalid adapter configuration: name missing');
101
                }
102
                $adapters[] = new Configuration\Adapter($a['type'], $a['name'], $this->getOptions($a));
103
            }
104
        }
105
        return $adapters;
106
    }
107
108
    /**
109
     * Set the phpbu application settings.
110
     *
111
     * @param \phpbu\App\Configuration $configuration
112
     */
113
    public function setAppSettings(Configuration $configuration)
114
    {
115
        if (isset($this->json['bootstrap'])) {
116
            $configuration->setBootstrap($this->toAbsolutePath($this->json['bootstrap']));
117
        }
118
        if (isset($this->json['verbose'])) {
119
            $configuration->setVerbose($this->json['verbose']);
120
        }
121
        if (isset($this->json['colors'])) {
122
            $configuration->setColors($this->json['colors']);
123
        }
124
    }
125
126
    /**
127
     * Set the log configuration.
128
     *
129
     * @param  \phpbu\App\Configuration $configuration
130
     * @throws \phpbu\App\Exception
131
     */
132
    public function setLoggers(Configuration $configuration)
133
    {
134
        if (isset($this->json['logging'])) {
135
            foreach ($this->json['logging'] as $l) {
136
                if (!isset($l['type'])) {
137
                    throw new Exception('invalid logger configuration: type missing');
138
                }
139
                $type    = $l['type'];
140
                $options = $this->getOptions($l);
141
                if (isset($options['target'])) {
142
                    $options['target'] = $this->toAbsolutePath($options['target']);
143
                }
144
                // search for target attribute to convert to option
145
                if (isset($l['target'])) {
146
                    $options['target'] = $this->toAbsolutePath($l['target']);
147
                }
148
                $configuration->addLogger(new Configuration\Logger($type, $options));
149
            }
150
        }
151
    }
152
153
    /**
154
     * Set the backup configurations.
155
     *
156
     * @param  \phpbu\App\Configuration $configuration
157
     * @throws \phpbu\App\Exception
158
     */
159
    public function setBackups(Configuration $configuration)
160
    {
161
        if (!isset($this->json['backups'])) {
162
            throw new Exception('no backup configured');
163
        }
164
        foreach ($this->json['backups'] as $backup) {
165
            $configuration->addBackup($this->getBackupConfig($backup));
166
        }
167
    }
168
169
    /**
170
     * Get the config for a single backup node.
171
     *
172
     * @param  array $json
173
     * @throws \phpbu\App\Exception
174
     * @return \phpbu\App\Configuration\Backup
175
     */
176 View Code Duplication
    private function getBackupConfig(array $json)
177
    {
178
        $name          = Arr::getValue($json, 'name');
179
        $stopOnFailure = Arr::getValue($json, 'stopOnFailure', false);
180
        $backup        = new Configuration\Backup($name, $stopOnFailure);
181
182
        $backup->setSource($this->getSource($json));
183
        $backup->setTarget($this->getTarget($json));
184
185
        $this->setChecks($backup, $json);
186
        $this->setCrypt($backup, $json);
187
        $this->setSyncs($backup, $json);
188
        $this->setCleanup($backup, $json);
189
190
        return $backup;
191
    }
192
193
    /**
194
     * Get source configuration.
195
     *
196
     * @param  array $json
197
     * @return \phpbu\App\Configuration\Backup\Source
198
     * @throws \phpbu\App\Exception
199
     */
200
    protected function getSource(array $json)
201
    {
202
        if (!isset($json['source'])) {
203
            throw new Exception('backup requires exactly one source config');
204
        }
205
        if (!isset($json['source']['type'])) {
206
            throw new Exception('source requires type');
207
        }
208
209
        return new Configuration\Backup\Source($json['source']['type'], $this->getOptions($json['source']));
210
    }
211
212
    /**
213
     * Get Target configuration.
214
     *
215
     * @param  array $json
216
     * @return \phpbu\App\Configuration\Backup\Target
217
     * @throws \phpbu\App\Exception
218
     */
219
    protected function getTarget(array $json)
220
    {
221
        if (!isset($json['target'])) {
222
            throw new Exception('backup requires a target config');
223
        }
224
        $compress = Arr::getValue($json['target'], 'compress');
225
        $filename = Arr::getValue($json['target'], 'filename');
226
        $dirname  = Arr::getValue($json['target'], 'dirname');
227
228
        if ($dirname) {
229
            $dirname = $this->toAbsolutePath($dirname);
230
        }
231
232
        return new Configuration\Backup\Target($dirname, $filename, $compress);
233
    }
234
235
    /**
236
     * Set backup checks.
237
     *
238
     * @param \phpbu\App\Configuration\Backup $backup
239
     * @param array                           $json
240
     */
241
    protected function setChecks(Configuration\Backup $backup, array $json)
242
    {
243
        if (isset($json['checks'])) {
244
            foreach ($json['checks'] as $c) {
245
                $type  = Arr::getValue($c, 'type');
246
                $value = Arr::getValue($c, 'value');
247
                // skip invalid sanity checks
248
                if (!$type || !$value) {
249
                    continue;
250
                }
251
                $backup->addCheck(new Configuration\Backup\Check($type, $value));
252
            }
253
        }
254
    }
255
256
    /**
257
     * Set the crypt configuration.
258
     *
259
     * @param  \phpbu\App\Configuration\Backup $backup
260
     * @param  array                           $json
261
     * @throws \phpbu\App\Exception
262
     */
263 View Code Duplication
    protected function setCrypt(Configuration\Backup $backup, array $json)
264
    {
265
        if (isset($json['crypt'])) {
266
            if (!isset($json['crypt']['type'])) {
267
                throw new Exception('invalid crypt configuration: type missing');
268
            }
269
            $type    = $json['crypt']['type'];
270
            $skip    = Arr::getValue($json['crypt'], 'skipOnFailure', true);
271
            $options = $this->getOptions($json['crypt']);
272
            $backup->setCrypt(new Configuration\Backup\Crypt($type, $skip, $options));
273
        }
274
    }
275
276
    /**
277
     * Set backup sync configurations.
278
     *
279
     * @param  \phpbu\App\Configuration\Backup $backup
280
     * @param  array                           $json
281
     * @throws \phpbu\App\Exception
282
     */
283
    protected function setSyncs(Configuration\Backup $backup, array $json)
284
    {
285
        if (isset($json['syncs'])) {
286
            foreach ($json['syncs'] as $s) {
287
                if (!isset($s['type'])) {
288
                    throw new Exception('invalid sync configuration: attribute type missing');
289
                }
290
                $type    = $s['type'];
291
                $skip    = Arr::getValue($s, 'skipOnFailure', true);
292
                $options = $this->getOptions($s);
293
                $backup->addSync(new Configuration\Backup\Sync($type, $skip, $options));
294
            }
295
        }
296
    }
297
298
    /**
299
     * Set the cleanup configuration.
300
     *
301
     * @param  \phpbu\App\Configuration\Backup $backup
302
     * @param  array                           $json
303
     * @throws \phpbu\App\Exception
304
     */
305 View Code Duplication
    protected function setCleanup(Configuration\Backup $backup, array $json)
306
    {
307
        if (isset($json['cleanup'])) {
308
            if (!isset($json['cleanup']['type'])) {
309
                throw new Exception('invalid cleanup configuration: type missing');
310
            }
311
            $type    = $json['cleanup']['type'];
312
            $skip    = Arr::getValue($json['cleanup'], 'skipOnFailure', true);
313
            $options = $this->getOptions($json['cleanup']);
314
            $backup->setCleanup(new Configuration\Backup\Cleanup($type, $skip, $options));
315
        }
316
    }
317
318
    /**
319
     * Extracts all option tags.
320
     *
321
     * @param  array $json
322
     * @return array
323
     */
324
    protected function getOptions(array $json)
325
    {
326
        $options = isset($json['options']) ? $json['options'] : [];
327
328
        foreach ($options as $name => $value) {
329
            $options[$name] = $this->getOptionValue($value);
330
        }
331
332
        return $options;
333
    }
334
335
    /**
336
     * Load the JSON-File.
337
     *
338
     * @param  string $filename
339
     * @throws \phpbu\App\Exception
340
     * @return array
341
     */
342
    private function loadJsonFile($filename)
343
    {
344
        $contents  = $this->loadFile($filename);
345
        $reporting = error_reporting(0);
346
        $json      = json_decode($contents, true);
347
        error_reporting($reporting);
348
349
        if (!is_array($json)) {
350
            throw new Exception(sprintf('Error loading file "%s"', $filename));
351
        }
352
        return $json;
353
    }
354
}
355