Completed
Push — config-output-formats ( 701b62 )
by Arnaud
02:00
created

Config::setDestinationDir()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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