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