Passed
Push — master ( a3db06...6080f3 )
by Sebastian
03:13
created

INILine::isSection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
/**
3
 * File containing the {@link \AppUtils\IniHelper\INILine} class.
4
 * @package Application Utils
5
 * @subpackage IniHelper
6
 * @see \AppUtils\IniHelper\INILine
7
 */
8
9
declare(strict_types=1);
10
11
namespace AppUtils\IniHelper;
12
13
use AppUtils\IniHelper_Exception;
14
use function AppUtils\parseVariable;
15
16
/**
17
 * Single INI line container.
18
 *
19
 * @package Application Utils
20
 * @subpackage IniHelper
21
 * @author Sebastian Mordziol <[email protected]>
22
 */
23
class INILine
24
{
25
    public const TYPE_SECTION_DECLARATION = 'section';
26
    public const TYPE_COMMENT = 'comment';
27
    public const TYPE_EMPTY = 'empty';
28
    public const TYPE_INVALID = 'invalid';
29
    public const TYPE_VALUE = 'value';
30
    
31
    public const ERROR_UNHANDLED_LINE_TYPE = 41901;
32
    public const ERROR_NON_SCALAR_VALUE = 41902;
33
    
34
    protected string $text;
35
    protected string $trimmed;
36
    protected int $lineNumber;
37
    protected string $type;
38
    protected string $varName = '';
39
    protected string $varValue = '';
40
    protected string $valueUnquoted = '';
41
    protected string $quoteStyle = '';
42
    protected string $sectionName = '';
43
    
44
    public function __construct(string $text, int $lineNumber)
45
    {
46
        $this->text = $text;
47
        $this->trimmed = trim($text);
48
        $this->lineNumber = $lineNumber;
49
        
50
        if(empty($this->trimmed)) 
51
        {
52
            $this->type = self::TYPE_EMPTY;
53
            return;
54
        }
55
        
56
        $startChar = $this->trimmed[0];
57
        
58
        if($startChar === ';')
59
        {
60
            $this->type = self::TYPE_COMMENT;
61
        }
62
        else if($startChar === '[')
63
        {
64
            $this->type = self::TYPE_SECTION_DECLARATION;
65
            $this->sectionName = trim($this->trimmed, '[]');
66
            $this->sectionName = trim($this->sectionName); // remove any whitespace
67
        }
68
        else
69
        {
70
            $pos = strpos($this->trimmed, '=');
71
            if($pos === false) 
72
            {
73
                $this->type = self::TYPE_INVALID;
74
                return;
75
            }
76
            
77
            $this->type = self::TYPE_VALUE;
78
            $this->varName = trim(substr($this->trimmed, 0, $pos));
79
            
80
            $this->parseValue(substr($this->trimmed, $pos+1));
81
        }
82
    }
83
    
84
    protected function parseValue(string $value) : void
85
    {
86
        $this->varValue = trim($value);
87
        $value = $this->varValue;
88
89
        if(empty($value)) {
90
            return;
91
        }
92
        
93
        if($value[0] === '"' && $value[strlen($value) - 1] === '"')
94
        {
95
            $value = trim($value, '"');
96
            $this->quoteStyle = '"';
97
        }
98
        else if($value[0] === "'" && $value[strlen($value) - 1] === "'")
99
        {
100
            $value = trim($value, "'");
101
            $this->quoteStyle = "'";
102
        }
103
        
104
        $this->valueUnquoted = $value;
105
    }
106
    
107
    public function getVarName() : string
108
    {
109
        return $this->varName;
110
    }
111
    
112
    public function getVarValue() : string
113
    {
114
        return $this->valueUnquoted;
115
    }
116
    
117
    public function getQuotedVarValue() : string
118
    {
119
        if($this->quoteStyle === '') {
120
            return $this->getVarValue();
121
        }
122
        
123
        return $this->quoteStyle.$this->getVarValue().$this->quoteStyle;
124
    }
125
    
126
    public function getText() : string
127
    {
128
        return $this->text;
129
    }
130
    
131
    public function getLineNumber() : int
132
    {
133
        return $this->lineNumber;
134
    }
135
    
136
    public function getSectionName() : string
137
    {
138
        return $this->sectionName;
139
    }
140
    
141
    public function isSection() : bool
142
    {
143
        return $this->isType(self::TYPE_SECTION_DECLARATION);
144
    }
145
    
146
    public function isComment() : bool
147
    {
148
        return $this->isType(self::TYPE_COMMENT);
149
    }
150
    
151
    public function isValue() : bool
152
    {
153
        return $this->isType(self::TYPE_VALUE);
154
    }
155
    
156
    public function isValid() : bool
157
    {
158
        return !$this->isType(self::TYPE_INVALID);
159
    }
160
    
161
    public function isEmpty() : bool
162
    {
163
        return $this->isType(self::TYPE_EMPTY);
164
    }
165
    
166
    protected function isType(string $type) : bool
167
    {
168
        return $this->type === $type;
169
    }
170
171
    /**
172
     * @param mixed|NULL $value
173
     * @return $this
174
     * @throws IniHelper_Exception
175
     */
176
    public function setValue($value) : INILine
177
    {
178
        if(!is_null($value) && !is_scalar($value))
179
        {
180
            throw new IniHelper_Exception(
181
                'Cannot use non-scalar values.',
182
                sprintf(
183
                    'Tried setting the value of [%s] to [%s]',
184
                    $this->getVarName(),
185
                    parseVariable($value)->toString()
186
                ),
187
                self::ERROR_NON_SCALAR_VALUE
188
            );
189
        }
190
        
191
        $this->parseValue((string)$value);
192
        
193
        return $this;
194
    }
195
    
196
    public function toString() : string
197
    {
198
        switch($this->type) 
199
        {
200
            case self::TYPE_EMPTY:
201
            case self::TYPE_INVALID:
202
                return '';
203
                
204
            case self::TYPE_COMMENT:
205
                return $this->text;
206
                
207
            case self::TYPE_SECTION_DECLARATION:
208
                return '['.$this->getSectionName().']';
209
                
210
            case self::TYPE_VALUE:
211
                return $this->getVarName().'='.$this->getQuotedVarValue();
212
        }
213
        
214
        throw new IniHelper_Exception(
215
            'Unhandled line type',
216
            sprintf(
217
                'The line type [%s] is not handled for converting to string.',
218
                $this->type
219
            ),
220
            self::ERROR_UNHANDLED_LINE_TYPE
221
        );
222
    }
223
}
224