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

StatsJsonView::render()   D

Complexity

Conditions 28
Paths 168

Size

Total Lines 163
Code Lines 74

Duplication

Lines 8
Ratio 4.91 %

Code Coverage

Tests 99
CRAP Score 28.0007

Importance

Changes 5
Bugs 0 Features 0
Metric Value
c 5
b 0
f 0
dl 8
loc 163
ccs 99
cts 100
cp 0.99
rs 4.248
cc 28
eloc 74
nc 168
nop 0
crap 28.0007

How to fix   Long Method    Complexity   

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
namespace Stats\Views\Stats;
4
5
use Joomla\View\BaseJsonView;
6
7
/**
8
 * JSON response for requesting the stats data.
9
 *
10
 * @property-read  \Stats\Models\StatsModel  $model  The model object.
11
 *
12
 * @since          1.0
13
 */
14
class StatsJsonView extends BaseJsonView
15
{
16
	/**
17
	 * Flag if the response should return the raw data.
18
	 *
19
	 * @var    boolean
20
	 * @since  1.0
21
	 */
22
	private $authorizedRaw = false;
23
24
	/**
25
	 * The data source to return.
26
	 *
27
	 * @var    string
28
	 * @since  1.0
29
	 */
30
	private $source;
31
32
	/**
33
	 * Set whether the raw data should be returned.
34
	 *
35
	 * @param   boolean  $authorizedRaw  Flag if the response should return the raw data.
36
	 *
37
	 * @return  void
38
	 *
39
	 * @since   1.0
40
	 */
41 1
	public function isAuthorizedRaw($authorizedRaw)
42
	{
43 1
		$this->authorizedRaw = $authorizedRaw;
44 1
	}
45
46
	/**
47
	 * Method to render the view.
48
	 *
49
	 * @return  string  The rendered view.
50
	 *
51
	 * @since   1.0
52
	 * @throws  \InvalidArgumentException
53
	 */
54 4
	public function render()
55
	{
56 4
		$items = $this->model->getItems();
57
58
		$data = [
59 4
			'php_version' => [],
60 4
			'db_type'     => [],
61 4
			'db_version'  => [],
62 4
			'cms_version' => [],
63 4
			'server_os'   => []
64 4
		];
65
66
67 4
		foreach ($items as $item)
68
		{
69 4
			foreach ($data as $key => $value)
70
			{
71 4
				if (!is_null($item->$key))
72 4
				{
73
					// Special case, if the server is empty then change the key to "unknown"
74 4
					if ($key === 'server_os' && empty($item->$key))
75 4
					{
76 4
						if (!isset($data[$key]['unknown']))
77 4
						{
78 4
							$data[$key]['unknown'] = 0;
79 4
						}
80
81 4
						$data[$key]['unknown']++;
82 4
					}
83
					else
84
					{
85 4
						if (!isset($data[$key][$item->$key]))
86 4
						{
87 4
							$data[$key][$item->$key] = 0;
88 4
						}
89
90 4
						$data[$key][$item->$key]++;
91
					}
92 4
				}
93 4
			}
94 4
		}
95
96 4
		$responseData = [];
97
98 4
		foreach ($data as $key => $value)
99
		{
100 4
			foreach ($value as $name => $count)
101
			{
102
				if ($name)
103 4
				{
104 4
					$responseData[$key][] = [
105 4
						'name'  => $name,
106
						'count' => $count
107 4
					];
108 4
				}
109 4
			}
110 4
		}
111
112 4
		$total = count($items);
113
114 4
		if (!$this->authorizedRaw)
115 4
		{
116 3
			foreach ($responseData as $key => $dataGroup)
117
			{
118
				switch ($key)
119
				{
120 3
					case 'php_version':
121 3
					case 'db_version':
122
						// We're going to group by minor version branch here and convert to a percentage
123 3
						$counts = [];
124
125 3
						foreach ($dataGroup as $row)
126
						{
127 3
							$exploded = explode('.', $row['name']);
128 3
							$version  = $exploded[0] . '.' . (isset($exploded[1]) ? $exploded[1] : '0');
129
130
							// If the container does not exist, add it
131 3
							if (!isset($counts[$version]))
132 3
							{
133 3
								$counts[$version] = 0;
134 3
							}
135
136 3
							$counts[$version] += $row['count'];
137 3
						}
138
139 3
						$sanitizedData = [];
140
141 3 View Code Duplication
						foreach ($counts as $version => $count)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
142
						{
143 3
							$sanitizedData[$version] = round(($count / $total) * 100, 4);
144 3
						}
145
146 3
						$responseData[$key] = $sanitizedData;
147
148 3
						break;
149
150 3
					case 'server_os':
151
						// We're going to group by operating system here
152 3
						$counts = [];
153
154 3
						foreach ($dataGroup as $row)
155
						{
156 3
							$fullOs = explode(' ', $row['name']);
157 3
							$os     = $fullOs[0];
158
159
							// If the container does not exist, add it
160 3
							if (!isset($counts[$os]))
161 3
							{
162 3
								$counts[$os] = 0;
163 3
							}
164
165 3
							$counts[$os] += $row['count'];
166 3
						}
167
168 3
						$sanitizedData = [];
169
170 3 View Code Duplication
						foreach ($counts as $os => $count)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
171
						{
172 3
							$sanitizedData[$os] = round(($count / $total) * 100, 4);
173 3
						}
174
175 3
						$responseData[$key] = $sanitizedData;
176
177 3
						break;
178
179 3
					case 'db_type':
180 3
					case 'cms_version':
181 3
					default:
182
						// For now, group by the object name and figure out the percentages
183 3
						$sanitizedData = [];
184
185 3
						foreach ($dataGroup as $row)
186
						{
187 3
							$sanitizedData[$row['name']] = round(($row['count'] / $total) * 100, 4);
188 3
						}
189
190 3
						$responseData[$key] = $sanitizedData;
191
192 3
						break;
193
				}
194 3
			}
195 3
		}
196
197 4
		$responseData['total'] = $total;
198
199
		// If a partial source was requested, only return that, or throw an exception if it doesn't exist
200 4
		if ($this->source)
201 4
		{
202 2
			if (!isset($responseData[$this->source]))
203 2
			{
204 1
				throw new \InvalidArgumentException('An invalid data source was requested.', 404);
205
			}
206
207
			$responseData = [
208 1
				$this->source => $responseData[$this->source],
209
				'total'       => $total
210 1
			];
211 1
		}
212
213 3
		$this->addData('data', $responseData);
214
215 3
		return parent::render();
216
	}
217
218
	/**
219
	 * Set the data source.
220
	 *
221
	 * @param   string  $source  Data source to return.
222
	 *
223
	 * @return  void
224
	 *
225
	 * @since   1.0
226
	 */
227 1
	public function setSource($source)
228
	{
229 1
		$this->source = $source;
230 1
	}
231
}
232