Completed
Push — master ( 740d41...a3b506 )
by Michal
07:10 queued 16s
created

ReportsController::unmark_related_to()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 17
ccs 0
cts 0
cp 0
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 11
nc 3
nop 1
crap 12
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 (https://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 (https://www.phpmyadmin.net/)
23
 * @package       Server.Controller
24
 * @link          https://www.phpmyadmin.net/
25
 * @license       https://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
		);
46 1
		$this->set('distinct_versions',
47 1
			$this->_findArrayList($this->Reports->find()->select(['pma_version'])->distinct(['pma_version']), 'pma_version')
48
		);
49 1
		$this->set('distinct_error_names',
50 1
			$this->_findArrayList($this->Reports->find('all', array(
51 1
				'fields' => array('error_name'),
52
				'conditions' => array('error_name !=' => ''),
53 1
			))->distinct(['error_name']), 'error_name')
54
		);
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')->
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 1
					'report_id' => $reportId
88
				),
89 1
				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
			);
91
		}
92 1
	}
93
94 1
	public function data_tables() {
95
		$subquery_params = [
96
			'fields' => [
97
				'report_id' => 'report_id',
98
				'inci_count' => 'COUNT(id)'
99 1
				],
100
			'group' => 'report_id'
101
		];
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
			'error_name' => 'error_name',
108
			'error_message' => 'error_message',
109
			'pma_version' => 'pma_version',
110
			'status' => 'status',
111
			'exception_type' => 'exception_type',
112
			'inci_count' => 'inci_count'
113
		];
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 1
					'related_to is NULL'
123
				],
124 1
			'order' => $orderConditions,
125
		];
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
			)
135
		);
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
					'report_id' => 'report_id',
153
				]
154 1
			];
155 1
			$subquery_count = TableRegistry::get('incidents')->find(
156 1
				'all', $subquery_params_count
157
			);
158
159
			$params_count = [
160 1
				'fields' => ['inci_count' => 'inci_count'],
161
				'conditions' => [
162 1
				        'related_to = ' . $row[0]
163
				]
164
			];
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
		}
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 1
			'aaData' => $dispRows
182
		);
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 #"
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.",
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.",
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
	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
					break;
291
				}
292
                $report->status = $state;
293
				$this->Reports->save($report);
294
			}
295
		}
296
297
		$this->Flash->default($msg,
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
		}
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
		}
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
			}
335 1
			$output[] = $output_row;
336
		}
337 1
		return $output;
338
	}
339
}
340