Completed
Push — master ( 3c24ea...404feb )
by Sam
02:45
created

Parser::parseConfiguration()   C

Complexity

Conditions 7
Paths 5

Size

Total Lines 49
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 3
Bugs 0 Features 1
Metric Value
c 3
b 0
f 1
dl 0
loc 49
ccs 0
cts 32
cp 0
rs 6.7272
cc 7
eloc 26
nc 5
nop 1
crap 56
1
<?php
2
3
namespace Jalle19\StatusManager\Configuration;
4
5
use Jalle19\StatusManager\Exception\InvalidConfigurationException;
6
use Symfony\Component\Console\Input\InputInterface;
7
use Symfony\Component\Yaml\Exception\ParseException;
8
use Symfony\Component\Yaml\Yaml;
9
10
/**
11
 * Class Parser
12
 * @package   Jalle19\StatusManager\Configuration
13
 * @copyright Copyright &copy; Sam Stenvall 2016-
14
 * @license   https://www.gnu.org/licenses/gpl.html The GNU General Public License v2.0
15
 */
16
class Parser
17
{
18
19
	/**
20
	 * Parses the application configuration
21
	 *
22
	 * @param InputInterface $input
23
	 *
24
	 * @return Configuration the parsed configuration
25
	 * @throws InvalidConfigurationException if the configuration contains unrecoverable errors
26
	 */
27
	public static function parseConfiguration(InputInterface $input)
28
	{
29
		self::validateArguments($input);
30
31
		$configFile   = $input->getArgument('configFile');
32
		$databaseFile = $input->getArgument('databaseFile');
33
		$logFile      = $input->getArgument('logFile');
34
35
		// Parse the configuration file
36
		try
37
		{
38
			$configuration = Yaml::parse(file_get_contents($configFile));
39
		}
40
		catch (ParseException $e)
41
		{
42
			throw new InvalidConfigurationException('Failed to parse the specified configuration file: ' . $e->getMessage());
43
		}
44
45
		// Validate the configuration
46
		if (!isset($configuration['instances']) || empty($configuration['instances']))
47
			throw new InvalidConfigurationException('No instances defined, you need to specify at least one instance');
48
49
		if (!isset($configuration['access_token']) || empty($configuration['access_token']))
50
			throw new InvalidConfigurationException('No access token defined');
51
52
		$instances   = [];
53
		$accessToken = $configuration['access_token'];
54
55
		// Parse instances
56
		foreach ($configuration['instances'] as $name => $options)
57
			$instances[] = self::parseInstance($name, $options);
58
59
		// Create the configuration object
60
		$config = new Configuration($databaseFile, $instances, $accessToken);
61
62
		// Parse options
63
		$updateInterval = floatval($input->getOption(Configuration::OPTION_UPDATE_INTERVAL));
64
		$config->setUpdateInterval($updateInterval);
65
66
		$listenAddress = $input->getOption(Configuration::OPTION_LISTEN_ADDRESS);
67
		$config->setListenAddress($listenAddress);
68
69
		$listenPort = $input->getOption(Configuration::OPTION_LISTEN_PORT);
70
		$config->setListenPort($listenPort);
71
72
		$config->setLogPath($logFile);
73
74
		return $config;
75
	}
76
77
78
	/**
79
	 * @param InputInterface $input
80
	 *
81
	 * @throws InvalidConfigurationException if the arguments are invalid
82
	 */
83
	private static function validateArguments(InputInterface $input)
84
	{
85
		$configFile   = $input->getArgument('configFile');
86
		$databasePath = $input->getArgument('databaseFile');
87
		$logFile      = $input->getArgument('logFile');
88
89
		// Check that the configuration file exists
90
		if (!file_exists($configFile))
91
			throw new InvalidConfigurationException('The specified configuration file does not exist');
92
93
		// Check that the database exists and is writable
94
		if (!file_exists($databasePath))
95
			throw new InvalidConfigurationException('The specified database path does not exist');
96
		else if (!is_writable($databasePath))
97
			throw new InvalidConfigurationException('The specified database path is not writable');
98
99
		// Check that the directory of the log file path is writable
100
		if ($logFile !== null && !is_writable(dirname($logFile)))
101
			throw new InvalidConfigurationException('The specified log file path is not writable');
102
	}
103
104
105
	/**
106
	 * @param string $name the name of the instance
107
	 * @param array  $options
108
	 *
109
	 * @return Instance
110
	 */
111
	private static function parseInstance($name, $options)
112
	{
113
		$address = $options['address'];
114
		$port    = intval($options['port']);
115
116
		$instance = new Instance($name, $address, $port);
117
118
		// Optionally set ignored users
119
		if (isset($options['ignoredUsers']))
120
			$instance->setIgnoredUsers($options['ignoredUsers']);
121
122
		// Optionally set credentials
123
		if (isset($options['username']) && isset($options['password']))
124
			$instance->setCredentials($options['username'], $options['password']);
125
126
		return $instance;
127
	}
128
129
}
130