Passed
Push — fix-assets-images-managment ( a7deda...445b39 )
by Arnaud
06:17 queued 39s
created

Config::getCachePath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
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
            $iterator->rewind();
87
            while ($iterator->valid()) {
88
                $path = [];
89
                foreach (range(0, $iterator->getDepth()) as $depth) {
90
                    $path[] = $iterator->getSubIterator($depth)->key();
91
                }
92
                $sPath = implode('_', $path);
93
                if ($getEnv = getenv('CECIL_'.strtoupper($sPath))) {
94
                    $data->set(str_replace('_', '.', strtolower($sPath)), $getEnv);
95
                }
96
                $iterator->next();
97
            }
98
        };
99
        $applyEnv($data->export());
100
    }
101
102
    /**
103
     * Set a Data object as configuration.
104
     *
105
     * @param Data $data
106
     *
107
     * @return $this
108
     */
109
    protected function setData(Data $data): self
110
    {
111
        if ($this->data !== $data) {
112
            $this->data = $data;
113
        }
114
115
        return $this;
116
    }
117
118
    /**
119
     * Get configuration as a Data object.
120
     *
121
     * @return Data
122
     */
123
    public function getData(): Data
124
    {
125
        return $this->data;
126
    }
127
128
    /**
129
     * Get configuration as an array.
130
     *
131
     * @return array
132
     */
133
    public function getAsArray(): array
134
    {
135
        return $this->data->export();
136
    }
137
138
    /**
139
     * Is configuration's key' exists?
140
     *
141
     * @param string $key
142
     *
143
     * @return bool
144
     */
145
    public function has(string $key): bool
146
    {
147
        return $this->data->has($key);
148
    }
149
150
    /**
151
     * Get the value of a configuration's key'.
152
     *
153
     * @param string      $key
154
     * @param string|null $language
155
     *
156
     * @return array|mixed|null
157
     */
158
    public function get(string $key, string $language = null)
159
    {
160
        if ($language !== null) {
161
            $index = $this->getLanguageIndex($language);
162
            $keyLang = sprintf('languages.%s.config.%s', $index, $key);
163
            if ($this->data->has($keyLang)) {
164
                return $this->data->get($keyLang);
165
            }
166
        }
167
168
        return $this->data->get($key);
169
    }
170
171
    /**
172
     * Set the source directory.
173
     *
174
     * @param string|null $sourceDir
175
     *
176
     * @throws \InvalidArgumentException
177
     *
178
     * @return $this
179
     */
180
    public function setSourceDir(string $sourceDir = null): self
181
    {
182
        if ($sourceDir === null) {
183
            $sourceDir = getcwd();
184
        }
185
        if (!is_dir($sourceDir)) {
186
            throw new \InvalidArgumentException(sprintf('The directory "%s" is not a valid source!', $sourceDir));
187
        }
188
        $this->sourceDir = $sourceDir;
189
190
        return $this;
191
    }
192
193
    /**
194
     * Get the source directory.
195
     *
196
     * @return string
197
     */
198
    public function getSourceDir(): string
199
    {
200
        return $this->sourceDir;
201
    }
202
203
    /**
204
     * Set the destination directory.
205
     *
206
     * @param string|null $destinationDir
207
     *
208
     * @throws \InvalidArgumentException
209
     *
210
     * @return $this
211
     */
212
    public function setDestinationDir(string $destinationDir = null): self
213
    {
214
        if ($destinationDir === null) {
215
            $destinationDir = $this->sourceDir;
216
        }
217
        if (!is_dir($destinationDir)) {
218
            throw new \InvalidArgumentException(sprintf(
219
                'The directory "%s" is not a valid destination!',
220
                $destinationDir
221
            ));
222
        }
223
        $this->destinationDir = $destinationDir;
224
225
        return $this;
226
    }
227
228
    /**
229
     * Get the destination directory.
230
     *
231
     * @return string
232
     */
233
    public function getDestinationDir(): string
234
    {
235
        return $this->destinationDir;
236
    }
237
238
    /**
239
     * Paths helpers.
240
     */
241
242
    /**
243
     * Return the path of the content directory.
244
     *
245
     * @return string
246
     */
247
    public function getContentPath(): string
248
    {
249
        return $this->getSourceDir().'/'.(string) $this->get('content.dir');
250
    }
251
252
    /**
253
     * Return the path of the data directory.
254
     *
255
     * @return string
256
     */
257
    public function getDataPath(): string
258
    {
259
        return $this->getSourceDir().'/'.(string) $this->get('data.dir');
260
    }
261
262
    /**
263
     * Return the path of templates directory.
264
     *
265
     * @return string
266
     */
267
    public function getLayoutsPath(): string
268
    {
269
        return $this->getSourceDir().'/'.(string) $this->get('layouts.dir');
270
    }
271
272
    /**
273
     * Return the path of themes directory.
274
     *
275
     * @return string
276
     */
277
    public function getThemesPath(): string
278
    {
279
        return $this->getSourceDir().'/'.(string) $this->get('themes.dir');
280
    }
281
282
    /**
283
     * Return the path of internal templates directory.
284
     *
285
     * @return string
286
     */
287
    public function getInternalLayoutsPath(): string
288
    {
289
        return __DIR__.'/../'.(string) $this->get('layouts.internal.dir');
290
    }
291
292
    /**
293
     * Return the path of the output directory.
294
     *
295
     * @return string
296
     */
297
    public function getOutputPath(): string
298
    {
299
        return $this->getDestinationDir().'/'.(string) $this->get('output.dir');
300
    }
301
302
    /**
303
     * Return the path of static files directory.
304
     *
305
     * @return string
306
     */
307
    public function getStaticPath(): string
308
    {
309
        return $this->getSourceDir().'/'.(string) $this->get('static.dir');
310
    }
311
312
    /**
313
     * Is cache dir is absolute to systeme file
314
     * or relative to project destiantion?
315
     *
316
     * @return bool
317
     */
318
    public function isCacheDirIsAbsolute(): bool
319
    {
320
        $path = (string) $this->get('cache.dir');
321
        if (strpos($path, '/') !== false && strpos($path, '/') === 0) {
322
            return true;
323
        }
324
325
        return false;
326
    }
327
328
    /**
329
     * Return cache path.
330
     *
331
     * @return string
332
     */
333
    public function getCachePath(): string
334
    {
335
        if ($this->isCacheDirIsAbsolute()) {
336
            return (string) $this->get('cache.dir');
337
        }
338
339
        return $this->getDestinationDir().'/'.(string) $this->get('cache.dir');
340
    }
341
342
    /**
343
     * Return the path to images/thumbs cache dir.
344
     *
345
     * @return string
346
     */
347
    public function getCacheImagesThumbsPath(): string
348
    {
349
        return $this->getCachePath()
350
            .'/'.(string) $this->get('cache.images.dir')
351
            .'/'.(string) $this->get('cache.images.thumbs.dir');
352
    }
353
354
    /**
355
     * Return the property value of an output format.
356
     *
357
     * @param string $property
358
     * @param string $name
359
     *
360
     * @return string|array|null
361
     */
362
    public function getOutputFormatProperty(string $name, string $property)
363
    {
364
        $properties = array_column((array) $this->get('output.formats'), $property, 'name');
365
366
        if (empty($properties)) {
367
            throw new Exception(sprintf(
368
                'Property "%s" is not defined for format "%s".',
369
                $property,
370
                $name
371
            ));
372
        }
373
374
        if (!array_key_exists($name, $properties)) {
375
            return null;
376
        }
377
378
        return $properties[$name];
379
    }
380
381
    /**
382
     * Theme helpers.
383
     */
384
385
    /**
386
     * Return theme(s) as an array.
387
     *
388
     * @return array|null
389
     */
390
    public function getTheme(): ?array
391
    {
392
        if ($themes = $this->get('theme')) {
393
            if (is_array($themes)) {
394
                return $themes;
395
            }
396
397
            return [$themes];
398
        }
399
400
        return null;
401
    }
402
403
    /**
404
     * Has a (valid) theme(s)?
405
     *
406
     * @throws Exception
407
     *
408
     * @return bool
409
     */
410
    public function hasTheme(): bool
411
    {
412
        if ($themes = $this->getTheme()) {
413
            foreach ($themes as $theme) {
414
                if (!Util::getFS()->exists($this->getThemeDirPath($theme, 'layouts'))) {
415
                    throw new Exception(sprintf(
416
                        "Theme directory '%s/%s/layouts' not found!",
417
                        $this->getThemesPath(),
418
                        $theme
419
                    ));
420
                }
421
            }
422
423
            return true;
424
        }
425
426
        return false;
427
    }
428
429
    /**
430
     * Return the path of a specific theme's directory.
431
     * ("layouts" by default).
432
     *
433
     * @param string $theme
434
     * @param string $dir
435
     *
436
     * @return string
437
     */
438
    public function getThemeDirPath(string $theme, string $dir = 'layouts'): string
439
    {
440
        return $this->getThemesPath().'/'.$theme.'/'.$dir;
441
    }
442
443
    /**
444
     * Language helpers.
445
     */
446
447
    /**
448
     * Return an array of available languages.
449
     *
450
     * @return array
451
     */
452
    public function getLanguages(): array
453
    {
454
        return $this->get('languages');
455
    }
456
457
    /**
458
     * Return the default language code (ie: "en", "fr-fr", etc.).
459
     *
460
     * @return string
461
     */
462
    public function getLanguageDefault(): string
463
    {
464
        if (!$this->get('language')) {
465
            throw new Exception('There is no default "language" in configuration.');
466
        }
467
468
        return $this->get('language');
469
    }
470
471
    /**
472
     * Return a language code index.
473
     *
474
     * @param string $code
475
     *
476
     * @return int
477
     */
478
    public function getLanguageIndex(string $code): int
479
    {
480
        $array = array_column($this->getLanguages(), 'code');
481
482
        if (!$index = array_search($code, $array)) {
483
            throw new Exception(sprintf('The language code "%s" is not defined.', $code));
484
        }
485
486
        return $index;
487
    }
488
489
    /**
490
     * Return the property value of a (specified or default) language.
491
     *
492
     * @param string      $property
493
     * @param string|null $code
494
     *
495
     * @return string|null
496
     */
497
    public function getLanguageProperty(string $property, string $code = null): ?string
498
    {
499
        $code = $code ?? $this->getLanguageDefault();
500
501
        $properties = array_column($this->getLanguages(), $property, 'code');
502
503
        if (empty($properties)) {
504
            throw new Exception(sprintf(
505
                'Property "%s" is not defined for language "%s".',
506
                $property,
507
                $code
508
            ));
509
        }
510
511
        return $properties[$code];
512
    }
513
}
514