Completed
Push — master ( 437185...b9fa04 )
by Michael
05:34
created

SubmitControllerCreate::checkPHPVersion()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 36
Code Lines 14

Duplication

Lines 36
Ratio 100 %

Code Coverage

Tests 10
CRAP Score 5.583

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 36
loc 36
ccs 10
cts 14
cp 0.7143
rs 8.439
cc 5
eloc 14
nc 5
nop 1
crap 5.583
1
<?php
2
3
namespace Stats\Controllers;
4
5
use Joomla\Controller\AbstractController;
6
use Stats\Decorators\ValidateVersion;
7
use Stats\Models\StatsModel;
8
9
/**
10
 * Controller for processing submitted statistics data.
11
 *
12
 * @method         \Stats\WebApplication  getApplication()  Get the application object.
13
 * @property-read  \Stats\WebApplication  $app              Application object
14
 *
15
 * @since          1.0
16
 */
17
class SubmitControllerCreate extends AbstractController
18
{
19
	use ValidateVersion;
20
21
	/**
22
	 * Statistics model object.
23
	 *
24
	 * @var    StatsModel
25
	 * @since  1.0
26
	 */
27
	private $model;
28
29
	/**
30
	 * Allowed Database Types.
31
	 *
32
	 * @var    array
33
	 * @since  1.0
34
	 */
35
	private $databaseTypes = [
36
		'mysql',
37
		'mysqli',
38
		'pdomysql',
39
		'postgresql',
40
		'sqlazure',
41
		'sqlsrv',
42
	];
43
44
	/**
45
	 * Constructor.
46
	 *
47
	 * @param   StatsModel  $model  Statistics model object.
48
	 *
49
	 * @since   1.0
50
	 */
51 1
	public function __construct(StatsModel $model)
52
	{
53 1
		$this->model = $model;
54 1
	}
55
56
	/**
57
	 * Execute the controller.
58
	 *
59
	 * @return  boolean
60
	 *
61
	 * @since   1.0
62
	 */
63 3
	public function execute()
64
	{
65 3
		$input = $this->getInput();
66
67
		$data = [
68 3
			'php_version' => $input->getRaw('php_version'),
69 3
			'db_version'  => $input->getRaw('db_version'),
70 3
			'cms_version' => $input->getRaw('cms_version'),
71 3
			'unique_id'   => $input->getString('unique_id'),
72 3
			'db_type'     => $input->getString('db_type'),
73 3
			'server_os'   => $input->getString('server_os'),
74
		];
75
76
		// Backup the original POST before manipulating/validating data
77 3
		$originalData = $data;
78
79
		// Validate the submitted data
80 3
		$data['php_version'] = $this->checkPHPVersion($data['php_version']);
81 3
		$data['cms_version'] = $this->checkCMSVersion($data['cms_version']);
82 3
		$data['db_type']     = $this->checkDatabaseType($data['db_type']);
83 3
		$data['db_version']  = $this->validateVersionNumber($data['db_version']);
84
85
		// We require at a minimum a unique ID and the CMS version
86 3
		if (empty($data['unique_id']) || empty($data['cms_version']))
87
		{
88 2
			$this->getApplication()->getLogger()->info(
89 2
				'Missing required data from request.',
90 2
				['postData' => $originalData]
91
			);
92
93
			$response = [
94 2
				'error'   => true,
95
				'message' => 'There was an error storing the data.',
96
			];
97
98 2
			$this->getApplication()->setHeader('HTTP/1.1 500 Internal Server Error', 500, true);
99 2
			$this->getApplication()->setBody(json_encode($response));
100
101 2
			return true;
102
		}
103
104
		// If the below data does not pass tests, we do not accept the POST
105 1
		if ($data['php_version'] === false || $data['cms_version'] === false || $data['db_type'] === false || $data['db_version'] === false)
106
		{
107
			$response = [
108
				'error'   => true,
109
				'message' => 'Invalid data submission.',
110
			];
111
112
			$this->getApplication()->setHeader('HTTP/1.1 500 Internal Server Error', 500, true);
113
			$this->getApplication()->setBody(json_encode($response));
114
115
			return true;
116
		}
117
118 1
		$this->model->save((object) $data);
119
120
		$response = [
121 1
			'error'   => false,
122
			'message' => 'Data saved successfully',
123
		];
124
125 1
		$this->getApplication()->setBody(json_encode($response));
126
127 1
		return true;
128
	}
129
130
	/**
131
	 * Check the CMS version.
132
	 *
133
	 * @param   string  $version  The version number to check.
134
	 *
135
	 * @return  string|boolean  The version number on success or boolean false on failure.
136
	 *
137
	 * @since   1.0
138
	 */
139 3 View Code Duplication
	private function checkCMSVersion(string $version)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
140
	{
141 3
		$version = $this->validateVersionNumber($version);
142
143
		// If the version number is invalid, don't go any further
144 3
		if ($version === false)
145
		{
146 1
			return false;
147
		}
148
149
		// Joomla only uses major.minor.patch so everything else is invalid
150 2
		$explodedVersion = explode('.', $version);
151
152 2
		if (count($explodedVersion) > 3)
153
		{
154 1
			return false;
155
		}
156
157
		// Import the valid release listing
158 1
		$path = APPROOT . '/versions/joomla.json';
159
160 1
		if (!file_exists($path))
161
		{
162
			throw new \RuntimeException('Missing Joomla! release listing', 500);
163
		}
164
165 1
		$validVersions = json_decode(file_get_contents($path), true);
166
167
		// Check that the version is in our valid release list
168 1
		if (!in_array($version, $validVersions))
169
		{
170
			return false;
171
		}
172
173 1
		return $version;
174
	}
175
176
	/**
177
	 * Check the database type
178
	 *
179
	 * @param   string  $database  The database type to check.
180
	 *
181
	 * @return  string|boolean  The database type on success or boolean false on failure.
182
	 *
183
	 * @since   1.0
184
	 */
185 3
	private function checkDatabaseType(string $database)
186
	{
187 3
		if (!in_array($database, $this->databaseTypes))
188
		{
189
			return false;
190
		}
191
192 3
		return $database;
193
	}
194
195
	/**
196
	 * Check the PHP version
197
	 *
198
	 * @param   string  $version  The version number to check.
199
	 *
200
	 * @return  string|boolean  The version number on success or boolean false on failure.
201
	 *
202
	 * @since   1.0
203
	 */
204 3 View Code Duplication
	private function checkPHPVersion(string $version)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
205
	{
206 3
		$version = $this->validateVersionNumber($version);
207
208
		// If the version number is invalid, don't go any further
209 3
		if ($version === false)
210
		{
211
			return false;
212
		}
213
214
		// We only track versions based on major.minor.patch so everything else is invalid
215 3
		$explodedVersion = explode('.', $version);
216
217 3
		if (count($explodedVersion) > 3)
218
		{
219
			return false;
220
		}
221
222
		// Import the valid release listing
223 3
		$path = APPROOT . '/versions/php.json';
224
225 3
		if (!file_exists($path))
226
		{
227
			throw new \RuntimeException('Missing PHP release listing', 500);
228
		}
229
230 3
		$validVersions = json_decode(file_get_contents($path), true);
231
232
		// Check that the version is in our valid release list
233 3
		if (!in_array($version, $validVersions))
234
		{
235
			return false;
236
		}
237
238 3
		return $version;
239
	}
240
}
241