IniFileLoader   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 158
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 4
Bugs 2 Features 1
Metric Value
c 4
b 2
f 1
dl 0
loc 158
wmc 19
lcom 1
cbo 3
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A assertNoNestedArray() 0 9 2
A import() 0 12 1
A write() 0 11 2
A appendString() 0 21 4
A normalizeString() 0 10 3
A normalize() 0 13 3
B mapValueType() 0 22 4
1
<?php
2
/*
3
 * This file is part of the Borobudur-Config package.
4
 *
5
 * (c) Hexacodelabs <http://hexacodelabs.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Borobudur\Config\FileLoader;
12
13
use Borobudur\Config\Exception\Exception;
14
15
/**
16
 * @author      Iqbal Maulana <[email protected]>
17
 * @created     8/12/15
18
 */
19
class IniFileLoader extends AbstractFileLoader
20
{
21
    /**
22
     * @var array
23
     */
24
    protected $extensions = array('ini', 'env');
25
26
    /**
27
     * Assert that value can't be nested array.
28
     *
29
     * @param string $parent
30
     * @param string $child
31
     * @param mixed  $value
32
     *
33
     * @throws Exception
34
     */
35
    private static function assertNoNestedArray($parent, $child, $value)
36
    {
37
        if (is_array($value)) {
38
            throw new Exception(sprintf(
39
                'Extension .ini cannot use nested array on "%s".',
40
                $parent . '.' . $child
41
            ));
42
        }
43
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    public function import(FileLocator $file)
49
    {
50
        $this->validateExtension($file->getExtension());
51
52
        $content = str_replace(array('false', 'FALSE'), array('"(bool)false"'), $file->readFile());
53
        $content = str_replace(array('true', 'TRUE'), array('"(bool)true"'), $content);
54
        $content = str_replace(array('null', 'NULL'), array('"(null)"'), $content);
55
56
        $configs = $this->normalize(array_filter(parse_ini_string($content, true)));
57
58
        return $this->normalize($configs);
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64
    public function write(array $configs, $file)
65
    {
66
        $this->validateExtension(pathinfo($file, PATHINFO_EXTENSION));
67
68
        $str = '';
69
        foreach ($configs as $name => $value) {
70
            $this->appendString($str, $name, $value);
71
        }
72
73
        file_put_contents($file, ltrim($str, "\n"));
74
    }
75
76
    /**
77
     * Append string from data.
78
     *
79
     * @param string $str
80
     * @param string $name
81
     * @param mixed  $value
82
     *
83
     * @throws Exception
84
     */
85
    private function appendString(&$str, $name, $value)
86
    {
87
        if (is_array($value)) {
88
            $section = false;
89
            foreach ($value as $n => $v) {
90
                self::assertNoNestedArray($name, $n, $v);
91
92
                if (false === $section) {
93
                    $section = true;
94
                    $str .= "\n\n";
95
                    $str .= sprintf('[%s]', $name);
96
                }
97
98
                $str .= $this->normalizeString($n, $v);
99
            }
100
101
            return;
102
        }
103
104
        $str .= $this->normalizeString($name, $value);
105
    }
106
107
    /**
108
     * Normalize string.
109
     *
110
     * @param string $name
111
     * @param string $value
112
     *
113
     * @return string
114
     */
115
    private function normalizeString($name, $value)
116
    {
117
        if (false === $value) {
118
            $value = 'false';
119
        } elseif (true === $value) {
120
            $value = 'true';
121
        }
122
123
        return "\n" . sprintf('%s=%s', $name, $value);
124
    }
125
126
    /**
127
     * Normalize array config.
128
     *
129
     * @param array $configs
130
     *
131
     * @return array
132
     */
133
    private function normalize(array $configs)
134
    {
135
        foreach ($configs as $index => $config) {
136
            if (is_array($config)) {
137
                $configs[$index] = $this->normalize($config);
138
                continue;
139
            }
140
141
            $configs[$index] = $this->mapValueType($config);
142
        }
143
144
        return $configs;
145
    }
146
147
    /**
148
     * Mapping type of value.
149
     *
150
     * @param string $value
151
     *
152
     * @return mixed
153
     */
154
    private function mapValueType($value)
155
    {
156
        $maps = array(
157
            '(bool)false' => false,
158
            '(bool)true'  => true,
159
            '(null)'      => null,
160
        );
161
162
        if (array_key_exists((string) $value, $maps)) {
163
            return $maps[$value];
164
        }
165
166
        if (is_numeric($value)) {
167
            if (preg_match('/^\d+$/', $value)) {
168
                return (int) $value;
169
            }
170
171
            return (float) $value;
172
        }
173
174
        return $value;
175
    }
176
}
177