Completed
Push — master ( 281eb8...04fe01 )
by Sebastian
10:51
created

Json::setSyncs()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

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