Completed
Push — master ( 922581...16cdba )
by Michael
02:34
created

SubmitControllerCreate::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Stats\Controllers;
4
5
use Joomla\Controller\AbstractController;
6
use Stats\Models\StatsModel;
7
8
/**
9
 * Controller for processing submitted statistics data.
10
 *
11
 * @method         \Stats\Application  getApplication()  Get the application object.
12
 * @property-read  \Stats\Application  $app              Application object
13
 *
14
 * @since          1.0
15
 */
16
class SubmitControllerCreate extends AbstractController
17
{
18
	/**
19
	 * Statistics model object.
20
	 *
21
	 * @var    StatsModel
22
	 * @since  1.0
23
	 */
24
	private $model;
25
26
	/**
27
	 * Allowed Database Types.
28
	 *
29
	 * @var    array
30
	 * @since  1.0
31
	 */
32
	private $databaseTypes = [
33
		'mysql',
34
		'mysqli',
35
		'pdomysql',
36
		'postgresql',
37
		'sqlazure',
38
		'sqlsrv',
39
	];
40
41
	/**
42
	 * Constructor.
43
	 *
44
	 * @param   StatsModel  $model  Statistics model object.
45
	 *
46
	 * @since   1.0
47
	 */
48 1
	public function __construct(StatsModel $model)
49
	{
50 1
		$this->model = $model;
51 1
	}
52
53
	/**
54
	 * Execute the controller.
55
	 *
56
	 * @return  boolean
57
	 *
58
	 * @since   1.0
59
	 */
60 2
	public function execute()
61
	{
62 2
		$input = $this->getInput();
63
64
		$data = [
65 2
			'php_version' => $input->getRaw('php_version'),
66 2
			'db_version'  => $input->getRaw('db_version'),
67 2
			'cms_version' => $input->getRaw('cms_version'),
68 2
			'unique_id'   => $input->getString('unique_id'),
69 2
			'db_type'     => $input->getString('db_type'),
70 2
			'server_os'   => $input->getString('server_os')
71 2
		];
72
73
		// Backup the original POST before manipulating/validating data
74 2
		$originalData = $data;
75
76
		// Validate the submitted data
77 2
		$data['php_version'] = $this->checkPHPVersion($data['php_version']);
78 2
		$data['cms_version'] = $this->checkCMSVersion($data['cms_version']);
79 2
		$data['db_type']     = $this->checkDatabaseType($data['db_type']);
80 2
		$data['db_version']  = $this->validateVersionNumber($data['db_version']);
81
82
		// We require at a minimum a unique ID and the CMS version
83 2
		if (empty($data['unique_id']) || empty($data['cms_version']))
84 2
		{
85 1
			$this->getApplication()->getLogger()->info(
86 1
				'Missing required data from request.',
87 1
				['postData' => $originalData]
88 1
			);
89
90
			$response = [
91 1
				'error'   => true,
92
				'message' => 'There was an error storing the data.'
93 1
			];
94
95 1
			$this->getApplication()->setHeader('HTTP/1.1 500 Internal Server Error', 500, true);
96 1
			$this->getApplication()->setBody(json_encode($response));
97
	
98 1
			return true;
99
		}
100
101
		// If the below data does not pass tests, we do not accept the POST
102 1
		if ($data['php_version'] === false || $data['cms_version'] === false || $data['db_type'] === false || $data['db_version'] === false)
103 1
		{
104
			$response = [
105
				'error'   => true,
106
				'message' => 'Invalid data submission.'
107
			];
108
	
109
			$this->getApplication()->setHeader('HTTP/1.1 500 Internal Server Error', 500, true);
110
			$this->getApplication()->setBody(json_encode($response));
111
	
112
			return true;
113
		}
114
115 1
		$this->model->save((object) $data);
116
117
		$response = [
118 1
			'error'   => false,
119
			'message' => 'Data saved successfully'
120 1
		];
121
122 1
		$this->getApplication()->setBody(json_encode($response));
123
124 1
		return true;
125
	}
126
127
	/**
128
	 * Check the CMS version.
129
	 *
130
	 * @param   string  $version  The version number to check.
131
	 *
132
	 * @return  string|boolean  The version number on success or boolean false on failure.
133
	 *
134
	 * @since   1.0
135
	 */
136 2
	private function checkCMSVersion($version)
137
	{
138 2
		$version = $this->validateVersionNumber($version);
139
140
		// If the version number is invalid, don't go any further
141 2
		if ($version === false)
142 2
		{
143 1
			return false;
144
		}
145
146
		// We are only collecting data for the 3.x series
147 1
		if (version_compare($version, '3.0.0', '<') || version_compare($version, '4.0.0', '>='))
148 1
		{
149
			return false;
150
		}
151
152 1
		return $version;
153
	}
154
155
	/**
156
	 * Check the database type
157
	 *
158
	 * @param   string  $database  The database type to check.
159
	 *
160
	 * @return  string|boolean  The database type on success or boolean false on failure.
161
	 *
162
	 * @since   1.0
163
	 */
164 2
	private function checkDatabaseType($database)
165
	{
166 2
		if (!in_array($database, $this->databaseTypes))
167 2
		{
168
			return false;
169
		}
170
171 2
		return $database;
172
	}
173
174
	/**
175
	 * Check the PHP version
176
	 *
177
	 * @param   string  $version  The version number to check.
178
	 *
179
	 * @return  string|boolean  The version number on success or boolean false on failure.
180
	 *
181
	 * @since   1.0
182
	 */
183 2
	private function checkPHPVersion($version)
184
	{
185 2
		$version = $this->validateVersionNumber($version);
186
187
		// If the version number is invalid, don't go any further
188 2
		if ($version === false)
189 2
		{
190
			return false;
191
		}
192
193 2
		$majorVersion = substr($version, 0, 1);
194
195
		// The version string should meet the minimum supported PHP version for 3.0.0 and be a released PHP version
196 2
		if (version_compare($version, '5.3.1', '<') || version_compare($version, '8.0.0', '>=') || $majorVersion == 6)
197 2
		{
198
			return false;
199
		}
200
201 2
		return $version;
202
	}
203
204
	/**
205
	 * Validates and filters the version number
206
	 *
207
	 * @param   string  $version  The version string to validate.
208
	 *
209
	 * @return  string|boolean  A validated version number on success or boolean false.
210
	 *
211
	 * @since   1.0
212
	 */
213 2
	private function validateVersionNumber($version)
214
	{
215 2
		return preg_match('/\d+(?:\.\d+)+/', $version, $matches) ? $matches[0] : false;
216
	}
217
}
218