Completed
Push — dependabot/composer/phpunit/ph... ( 5f27b0...220ad7 )
by
unknown
03:47 queued 02:04
created

Config::has()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
/*
3
 * Copyright (c) Arnaud Ligny <[email protected]>
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace Cecil;
10
11
use Cecil\Exception\Exception;
12
use Dflydev\DotAccessData\Data;
13
14
/**
15
 * Class Config.
16
 */
17
class Config implements \ArrayAccess
18
{
19
    /**
20
     * Configuration is a Data object.
21
     *
22
     * @var Data
23
     */
24
    protected $data;
25
    /**
26
     * Source directory.
27
     *
28
     * @var string
29
     */
30
    protected $sourceDir;
31
    /**
32
     * Destination directory.
33
     *
34
     * @var string
35
     */
36
    protected $destinationDir;
37
38
    /**
39
     * Config constructor.
40
     *
41
     * @param Config|array|null $config
42
     */
43
    public function __construct($config = null)
44
    {
45
        $data = new Data(include __DIR__.'/../config/default.php');
46
47
        if ($config) {
48
            if ($config instanceof self) {
49
                $data->importData($config->getAll());
50
            } elseif (is_array($config)) {
51
                $data->import($config);
52
            }
53
        }
54
55
        /**
56
         * Apply environment variables.
57
         */
58
        $applyEnv = function ($array) use ($data) {
59
            $iterator = new \RecursiveIteratorIterator(
60
                new \RecursiveArrayIterator($array),
61
                \RecursiveIteratorIterator::SELF_FIRST
62
            );
63
            foreach ($iterator as $leafValue) {
64
                $path = [];
65
                foreach (range(0, $iterator->getDepth()) as $depth) {
66
                    $path[] = $iterator->getSubIterator($depth)->key();
67
                }
68
                $sPath = implode('_', $path);
69
                if ($getEnv = getenv('CECIL_'.strtoupper($sPath))) {
70
                    $data->set(str_replace('_', '.', strtolower($sPath)), $getEnv);
71
                }
72
            }
73
        };
74
        $applyEnv($data->export());
75
76
        $this->setFromData($data);
77
    }
78
79
    /**
80
     * Import an array to the current configuration.
81
     *
82
     * @param array $config
83
     */
84
    public function import($config)
85
    {
86
        if (is_array($config)) {
87
            $data = $this->getAll();
88
            $origin = $data->export();
89
            $data->import($config);
90
            $data->import($origin);
91
            $this->setFromData($data);
92
        }
93
    }
94
95
    /**
96
     * Set a Data object as configuration.
97
     *
98
     * @param Data $data
99
     *
100
     * @return $this
101
     */
102
    protected function setFromData(Data $data)
103
    {
104
        if ($this->data !== $data) {
105
            $this->data = $data;
106
        }
107
108
        return $this;
109
    }
110
111
    /**
112
     * Get configuration as a Data object.
113
     *
114
     * @return Data
115
     */
116
    public function getAll()
117
    {
118
        return $this->data;
119
    }
120
121
    /**
122
     * Get configuration as an array.
123
     *
124
     * @return array
125
     */
126
    public function getAllAsArray()
127
    {
128
        return $this->data->export();
129
    }
130
131
    /**
132
     * Is configuration's key' exists?
133
     *
134
     * @param string $key
135
     *
136
     * @return bool
137
     */
138
    public function has($key)
139
    {
140
        return $this->data->has($key);
141
    }
142
143
    /**
144
     * Get the value of a configuration's key'.
145
     *
146
     * @param string $key
147
     * @param string $default
148
     *
149
     * @return array|mixed|null
150
     */
151
    public function get($key, $default = '')
152
    {
153
        return $this->data->get($key, $default);
154
    }
155
156
    /**
157
     * Implement ArrayAccess.
158
     *
159
     * @param mixed $offset
160
     *
161
     * @return bool
162
     */
163
    public function offsetExists($offset)
164
    {
165
        return $this->data->has($offset);
166
    }
167
168
    /**
169
     * Implement ArrayAccess.
170
     *
171
     * @param mixed $offset
172
     *
173
     * @return null
174
     */
175
    public function offsetGet($offset)
176
    {
177
        return $this->data->get($offset);
178
    }
179
180
    /**
181
     * Implement ArrayAccess.
182
     *
183
     * @param mixed $offset
184
     * @param mixed $value
185
     */
186
    public function offsetSet($offset, $value)
187
    {
188
        return $this->data->set($offset, $value);
189
    }
190
191
    /**
192
     * Implement ArrayAccess.
193
     *
194
     * @param mixed $offset
195
     */
196
    public function offsetUnset($offset)
197
    {
198
        return $this->data->remove($offset);
199
    }
200
201
    /**
202
     * Set the source directory.
203
     *
204
     * @param null $sourceDir
205
     *
206
     * @throws Exception
207
     *
208
     * @return $this
209
     */
210 View Code Duplication
    public function setSourceDir($sourceDir = null)
211
    {
212
        if ($sourceDir === null) {
213
            $sourceDir = getcwd();
214
        }
215
        if (!is_dir($sourceDir)) {
216
            throw new \InvalidArgumentException(sprintf('The directory "%s" is not a valid source!', $sourceDir));
217
        }
218
        $this->sourceDir = $sourceDir;
219
220
        return $this;
221
    }
222
223
    /**
224
     * Get the source directory.
225
     *
226
     * @return string
227
     */
228
    public function getSourceDir()
229
    {
230
        return $this->sourceDir;
231
    }
232
233
    /**
234
     * Set the destination directory.
235
     *
236
     * @param null $destinationDir
237
     *
238
     * @throws Exception
239
     *
240
     * @return $this
241
     */
242 View Code Duplication
    public function setDestinationDir($destinationDir = null)
243
    {
244
        if ($destinationDir === null) {
245
            $destinationDir = $this->sourceDir;
246
        }
247
        if (!is_dir($destinationDir)) {
248
            throw new \InvalidArgumentException(sprintf(
249
                'The directory "%s" is not a valid destination!',
250
                $destinationDir
251
            ));
252
        }
253
        $this->destinationDir = $destinationDir;
254
255
        return $this;
256
    }
257
258
    /**
259
     * Get the destination directory.
260
     *
261
     * @return string
262
     */
263
    public function getDestinationDir()
264
    {
265
        return $this->destinationDir;
266
    }
267
268
    /**
269
     * Paths helpers.
270
     */
271
272
    /**
273
     * Return the path of the content directory.
274
     *
275
     * @return string
276
     */
277
    public function getContentPath()
278
    {
279
        return $this->getSourceDir().'/'.$this->get('content.dir');
280
    }
281
282
    /**
283
     * Return the path of templates directory.
284
     *
285
     * @return string
286
     */
287
    public function getLayoutsPath()
288
    {
289
        return $this->getSourceDir().'/'.$this->get('layouts.dir');
290
    }
291
292
    /**
293
     * Return the path of themes directory.
294
     *
295
     * @return string
296
     */
297
    public function getThemesPath()
298
    {
299
        return $this->getSourceDir().'/'.$this->get('themes.dir');
300
    }
301
302
    /**
303
     * Return the path of internal templates directory.
304
     *
305
     * @return string
306
     */
307
    public function getInternalLayoutsPath()
308
    {
309
        return __DIR__.'/../'.$this->get('layouts.internal.dir');
310
    }
311
312
    /**
313
     * Return the path of the output directory.
314
     *
315
     * @return string
316
     */
317
    public function getOutputPath()
318
    {
319
        return $this->getDestinationDir().'/'.$this->get('output.dir');
320
    }
321
322
    /**
323
     * Return the path of static files directory.
324
     *
325
     * @return string
326
     */
327
    public function getStaticPath()
328
    {
329
        return $this->getSourceDir().'/'.$this->get('static.dir');
330
    }
331
332
    /**
333
     * Return a "clean" array of an output format.
334
     *
335
     * @param string $format
336
     *
337
     * @return array
338
     */
339
    public function getOutputFormat(string $format): array
340
    {
341
        $default = [
342
            'mediatype' => null, // 'text/html'
343
            'subpath'   => null, // ''
344
            'suffix'    => null, // '/index'
345
            'extension' => null, // 'html'
346
        ];
347
348
        $result = $this->get(sprintf('output.formats.%s', $format));
349
350
        return array_merge($default, $result);
351
    }
352
353
    /**
354
     * Theme helpers.
355
     */
356
357
    /**
358
     * Return theme(s) as an array.
359
     *
360
     * @return array|null
361
     */
362
    public function getTheme()
363
    {
364
        if ($themes = $this->get('theme')) {
365
            if (is_array($themes)) {
366
                return $themes;
367
            }
368
369
            return [$themes];
370
        }
371
    }
372
373
    /**
374
     * Has a (valid) theme(s)?
375
     *
376
     * @throws Exception
377
     *
378
     * @return bool
379
     */
380
    public function hasTheme()
381
    {
382
        if ($themes = $this->getTheme()) {
383
            foreach ($themes as $theme) {
384
                if (!Util::getFS()->exists($this->getThemeDirPath($theme, 'layouts'))) {
385
                    throw new Exception(sprintf(
386
                        "Theme directory '%s/%s/layouts' not found!",
387
                        $this->getThemesPath(),
388
                        $theme
389
                    ));
390
                }
391
            }
392
393
            return true;
394
        }
395
396
        return false;
397
    }
398
399
    /**
400
     * Return the path of a specific theme's directory.
401
     * ("layouts" by default).
402
     *
403
     * @param string $theme
404
     * @param string $dir
405
     *
406
     * @return string
407
     */
408
    public function getThemeDirPath($theme, $dir = 'layouts')
409
    {
410
        return $this->getThemesPath().'/'.$theme.'/'.$dir;
411
    }
412
413
    /**
414
     * Language helpers.
415
     */
416
417
    /**
418
     * Return an array of available languages.
419
     *
420
     * @return array
421
     */
422
    public function getLanguages(): array
423
    {
424
        return $this->get('languages');
425
    }
426
427
    /**
428
     * Return the default language key (ie: "en", "fr-fr", etc.).
429
     *
430
     * @return string
431
     */
432
    public function getLanguageDefaultKey(): string
433
    {
434
        if ($this->get('language')) {
435
            return $this->get('language');
436
        }
437
438
        $languages = $this->getLanguages();
439
        if (!is_array($languages)) {
440
            throw new Exception('There is no default "language" in configuration!');
441
        }
442
        reset($languages);
443
444
        return key($languages);
445
    }
446
447
    /**
448
     * Return properties of a (specified or default) language.
449
     *
450
     * @return array
451
     */
452
    public function getLanguageProperties($key = null): array
453
    {
454
        $key = $key ?? $this->getLanguageDefaultKey();
455
456
        $languageProperties = $this->get(sprintf('languages.%s', $key));
457
        if (!is_array($languageProperties)) {
458
            throw new Exception(sprintf('Language "%s" is not correctly set in config!', $key));
459
        }
460
461
        return $languageProperties;
462
    }
463
464
    /**
465
     * Return the property value of a (specified or default) language.
466
     *
467
     * @return string
468
     */
469
    public function getLanguageProperty($property, $key = null): string
470
    {
471
        $properties = ['name', 'locale'];
472
        $languageProperties = $this->getLanguageProperties($key);
473
474
        if (!in_array($property, $properties)) {
475
            throw new Exception(sprintf(
476
                'Property language "%s" is not available!',
477
                $property
478
            ));
479
        }
480
        if (!\array_key_exists($property, $languageProperties)) {
481
            throw new Exception(sprintf(
482
                'Property "%s" is not defined for language "%s"!',
483
                $property,
484
                $languageProperties['name']
485
            ));
486
        }
487
488
        return $languageProperties[$property];
489
    }
490
}
491