Completed
Push — include-lib ( fd24a6...4173d3 )
by Arnaud
13:24
created

Config   A

Complexity

Total Complexity 36

Size/Duplication

Total Lines 401
Duplicated Lines 5.99 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 36
lcom 1
cbo 4
dl 24
loc 401
rs 9.52
c 0
b 0
f 0

19 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 35 7
A import() 0 10 2
A setFromData() 0 8 2
A getAll() 0 4 1
A getAllAsArray() 0 4 1
A get() 0 4 1
A setSourceDir() 12 12 3
A getSourceDir() 0 4 1
A setDestinationDir() 12 12 3
A getDestinationDir() 0 4 1
A getContentPath() 0 4 1
A getLayoutsPath() 0 4 1
A getThemesPath() 0 4 1
A getInternalLayoutsPath() 0 4 1
A getOutputPath() 0 4 1
A getStaticPath() 0 4 1
A getTheme() 0 10 3
A hasTheme() 0 18 4
A getThemeDirPath() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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 Dflydev\DotAccessData\Data;
12
use Cecil\Exception\Exception;
13
14
/**
15
 * Class Config.
16
 */
17
class Config
18
{
19
    /**
20
     * Config.
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
     * Default data.
39
     *
40
     * @var array
41
     */
42
    protected static $defaultData = [
43
        'site' => [
44
            'title'        => 'My Webiste',
45
            'baseline'     => 'An amazing static website!',
46
            'baseurl'      => 'http://localhost:8000/',
47
            'canonicalurl' => false,
48
            'description'  => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
49
            'taxonomies'   => [
50
                'tags'       => 'tag',
51
                'categories' => 'category',
52
            ],
53
            'paginate' => [
54
                'max'  => 5,
55
                'path' => 'page',
56
            ],
57
            'date' => [
58
                'format'   => 'j F Y',
59
                'timezone' => 'Europe/Paris',
60
            ],
61
            'fmpages' => [
62
                'robotstxt' => [
63
                    'title'     => 'Robots.txt',
64
                    'layout'    => 'robots.txt',
65
                    'permalink' => 'robots.txt',
66
                ],
67
                'sitemap' => [
68
                    'title'      => 'XML sitemap',
69
                    'layout'     => 'sitemap.xml',
70
                    'permalink'  => 'sitemap.xml',
71
                    'changefreq' => 'monthly',
72
                    'priority'   => '0.5',
73
                ],
74
                '404' => [
75
                    'title'     => '404 page',
76
                    'layout'    => '404.html',
77
                    'permalink' => '404.html',
78
                ],
79
                'rss' => [
80
                    'title'     => 'RSS file',
81
                    'layout'    => 'rss.xml',
82
                    'permalink' => 'rss.xml',
83
                    'section'   => 'blog',
84
                ],
85
            ],
86
        ],
87
        'content' => [
88
            'dir' => 'content',
89
            'ext' => ['md', 'markdown', 'mdown', 'mkdn', 'mkd', 'text', 'txt'],
90
        ],
91
        'frontmatter' => [
92
            'format' => 'yaml',
93
        ],
94
        'body' => [
95
            'format' => 'md',
96
        ],
97
        'static' => [
98
            'dir' => 'static',
99
        ],
100
        'layouts' => [
101
            'dir'      => 'layouts',
102
            'internal' => [
103
                'dir' => 'res/layouts',
104
            ],
105
        ],
106
        'output' => [
107
            'dir'      => '_site',
108
            'filename' => 'index.html',
109
        ],
110
        'themes' => [
111
            'dir' => 'themes',
112
        ],
113
        'generators' => [
114
            10 => 'Cecil\Generator\Section',
115
            20 => 'Cecil\Generator\Taxonomy',
116
            30 => 'Cecil\Generator\Homepage',
117
            40 => 'Cecil\Generator\Pagination',
118
            50 => 'Cecil\Generator\Alias',
119
            35 => 'Cecil\Generator\ExternalBody',
120
            36 => 'Cecil\Generator\PagesFromConfig',
121
            60 => 'Cecil\Generator\Redirect',
122
        ],
123
    ];
124
125
    /**
126
     * Config constructor.
127
     *
128
     * @param Config|array|null $config
129
     */
130
    public function __construct($config = null)
131
    {
132
        $data = new Data(self::$defaultData);
133
134
        if ($config) {
135
            if ($config instanceof self) {
136
                $data->importData($config->getAll());
137
            } elseif (is_array($config)) {
138
                $data->import($config);
139
            }
140
        }
141
142
        /**
143
         * Apply environment variables.
144
         */
145
        $applyEnv = function ($array) use ($data) {
146
            $iterator = new \RecursiveIteratorIterator(
147
                new \RecursiveArrayIterator($array),
148
                \RecursiveIteratorIterator::SELF_FIRST
149
            );
150
            foreach ($iterator as $leafValue) {
151
                $path = [];
152
                foreach (range(0, $iterator->getDepth()) as $depth) {
153
                    $path[] = $iterator->getSubIterator($depth)->key();
154
                }
155
                $sPath = implode('_', $path);
156
                if ($getEnv = getenv('PHPOOLE_'.strtoupper($sPath))) {
157
                    $data->set(str_replace('_', '.', strtolower($sPath)), $getEnv);
158
                }
159
            }
160
        };
161
        $applyEnv($data->export());
162
163
        $this->setFromData($data);
164
    }
165
166
    /**
167
     * Import array config to current config.
168
     *
169
     * @param array $config
170
     */
171
    public function import($config)
172
    {
173
        if (is_array($config)) {
174
            $data = $this->getAll();
175
            $origin = $data->export();
176
            $data->import($config);
177
            $data->import($origin);
178
            $this->setFromData($data);
179
        }
180
    }
181
182
    /**
183
     * Set config data.
184
     *
185
     * @param Data $data
186
     *
187
     * @return $this
188
     */
189
    protected function setFromData(Data $data)
190
    {
191
        if ($this->data !== $data) {
192
            $this->data = $data;
193
        }
194
195
        return $this;
196
    }
197
198
    /**
199
     * Get config data.
200
     *
201
     * @return Data
202
     */
203
    public function getAll()
204
    {
205
        return $this->data;
206
    }
207
208
    /**
209
     * Get data as array.
210
     *
211
     * @return array
212
     */
213
    public function getAllAsArray()
214
    {
215
        return $this->data->export();
216
    }
217
218
    /**
219
     * Return a config value.
220
     *
221
     * @param string $key
222
     * @param string $default
223
     *
224
     * @return array|mixed|null
225
     */
226
    public function get($key, $default = '')
227
    {
228
        return $this->data->get($key, $default);
229
    }
230
231
    /**
232
     * Set source directory.
233
     *
234
     * @param null $sourceDir
235
     *
236
     * @throws Exception
237
     *
238
     * @return $this
239
     */
240 View Code Duplication
    public function setSourceDir($sourceDir = null)
241
    {
242
        if ($sourceDir === null) {
243
            $sourceDir = getcwd();
244
        }
245
        if (!is_dir($sourceDir)) {
246
            throw new \InvalidArgumentException(sprintf("'%s' is not a valid source directory.", $sourceDir));
247
        }
248
        $this->sourceDir = $sourceDir;
249
250
        return $this;
251
    }
252
253
    /**
254
     * Get source directory.
255
     *
256
     * @return string
257
     */
258
    public function getSourceDir()
259
    {
260
        return $this->sourceDir;
261
    }
262
263
    /**
264
     * Set destination directory.
265
     *
266
     * @param null $destinationDir
267
     *
268
     * @throws Exception
269
     *
270
     * @return $this
271
     */
272 View Code Duplication
    public function setDestinationDir($destinationDir = null)
273
    {
274
        if ($destinationDir === null) {
275
            $destinationDir = $this->sourceDir;
276
        }
277
        if (!is_dir($destinationDir)) {
278
            throw new \InvalidArgumentException(sprintf("'%s' is not a valid destination directory.", $destinationDir));
279
        }
280
        $this->destinationDir = $destinationDir;
281
282
        return $this;
283
    }
284
285
    /**
286
     * Get destination directory.
287
     *
288
     * @return string
289
     */
290
    public function getDestinationDir()
291
    {
292
        return $this->destinationDir;
293
    }
294
295
    /**
296
     * Path helpers.
297
     */
298
299
    /**
300
     * Return content directory path.
301
     *
302
     * @return string
303
     */
304
    public function getContentPath()
305
    {
306
        return $this->getSourceDir().'/'.$this->get('content.dir');
307
    }
308
309
    /**
310
     * Return templates directory path.
311
     *
312
     * @return string
313
     */
314
    public function getLayoutsPath()
315
    {
316
        return $this->getSourceDir().'/'.$this->get('layouts.dir');
317
    }
318
319
    /**
320
     * Return themes directory path.
321
     *
322
     * @return string
323
     */
324
    public function getThemesPath()
325
    {
326
        return $this->getSourceDir().'/'.$this->get('themes.dir');
327
    }
328
329
    /**
330
     * Return internal templates directory path.
331
     *
332
     * @return string
333
     */
334
    public function getInternalLayoutsPath()
335
    {
336
        return __DIR__.'/../'.$this->get('layouts.internal.dir');
337
    }
338
339
    /**
340
     * Return output directory path.
341
     *
342
     * @return string
343
     */
344
    public function getOutputPath()
345
    {
346
        return $this->getSourceDir().'/'.$this->get('output.dir');
347
    }
348
349
    /**
350
     * Return static files directory path.
351
     *
352
     * @return string
353
     */
354
    public function getStaticPath()
355
    {
356
        return $this->getSourceDir().'/'.$this->get('static.dir');
357
    }
358
359
    /**
360
     * Themes helpers.
361
     */
362
363
    /**
364
     * Return theme(s).
365
     *
366
     * @return array|null
367
     */
368
    public function getTheme()
369
    {
370
        if ($themes = $this->get('theme')) {
371
            if (is_array($themes)) {
372
                return $themes;
373
            }
374
375
            return [$themes];
376
        }
377
    }
378
379
    /**
380
     * Has a (valid) theme(s)?
381
     *
382
     * @throws Exception
383
     *
384
     * @return bool
385
     */
386
    public function hasTheme()
387
    {
388
        if ($themes = $this->getTheme()) {
389
            foreach ($themes as $theme) {
390
                if (!Util::getFS()->exists($this->getThemeDirPath($theme, 'layouts'))) {
391
                    throw new Exception(sprintf(
392
                        "Theme directory '%s/%s/layouts' not found!",
393
                        $this->getThemesPath(),
394
                        $theme
395
                    ));
396
                }
397
            }
398
399
            return true;
400
        }
401
402
        return false;
403
    }
404
405
    /**
406
     * Return the path of a specific theme's directory.
407
     *
408
     * @param string $theme
409
     * @param string $dir
410
     *
411
     * @return string
412
     */
413
    public function getThemeDirPath($theme, $dir = 'layouts')
414
    {
415
        return $this->getThemesPath().'/'.$theme.'/'.$dir;
416
    }
417
}
418