Completed
Pull Request — master (#117)
by Deven
17:58
created

ReportsController::data_tables()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 93
Code Lines 61

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 58
CRAP Score 3

Importance

Changes 4
Bugs 1 Features 2
Metric Value
c 4
b 1
f 2
dl 0
loc 93
ccs 58
cts 58
cp 1
rs 8.4642
cc 3
eloc 61
nc 3
nop 0
crap 3

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
/* vim: set noexpandtab sw=2 ts=2 sts=2: */
3
namespace App\Controller;
4
5
use App\Controller\AppController;
6
use App\Utility\Sanitize;
7
use Cake\Core\Configure;
8
use Cake\Log\Log;
9
use Cake\ORM\Table;
10
use Cake\ORM\TableRegistry;
11
use Cake\Network\Exception\NotFoundException;
12
/**
13
 * Reports controller handling reports creation and rendering
14
 *
15
 * phpMyAdmin Error reporting server
16
 * Copyright (c) phpMyAdmin project (http://www.phpmyadmin.net)
17
 *
18
 * Licensed under The MIT License
19
 * For full copyright and license information, please see the LICENSE.txt
20
 * Redistributions of files must retain the above copyright notice.
21
 *
22
 * @copyright     Copyright (c) phpMyAdmin project (http://www.phpmyadmin.net)
23
 * @package       Server.Controller
24
 * @link          http://www.phpmyadmin.net
25
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
26
 */
27
28
/**
29
 * Reports controller handling reports modification and rendering
30
 *
31
 * @package       Server.Controller
32
 */
33
class ReportsController extends AppController {
34
35
	public $components = array('RequestHandler', 'OrderSearch');
36
37
	public $helpers = array('Html', 'Form', 'Reports', 'Incidents');
38
	public $uses = array('Incidents', 'Reports', 'Notifications', 'Developers');
39
40 1
	public function index() {
41 1
		$this->Reports->recursive = -1;
42 1
		$this->set('distinct_statuses',
43 1
			$this->_findArrayList($this->Reports->find()->select(['status'])->distinct(['status']),
44 1
			'status')
45 1
		);
46 1
		$this->set('distinct_versions',
47 1
			$this->_findArrayList($this->Reports->find()->select(['pma_version'])->distinct(['pma_version']), 'pma_version')
48 1
		);
49 1
		$this->set('distinct_error_names',
50 1
			$this->_findArrayList($this->Reports->find('all', array(
51 1
				'fields' => array('error_name'),
52 1
				'conditions' => array('error_name !=' => ''),
53 1
			))->distinct(['error_name']), 'error_name')
54 1
		);
55 1
		$this->set('statuses', $this->Reports->status);
56 1
        $this->autoRender = true;
57 1
	}
58
59 1
	public function view($reportId) {
60 1
		if (!$reportId) {
61
			throw new NotFoundException(__('Invalid Report'));
62
		}
63 1
		$report = $this->Reports->findById($reportId)->toArray();
64 1
		if (!$report) {
65 1
			throw new NotFoundException(__('Invalid Report'));
66
		}
67
68 1
		$this->set('report', $report);
69 1
		$this->set('project_name', Configure::read('GithubRepoPath'));
70 1
		$this->Reports->id = $reportId;
71 1
		$this->set('incidents', $this->Reports->getIncidents()->toArray());
72 1
		$this->set('incidents_with_description',
73 1
            $this->Reports->getIncidentsWithDescription());
74 1
		$this->set('incidents_with_stacktrace',
75 1
				$this->Reports->getIncidentsWithDifferentStacktrace());
76 1
		$this->set('related_reports', $this->Reports->getRelatedReports());
77 1
		$this->set('status', $this->Reports->status);
78 1
		$this->_setSimilarFields($reportId);
79
80
		// if there is an unread notification for this report, then mark it as read
81 1
		$current_developer = TableRegistry::get('Developers')->
0 ignored issues
show
Documentation Bug introduced by
The method findById does not exist on object<Cake\ORM\Table>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
82 1
					findById($this->request->session()->read('Developer.id'))->all()->first();
83
		//$current_developer = Sanitize::clean($current_developer);
84 1
		if ($current_developer) {
85 1
			TableRegistry::get('Notifications')->deleteAll(
86 1
				array('developer_id' => $current_developer['Developer']['id'],
87
					'report_id' => $reportId
88 1
				),
89
				false
0 ignored issues
show
Unused Code introduced by
The call to Table::deleteAll() has too many arguments starting with false.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
90 1
			);
91 1
		}
92 1
	}
93
94 1
	public function data_tables() {
95
		$subquery_params = [
96
			'fields' => [
97 1
				'report_id' => 'report_id',
98
				'inci_count' => 'COUNT(id)'
99 1
				],
100
			'group' => 'report_id'
101 1
		];
102 1
		$subquery = TableRegistry::get('incidents')->find('all', $subquery_params);
103
104
		// override automatic aliasing, for proper usage in joins
105
		$aColumns = [
106 1
			'id' => 'id',
107 1
			'error_name' => 'error_name',
108 1
			'error_message' => 'error_message',
109 1
			'pma_version' => 'pma_version',
110 1
			'status' => 'status',
111 1
			'exception_type' => 'exception_type',
112
			'inci_count' => 'inci_count'
113 1
		];
114
115 1
		$searchConditions = $this->OrderSearch->getSearchConditions($aColumns);
116 1
		$orderConditions = $this->OrderSearch->getOrder($aColumns);
117
118
		$params = [
119 1
			'fields' => $aColumns,
120
			'conditions' => [
121 1
					$searchConditions,
122
					'related_to is NULL'
123 1
				],
124 1
			'order' => $orderConditions,
125 1
		];
126
127 1
		$pagedParams = $params;
128 1
		$pagedParams['limit'] = intval($this->request->query('iDisplayLength'));
129 1
		$pagedParams['offset'] = intval($this->request->query('iDisplayStart'));
130
131 1
		$rows = $this->_findAllDataTable(
132 1
			$this->Reports->find('all', $pagedParams)->innerJoin(
133 1
				['incidents' => $subquery], ['incidents.report_id = Reports.id']
134 1
			)
135 1
		);
136
		//$rows = Sanitize::clean($rows);
137 1
		$totalFiltered = $this->Reports->find('all', $params)->count();
138
139
140
		// change exception_type from boolean values to strings
141
		// add incident count for related reports
142 1
		$dispRows = array();
143 1
		foreach($rows as $row) {
144 1
			$row[4] = $this->Reports->status[$row[4]];
145 1
			$row[5] = (intval($row[5]))?('php'):('js');
146
			$input_elem = "<input type='checkbox' name='reports[]' value='"
147 1
				. $row[0]
148 1
				. "'/>";
149
150
			$subquery_params_count = [
151
				'fields' => [
152 1
					'report_id' => 'report_id',
153
				]
154 1
			];
155 1
			$subquery_count = TableRegistry::get('incidents')->find(
156 1
				'all', $subquery_params_count
157 1
			);
158
159
			$params_count = [
160 1
				'fields' => ['inci_count' => 'inci_count'],
161
				'conditions' => [
162 1
				        'related_to = ' . $row[0]
163 1
				]
164 1
			];
165
166 1
			$inci_count_related = $this->Reports->find('all', $params_count)->innerJoin(
167 1
				['incidents' => $subquery_count],
168 1
				['incidents.report_id = Reports.related_to']
169 1
			)->count();
170
171 1
			$row[6] += $inci_count_related;
172
173 1
			array_unshift($row, $input_elem);
174 1
			array_push($dispRows, $row);
175 1
		}
176
177
		$response = array(
178 1
			'iTotalRecords' => $this->Reports->find('all')->count(),
179 1
			'iTotalDisplayRecords' => $totalFiltered,
180 1
			'sEcho' => intval($this->request->query('sEcho')),
181
			'aaData' => $dispRows
182 1
		);
183 1
		$this->autoRender = false;
184 1
		$this->response->body(json_encode($response));
185 1
        return $this->response;
186
	}
187
188
	public function mark_related_to($reportId) {
189
		$relatedTo = $this->request->query("related_to");
190
		if (!$reportId
191
			|| !$relatedTo
192
			|| $reportId == $relatedTo
193
		) {
194
			throw new NotFoundException(__('Invalid Report'));
195
		}
196
197
		$report = $this->Reports->get($reportId);
198
		if (!$report) {
199
			throw new NotFoundException(__('Invalid Report'));
200
		}
201
202
		$this->Reports->addToRelatedGroup($report, $relatedTo);
203
204
		$flash_class = "alert alert-success";
205
		$this->Flash->default("This report has been marked the same as #"
0 ignored issues
show
Documentation Bug introduced by
The method default does not exist on object<Cake\Controller\Component\FlashComponent>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
206
				. $relatedTo,
207
				array("params" => array("class" => $flash_class)));
208
		$this->redirect("/reports/view/$reportId");
209
	}
210
211
	public function unmark_related_to($reportId) {
212
		if (!$reportId) {
213
			throw new NotFoundException(__('Invalid Report'));
214
		}
215
216
		$report = $this->Reports->get($reportId);
217
		if (!$report) {
218
			throw new NotFoundException(__('Invalid Report'));
219
		}
220
221
		$this->Reports->removeFromRelatedGroup($report);
222
223
		$flash_class = "alert alert-success";
224
		$this->Flash->default("This report has been marked as different.",
0 ignored issues
show
Documentation Bug introduced by
The method default does not exist on object<Cake\Controller\Component\FlashComponent>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
225
			array("params" => array("class" => $flash_class)));
226
		$this->redirect("/reports/view/$reportId");
227
	}
228
229
	public function change_state($reportId) {
230
		if (!$reportId) {
231
			throw new NotFoundException(__('Invalid Report'));
232
		}
233
234
		$report = $this->Reports->get($reportId);
235
		if (!$report) {
236
			throw new NotFoundException(__('Invalid Report'));
237
		}
238
239
		$state = $this->request->data['state'];
240
		$newState = $this->Reports->status[$state];
241
		if (!$newState) {
242
			throw new NotFoundException(__('Invalid State'));
243
		}
244
        $report->status = $state;
245
		$this->Reports->save($report);
246
247
		$flash_class = "alert alert-success";
248
		$this->Flash->default("The state has been successfully changed.",
0 ignored issues
show
Documentation Bug introduced by
The method default does not exist on object<Cake\Controller\Component\FlashComponent>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
249
			array("params" => array("class" => $flash_class)));
250
		$this->redirect("/reports/view/$reportId");
251
	}
252
253
	/**
254
	 * To carry out mass actions on Reports
255
	 * Currently only to change their statuses.
256
	 * Can be Extended for other mass operations as well.
257
	 * Expects an array of Report Ids as a POST parameter.
258
	 *
259
	 */
260 1
	public function mass_action()
261
	{
262
		$flash_class = "alert alert-error";
263
		$state = $this->request->data['state'];
264
		$newState = $this->Reports->status[$state];
265
		if (!$newState) {
266
			Log::write(
267
				'error',
268
				'ERRORED: Invalid param "state" in ReportsController::mass_action()',
269
				'alert'
270
			);
271
			$msg = "ERROR: Invalid State!!";
272
		} else if (count($this->request->data['reports']) == 0) {
273
			$msg = "No Reports Selected!! Please Select Reports and try again.";
274
		} else {
275
			$msg = "Status has been changed to '"
276
				. $this->request->data['state']
277
				. "' for selected Reports!";
278
			$flash_class = "alert alert-success";
279
			foreach($this->request->data['reports'] as $report_id)
280
			{
281
				$report = $this->Reports->get($report_id);
282
				if (!$report) {
283
					Log::write(
284
						'error',
285
						'ERRORED: Invalid report_id in ReportsController::mass_action()',
286
						'alert'
287
					);
288
					$msg = "ERROR:Invalid Report ID:" . $report_id;
289
					$flash_class = "alert alert-error";
290 1
					break;
291
				}
292
                $report->status = $state;
293
				$this->Reports->save($report);
294
			}
295
		}
296
297
		$this->Flash->default($msg,
0 ignored issues
show
Documentation Bug introduced by
The method default does not exist on object<Cake\Controller\Component\FlashComponent>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
298
			array("params" => array("class" => $flash_class)));
299
		$this->redirect("/reports/");
300
	}
301
302
## HELPERS
303 1
	protected function _setSimilarFields($id) {
304 1
		$this->Reports->id = $id;
305
306 1
		$this->set('columns', TableRegistry::get('Incidents')->summarizableFields);
307 1
		$relatedEntries = array();
308
309 1
		foreach (TableRegistry::get('Incidents')->summarizableFields as $field) {
310
			list($entriesWithCount, $totalEntries) =
311 1
					$this->Reports->getRelatedByField($field, 25, true);
312 1
			$relatedEntries[$field] = $entriesWithCount;
313 1
			$this->set("${field}_distinct_count", $totalEntries);
314 1
		}
315
        //error_log(json_encode($relatedEntries));
316
		$this->set("related_entries", $relatedEntries);
317
	}
318
319
    protected function _findArrayList($results, $key) {
320 1
        $output = array();
321 1
		foreach ($results as $row) {
322 1
			$output[] = $row[$key];
323 1
		}
324 1
		return $output;
325
    }
326
327
    protected function _findAllDataTable($results) {
328 1
		$output = array();
329 1
		foreach ($results as $row) {
330 1
			$output_row = array();
331 1
            $row = $row->toArray();
332 1
			foreach ($row as $key => $value) {
333 1
				$output_row[] = $value;
334 1
			}
335 1
			$output[] = $output_row;
336 1
		}
337 1
		return $output;
338
	}
339
}
340