Config   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 129
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 5
Bugs 0 Features 1
Metric Value
wmc 17
c 5
b 0
f 1
lcom 1
cbo 3
dl 0
loc 129
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 2
A offsetExists() 0 4 1
A offsetGet() 0 15 2
A offsetSet() 0 4 1
A offsetUnset() 0 4 1
C readConfig() 0 23 7
A normalizePath() 0 15 3
1
<?php
2
3
namespace Cauditor;
4
5
use MatthiasMullie\PathConverter\Converter as PathConverter;
6
use Symfony\Component\Yaml\Exception\ParseException;
7
use Symfony\Component\Yaml\Parser;
8
9
/**
10
 * @author Matthias Mullie <[email protected]>
11
 * @copyright Copyright (c) 2016, Matthias Mullie. All rights reserved.
12
 * @license LICENSE MIT
13
 */
14
class Config implements \ArrayAccess
15
{
16
    /**
17
     * @var array
18
     */
19
    protected $config = array();
20
21
    /**
22
     * @var array
23
     */
24
    protected $defaults = array(
25
        'build_path' => 'build/cauditor',
26
        'exclude_folders' => array('tests', 'vendor'),
27
    );
28
29
    /**
30
     * List of config keys that denote paths, so they can be normalized
31
     * (= turned into "relative to project root" instead of "relative to config
32
     * file").
33
     *
34
     * @var string[]
35
     */
36
    protected $paths = array('build_path', 'exclude_folders');
37
38
    /**
39
     * @param string $project Project root path.
40
     * @param string $config  Config YML file path.
41
     */
42
    public function __construct($project, $config = null)
43
    {
44
        $this->config['path'] = rtrim($project, DIRECTORY_SEPARATOR);
45
        $this->config['config_path'] = $config ? rtrim($config, DIRECTORY_SEPARATOR) : null;
46
    }
47
48
    /**
49
     * {@inheritdoc.
50
     */
51
    public function offsetExists($offset)
52
    {
53
        return $this->offsetGet($offset) !== null;
54
    }
55
56
    /**
57
     * {@inheritdoc.
58
     */
59
    public function offsetGet($offset)
60
    {
61
        $path = $this->config['config_path'];
62
        $config = $this->config + $this->readConfig($path) + $this->defaults;
63
64
        // *always* exclude some folders - they're not project-specific code and
65
        // could easily be overlooked when overriding excludes
66
        $config['exclude_folders'][] = 'vendor';
67
        $config['exclude_folders'][] = '.git';
68
        $config['exclude_folders'][] = '.svn';
69
        $config['exclude_folders'][] = $config['build_path'];
70
        $config['exclude_folders'] = array_unique($config['exclude_folders']);
71
72
        return isset($config[$offset]) ? $config[$offset] : null;
73
    }
74
75
    /**
76
     * {@inheritdoc.
77
     */
78
    public function offsetSet($offset, $value)
79
    {
80
        throw new Exception('Can not set config.');
81
    }
82
83
    /**
84
     * {@inheritdoc.
85
     */
86
    public function offsetUnset($offset)
87
    {
88
        throw new Exception('Can not unset config.');
89
    }
90
91
    /**
92
     * @param string $path Path to config file.
93
     *
94
     * @return array
95
     */
96
    protected function readConfig($path)
97
    {
98
        if (!file_exists($path) || !is_file($path) || !is_readable($path)) {
99
            return array();
100
        }
101
102
        $yaml = new Parser();
103
104
        try {
105
            $config = (array) $yaml->parse(file_get_contents($path));
106
        } catch (ParseException $e) {
107
            return array();
108
        }
109
110
        // adjust relative paths
111
        foreach ($this->paths as $key) {
112
            if (isset($config[$key])) {
113
                $config[$key] = $this->normalizePath($config[$key]);
114
            }
115
        }
116
117
        return $config;
118
    }
119
120
    /**
121
     * Normalize all relative paths by prefixing them with the project path.
122
     *
123
     * @param string|string[] $value
124
     *
125
     * @return string|string[]
126
     */
127
    protected function normalizePath($value)
128
    {
129
        // array of paths = recursive
130
        if (is_array($value)) {
131
            foreach ($value as $i => $val) {
132
                $value[$i] = $this->normalizePath($val);
133
            }
134
135
            return $value;
136
        }
137
138
        $converter = new PathConverter(dirname($this->config['config_path']), $this->config['path']);
139
140
        return $converter->convert($value);
141
    }
142
}
143