Completed
Push — master ( 6167e8...c23e1b )
by Sam
02:58
created

Parser::parseMagicComment()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace Jalle19\HaPHProxy;
4
5
use Jalle19\HaPHProxy\Exception\FileNotFoundException;
6
use Jalle19\HaPHProxy\Parameter\Parameter;
7
use Jalle19\HaPHProxy\Section\AbstractSection;
8
use Jalle19\HaPHProxy\Section\Factory;
9
10
/**
11
 * Class Parser
12
 * @package Jalle19\HaPHProxy
13
 * @author  Sam Stenvall <[email protected]>
14
 * @license GNU General Public License 2.0+
15
 */
16
class Parser
17
{
18
19
	const MAGIC_COMMENT_PREFIX = '# HAPHPROXY_COMMENT';
20
21
	/**
22
	 * @var string
23
	 */
24
	private $filePath;
25
26
27
	/**
28
	 * Parser constructor.
29
	 *
30
	 * @param string $filePath
31
	 *
32
	 * @throws FileNotFoundException if the specified file could not be found or is not readable
33
	 */
34
	public function __construct($filePath)
35
	{
36
		if (!file_exists($filePath) || !is_readable($filePath)) {
37
			throw new FileNotFoundException($filePath . ' not found or is not readable');
38
		}
39
40
		$this->filePath = $filePath;
41
	}
42
43
44
	/**
45
	 * @return Configuration
46
	 */
47
	public function parse()
48
	{
49
		$configuration = new Configuration();
50
		$preface       = '';
51
52
		/* @var AbstractSection|null $currentSection */
53
		$currentSection = null;
54
55
		foreach ($this->getNormalizedConfigurationLines() as $line) {
56
			// Parse preface
57
			if ($currentSection === null && self::isComment($line)) {
58
				$preface .= $line . PHP_EOL;
59
			}
60
61
			// Omit empty lines
62
			if (empty($line)) {
63
				continue;
64
			}
65
66
			// Check for section changes
67
			$newSection = Factory::makeFactory($line);
68
69
			if ($newSection !== null) {
70
				$currentSection = $newSection;
71
				$configuration->addSection($currentSection);
72
73
				continue;
74
			}
75
76
			// Parse parameters into the current section
77
			if ($currentSection !== null) {
78
				// Distinguish between parameters and magic comments
79
				if (self::isMagicComment($line)) {
80
					$currentSection->addMagicComment(self::parseMagicComment($line));
81
				} else if (!self::isComment($line)) {
82
					$currentSection->addParameter(self::parseParameter($line));
83
				}
84
			}
85
		}
86
87
		if (!empty($preface)) {
88
			$configuration->setPreface($preface);
89
		}
90
91
		return $configuration;
92
	}
93
94
95
	/**
96
	 * Reads the configuration and yields one line at a time
97
	 *
98
	 * @return \Generator
99
	 */
100
	private function getConfigurationLines()
101
	{
102
		$handle = fopen($this->filePath, "r");
103
104
		while (($line = fgets($handle)) !== false) {
105
			yield $line;
106
		}
107
	}
108
109
110
	/**
111
	 * @return \Generator
112
	 */
113
	private function getNormalizedConfigurationLines()
114
	{
115
		foreach ($this->getConfigurationLines() as $line) {
116
			yield self::normalizeLine($line);
117
		}
118
	}
119
120
121
	/**
122
	 * @param string $line
123
	 *
124
	 * @return string
125
	 */
126
	private static function normalizeLine($line)
127
	{
128
		return preg_replace('/\s+/', ' ', trim($line));
129
	}
130
131
132
	/**
133
	 * @param string $line
134
	 *
135
	 * @return bool if the line is a comment
136
	 */
137
	private static function isComment($line)
138
	{
139
		return substr($line, 0, 1) === '#';
140
	}
141
142
143
	/**
144
	 * @param string $line
145
	 *
146
	 * @return bool whether the line is a magic comment
147
	 */
148
	private static function isMagicComment($line)
149
	{
150
		return substr($line, 0, strlen(self::MAGIC_COMMENT_PREFIX)) === self::MAGIC_COMMENT_PREFIX;
151
	}
152
153
154
	/**
155
	 * @param string $line
156
	 *
157
	 * @return string
158
	 */
159
	private static function parseMagicComment($line)
160
	{
161
		return trim(substr($line, strlen(self::MAGIC_COMMENT_PREFIX)));
162
	}
163
164
165
	/**
166
	 * @param string $line
167
	 *
168
	 * @return Parameter
169
	 */
170
	private static function parseParameter($line)
171
	{
172
		$words = explode(' ', $line, 2);
173
174
		if (count($words) > 1) {
175
			list($name, $value) = $words;
176
177
			return new Parameter($name, $value);
178
		}
179
180
		list($name) = $words;
181
182
		return new Parameter($name);
183
	}
184
185
}
186