Completed
Push — languages ( e4f0fd...dc8bf0 )
by Arnaud
01:55 queued 12s
created

Config::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
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
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
            //DEBUG
160
            die('POUET');
161
            $keyLang = "languages.$language.$key";
0 ignored issues
show
Unused Code introduced by
$keyLang = "languages.{$language}.{$key}"; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
162
            if ($this->data->has($keyLang)) {
163
                return $this->data->get($keyLang);
164
            }
165
        }
166
167
        return $this->data->get($key);
168
    }
169
170
    /**
171
     * Set the source directory.
172
     *
173
     * @param string|null $sourceDir
174
     *
175
     * @throws \InvalidArgumentException
176
     *
177
     * @return $this
178
     */
179
    public function setSourceDir(string $sourceDir = null): self
180
    {
181
        if ($sourceDir === null) {
182
            $sourceDir = getcwd();
183
        }
184
        if (!is_dir($sourceDir)) {
185
            throw new \InvalidArgumentException(sprintf('The directory "%s" is not a valid source!', $sourceDir));
186
        }
187
        $this->sourceDir = $sourceDir;
188
189
        return $this;
190
    }
191
192
    /**
193
     * Get the source directory.
194
     *
195
     * @return string
196
     */
197
    public function getSourceDir(): string
198
    {
199
        return $this->sourceDir;
200
    }
201
202
    /**
203
     * Set the destination directory.
204
     *
205
     * @param string|null $destinationDir
206
     *
207
     * @throws \InvalidArgumentException
208
     *
209
     * @return $this
210
     */
211
    public function setDestinationDir(string $destinationDir = null): self
212
    {
213
        if ($destinationDir === null) {
214
            $destinationDir = $this->sourceDir;
215
        }
216
        if (!is_dir($destinationDir)) {
217
            throw new \InvalidArgumentException(sprintf(
218
                'The directory "%s" is not a valid destination!',
219
                $destinationDir
220
            ));
221
        }
222
        $this->destinationDir = $destinationDir;
223
224
        return $this;
225
    }
226
227
    /**
228
     * Get the destination directory.
229
     *
230
     * @return string
231
     */
232
    public function getDestinationDir(): string
233
    {
234
        return $this->destinationDir;
235
    }
236
237
    /**
238
     * Paths helpers.
239
     */
240
241
    /**
242
     * Return the path of the content directory.
243
     *
244
     * @return string
245
     */
246
    public function getContentPath(): string
247
    {
248
        return $this->getSourceDir().'/'.$this->get('content.dir');
249
    }
250
251
    /**
252
     * Return the path of the data directory.
253
     *
254
     * @return string
255
     */
256
    public function getDataPath(): string
257
    {
258
        return $this->getSourceDir().'/'.$this->get('data.dir');
259
    }
260
261
    /**
262
     * Return the path of templates directory.
263
     *
264
     * @return string
265
     */
266
    public function getLayoutsPath(): string
267
    {
268
        return $this->getSourceDir().'/'.$this->get('layouts.dir');
269
    }
270
271
    /**
272
     * Return the path of themes directory.
273
     *
274
     * @return string
275
     */
276
    public function getThemesPath(): string
277
    {
278
        return $this->getSourceDir().'/'.$this->get('themes.dir');
279
    }
280
281
    /**
282
     * Return the path of internal templates directory.
283
     *
284
     * @return string
285
     */
286
    public function getInternalLayoutsPath(): string
287
    {
288
        return __DIR__.'/../'.$this->get('layouts.internal.dir');
289
    }
290
291
    /**
292
     * Return the path of the output directory.
293
     *
294
     * @return string
295
     */
296
    public function getOutputPath(): string
297
    {
298
        return $this->getDestinationDir().'/'.$this->get('output.dir');
299
    }
300
301
    /**
302
     * Return the path of static files directory.
303
     *
304
     * @return string
305
     */
306
    public function getStaticPath(): string
307
    {
308
        return $this->getSourceDir().'/'.$this->get('static.dir');
309
    }
310
311
    /**
312
     * Return a "clean" array of an output format.
313
     *
314
     * @param string $format
315
     *
316
     * @return array
317
     */
318
    public function getOutputFormat(string $format): array
319
    {
320
        $default = [
321
            'mediatype' => null, // 'text/html'
322
            'subpath'   => null, // ''
323
            'suffix'    => null, // '/index'
324
            'extension' => null, // 'html'
325
        ];
326
327
        $result = $this->get(sprintf('output.formats.%s', $format));
328
329
        return array_merge($default, $result);
330
    }
331
332
    /**
333
     * Theme helpers.
334
     */
335
336
    /**
337
     * Return theme(s) as an array.
338
     *
339
     * @return array|null
340
     */
341
    public function getTheme(): ?array
342
    {
343
        if ($themes = $this->get('theme')) {
344
            if (is_array($themes)) {
345
                return $themes;
346
            }
347
348
            return [$themes];
349
        }
350
351
        return null;
352
    }
353
354
    /**
355
     * Has a (valid) theme(s)?
356
     *
357
     * @throws Exception
358
     *
359
     * @return bool
360
     */
361
    public function hasTheme(): bool
362
    {
363
        if ($themes = $this->getTheme()) {
364
            foreach ($themes as $theme) {
365
                if (!Util::getFS()->exists($this->getThemeDirPath($theme, 'layouts'))) {
366
                    throw new Exception(sprintf(
367
                        "Theme directory '%s/%s/layouts' not found!",
368
                        $this->getThemesPath(),
369
                        $theme
370
                    ));
371
                }
372
            }
373
374
            return true;
375
        }
376
377
        return false;
378
    }
379
380
    /**
381
     * Return the path of a specific theme's directory.
382
     * ("layouts" by default).
383
     *
384
     * @param string $theme
385
     * @param string $dir
386
     *
387
     * @return string
388
     */
389
    public function getThemeDirPath(string $theme, string $dir = 'layouts'): string
390
    {
391
        return $this->getThemesPath().'/'.$theme.'/'.$dir;
392
    }
393
394
    /**
395
     * Language helpers.
396
     */
397
398
    /**
399
     * Return an array of available languages.
400
     *
401
     * @return array
402
     */
403
    public function getLanguages(): array
404
    {
405
        return $this->get('languages');
406
    }
407
408
    /**
409
     * Return the default language code (ie: "en", "fr-fr", etc.).
410
     *
411
     * @return string
412
     */
413
    public function getLanguageDefault(): string
414
    {
415
        if ($this->get('language')) {
416
            return $this->get('language');
417
        }
418
419
        $languages = $this->getLanguages();
420
        if (!is_array($languages)) {
421
            throw new Exception('There is no default "language" in configuration!');
422
        }
423
        reset($languages);
424
425
        return $languages['code'];
426
    }
427
428
    /**
429
     * Return the property value of a (specified or default) language.
430
     *
431
     * @param string      $property
432
     * @param string|null $key
433
     *
434
     * @return string
435
     */
436
    public function getLanguageProperty($property, $key = null): string
437
    {
438
        $properties = ['name', 'locale'];
439
        $languageProperties = $this->getLanguageProperties($key);
0 ignored issues
show
Bug introduced by
The method getLanguageProperties() does not exist on Cecil\Config. Did you maybe mean getLanguageProperty()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
440
441
        if (!in_array($property, $properties)) {
442
            throw new Exception(sprintf(
443
                'Property language "%s" is not available!',
444
                $property
445
            ));
446
        }
447
        if (!\array_key_exists($property, $languageProperties)) {
448
            throw new Exception(sprintf(
449
                'Property "%s" is not defined for language "%s"!',
450
                $property,
451
                $languageProperties['name']
452
            ));
453
        }
454
455
        return $languageProperties[$property];
456
    }
457
}
458