Completed
Push — master ( 600e8c...3dfec0 )
by Sam
02:51
created

Parser   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 5

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 15
c 2
b 0
f 0
lcom 0
cbo 5
dl 0
loc 110
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
B parseConfiguration() 0 45 5
B validateArguments() 0 20 6
A parseInstance() 0 17 4
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. We need at least one instance.
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
		$instances = [];
50
51
		// Parse instances
52
		foreach ($configuration['instances'] as $name => $options)
53
			$instances[] = self::parseInstance($name, $options);
54
55
		// Create the configuration object
56
		$config = new Configuration($databaseFile, $instances);
57
58
		// Parse options
59
		$updateInterval = floatval($input->getOption(Configuration::OPTION_UPDATE_INTERVAL));
60
		$config->setUpdateInterval($updateInterval);
61
62
		$listenAddress = $input->getOption(Configuration::OPTION_LISTEN_ADDRESS);
63
		$config->setListenAddress($listenAddress);
64
65
		$listenPort = $input->getOption(Configuration::OPTION_LISTEN_PORT);
66
		$config->setListenPort($listenPort);
67
68
		$config->setLogPath($logFile);
69
70
		return $config;
71
	}
72
73
74
	/**
75
	 * @param InputInterface $input
76
	 *
77
	 * @throws InvalidConfigurationException if the arguments are invalid
78
	 */
79
	private static function validateArguments(InputInterface $input)
80
	{
81
		$configFile   = $input->getArgument('configFile');
82
		$databasePath = $input->getArgument('databaseFile');
83
		$logFile      = $input->getArgument('logFile');
84
85
		// Check that the configuration file exists
86
		if (!file_exists($configFile))
87
			throw new InvalidConfigurationException('The specified configuration file does not exist');
88
89
		// Check that the database exists and is writable
90
		if (!file_exists($databasePath))
91
			throw new InvalidConfigurationException('The specified database path does not exist');
92
		else if (!is_writable($databasePath))
93
			throw new InvalidConfigurationException('The specified database path is not writable');
94
95
		// Check that the directory of the log file path is writable
96
		if ($logFile !== null && !is_writable(dirname($logFile)))
97
			throw new InvalidConfigurationException('The specified log file path is not writable');
98
	}
99
100
101
	/**
102
	 * @param string $name the name of the instance
103
	 * @param array  $options
104
	 *
105
	 * @return Instance
106
	 */
107
	private static function parseInstance($name, $options)
108
	{
109
		$address = $options['address'];
110
		$port    = intval($options['port']);
111
112
		$instance = new Instance($name, $address, $port);
113
114
		// Optionally set ignored users
115
		if (isset($options['ignoredUsers']))
116
			$instance->setIgnoredUsers($options['ignoredUsers']);
117
118
		// Optionally set credentials
119
		if (isset($options['username']) && isset($options['password']))
120
			$instance->setCredentials($options['username'], $options['password']);
121
122
		return $instance;
123
	}
124
125
}
126