Completed
Push — mysql_improvements ( 2e95ce...dedbef )
by Michael
03:52
created

SubmitControllerCreate::execute()   C

Complexity

Conditions 9
Paths 5

Size

Total Lines 76
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 9.1442

Importance

Changes 0
Metric Value
dl 0
loc 76
ccs 29
cts 33
cp 0.8788
rs 5.8219
c 0
b 0
f 0
cc 9
eloc 40
nc 5
nop 0
crap 9.1442

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Joomla! Statistics Server
4
 *
5
 * @copyright  Copyright (C) 2013 - 2017 Open Source Matters, Inc. All rights reserved.
6
 * @license    http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
7
 */
8
9
namespace Joomla\StatsServer\Controllers;
10
11
use Joomla\Controller\AbstractController;
12
use Joomla\StatsServer\Decorators\ValidateVersion;
13
use Joomla\StatsServer\Models\StatsModel;
14
15
/**
16
 * Controller for processing submitted statistics data.
17
 *
18
 * @method         \Joomla\StatsServer\WebApplication  getApplication()  Get the application object.
19
 * @property-read  \Joomla\StatsServer\WebApplication  $app              Application object
20
 */
21
class SubmitControllerCreate extends AbstractController
22
{
23
	use ValidateVersion;
24
25
	/**
26
	 * Statistics model object.
27
	 *
28
	 * @var  StatsModel
29
	 */
30
	private $model;
31
32
	/**
33
	 * Allowed Database Types.
34
	 *
35
	 * @var  array
36
	 */
37
	private $databaseTypes = [
38
		'mysql',
39
		'mysqli',
40
		'pgsql',
41
		'pdomysql',
42
		'postgresql',
43
		'sqlazure',
44
		'sqlsrv',
45
	];
46
47
	/**
48
	 * Constructor.
49
	 *
50
	 * @param   StatsModel  $model  Statistics model object.
51
	 */
52 1
	public function __construct(StatsModel $model)
53
	{
54 1
		$this->model = $model;
55 1
	}
56
57
	/**
58
	 * Execute the controller.
59
	 *
60
	 * @return  boolean
61
	 */
62 4
	public function execute()
63
	{
64 4
		$input = $this->getInput();
65
66
		$data = [
67 4
			'php_version' => $input->getRaw('php_version', ''),
68 4
			'db_version'  => $input->getRaw('db_version', ''),
69 4
			'cms_version' => $input->getRaw('cms_version', ''),
70 4
			'unique_id'   => $input->getString('unique_id'),
71 4
			'db_type'     => $input->getString('db_type', ''),
72 4
			'server_os'   => $input->getString('server_os'),
73
		];
74
75
		// Backup the original POST before manipulating/validating data
76 4
		$originalData = $data;
77
78
		// Validate the submitted data
79 4
		$data['php_version'] = $this->checkPHPVersion($data['php_version']);
80 4
		$data['cms_version'] = $this->checkCMSVersion($data['cms_version']);
81 4
		$data['db_type']     = $this->checkDatabaseType($data['db_type']);
82 4
		$data['db_version']  = $this->validateVersionNumber($data['db_version']);
83
84
		// We require at a minimum a unique ID and the CMS version
85 4
		if (empty($data['unique_id']) || empty($data['cms_version']))
86
		{
87 2
			$this->getApplication()->getLogger()->info(
88 2
				'Missing required data from request.',
89 2
				['postData' => $originalData]
90
			);
91
92
			$response = [
93 2
				'error'   => true,
94
				'message' => 'There was an error storing the data.',
95
			];
96
97 2
			$this->getApplication()->setHeader('HTTP/1.1 500 Internal Server Error', 500, true);
98 2
			$this->getApplication()->setBody(json_encode($response));
99
100 2
			return true;
101
		}
102
103
		// If the below data does not pass tests, we do not accept the POST
104 2
		if ($data['php_version'] === false || $data['cms_version'] === false || $data['db_type'] === false || $data['db_version'] === false)
105
		{
106
			$response = [
107
				'error'   => true,
108
				'message' => 'Invalid data submission.',
109
			];
110
111
			$this->getApplication()->setHeader('HTTP/1.1 500 Internal Server Error', 500, true);
112
			$this->getApplication()->setBody(json_encode($response));
113
114
			return true;
115
		}
116
117
		// Account for configuration differences with 4.0
118 2
		if (version_compare($data['cms_version'], '4.0', 'ge'))
119
		{
120
			// For 4.0 and later, we map `mysql` to the `pdomysql` option to correctly track the database type
121 1
			if ($data['db_type'] === 'mysql')
122
			{
123 1
				$data['db_type'] = 'pdomysql';
124
			}
125
		}
126
127 2
		$this->model->save((object) $data);
128
129
		$response = [
130 2
			'error'   => false,
131
			'message' => 'Data saved successfully',
132
		];
133
134 2
		$this->getApplication()->setBody(json_encode($response));
135
136 2
		return true;
137
	}
138
139
	/**
140
	 * Check the CMS version.
141
	 *
142
	 * @param   string  $version  The version number to check.
143
	 *
144
	 * @return  string|boolean  The version number on success or boolean false on failure.
145
	 */
146 4 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...
147
	{
148 4
		$version = $this->validateVersionNumber($version);
149
150
		// If the version number is invalid, don't go any further
151 4
		if ($version === false)
152
		{
153 1
			return false;
154
		}
155
156
		// Joomla only uses major.minor.patch so everything else is invalid
157 3
		$explodedVersion = explode('.', $version);
158
159 3
		if (count($explodedVersion) > 3)
160
		{
161 1
			return false;
162
		}
163
164
		// Import the valid release listing
165 2
		$path = APPROOT . '/versions/joomla.json';
166
167 2
		if (!file_exists($path))
168
		{
169
			throw new \RuntimeException('Missing Joomla! release listing', 500);
170
		}
171
172 2
		$validVersions = json_decode(file_get_contents($path), true);
173
174
		// Check that the version is in our valid release list
175 2
		if (!in_array($version, $validVersions))
176
		{
177
			return false;
178
		}
179
180 2
		return $version;
181
	}
182
183
	/**
184
	 * Check the database type
185
	 *
186
	 * @param   string  $database  The database type to check.
187
	 *
188
	 * @return  string|boolean  The database type on success or boolean false on failure.
189
	 */
190 4
	private function checkDatabaseType(string $database)
191
	{
192 4
		if (!in_array($database, $this->databaseTypes))
193
		{
194
			return false;
195
		}
196
197 4
		return $database;
198
	}
199
200
	/**
201
	 * Check the PHP version
202
	 *
203
	 * @param   string  $version  The version number to check.
204
	 *
205
	 * @return  string|boolean  The version number on success or boolean false on failure.
206
	 */
207 4 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...
208
	{
209 4
		$version = $this->validateVersionNumber($version);
210
211
		// If the version number is invalid, don't go any further
212 4
		if ($version === false)
213
		{
214
			return false;
215
		}
216
217
		// We only track versions based on major.minor.patch so everything else is invalid
218 4
		$explodedVersion = explode('.', $version);
219
220 4
		if (count($explodedVersion) > 3)
221
		{
222
			return false;
223
		}
224
225
		// Import the valid release listing
226 4
		$path = APPROOT . '/versions/php.json';
227
228 4
		if (!file_exists($path))
229
		{
230
			throw new \RuntimeException('Missing PHP release listing', 500);
231
		}
232
233 4
		$validVersions = json_decode(file_get_contents($path), true);
234
235
		// Check that the version is in our valid release list
236 4
		if (!in_array($version, $validVersions))
237
		{
238
			return false;
239
		}
240
241 4
		return $version;
242
	}
243
}
244