Completed
Push — master ( 667317...f33c3d )
by William
09:54
created

GithubController::_getTotalIncidentCount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 9.488
c 0
b 0
f 0
ccs 13
cts 13
cp 1
cc 1
nc 1
nop 1
crap 1
1
<?php
2
/* vim: set expandtab sw=4 ts=4 sts=4: */
3
4
/**
5
 * Github controller handling issue creation, comments and sync.
6
 *
7
 * phpMyAdmin Error reporting server
8
 * Copyright (c) phpMyAdmin project (https://www.phpmyadmin.net/)
9
 *
10
 * Licensed under The MIT License
11
 * For full copyright and license information, please see the LICENSE.txt
12
 * Redistributions of files must retain the above copyright notice.
13
 *
14
 * @copyright Copyright (c) phpMyAdmin project (https://www.phpmyadmin.net/)
15
 * @license   https://opensource.org/licenses/mit-license.php MIT License
16
 *
17
 * @see      https://www.phpmyadmin.net/
18
 */
19
20
namespace App\Controller;
21
22
use Cake\Core\Configure;
23
use Cake\Event\Event;
24
use Cake\Log\Log;
25
use Cake\Http\Exception\NotFoundException;
26
use Cake\ORM\TableRegistry;
27
use Cake\Routing\Router;
28
29
/**
30
 * Github controller handling github issue submission and creation.
31
 */
32
class GithubController extends AppController
33
{
34
    public $helpers = [
35
        'Html',
36
        'Form',
37
    ];
38
39
    public $components = ['GithubApi'];
40
41 5
    public function beforeFilter(Event $event)
42
    {
43 5
        parent::beforeFilter($event);
44 5
        $this->GithubApi->githubConfig = Configure::read('GithubConfig');
45 5
        $this->GithubApi->githubRepo = Configure::read('GithubRepoPath');
46 5
    }
47
48
    /**
49
     * create Github Issue.
50
     *
51
     * @param int $reportId The report number
52
     *
53
     * @throws NotFoundException
54
     * @return void
55
     */
56 1
    public function create_issue($reportId)
57
    {
58 1
        if (! isset($reportId) || ! $reportId) {
59
            throw new NotFoundException(__('Invalid report'));
60
        }
61
62 1
        $reportsTable = TableRegistry::get('Reports');
0 ignored issues
show
Deprecated Code introduced by
The method Cake\ORM\TableRegistry::get() has been deprecated with message: 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
63 1
        $report = $reportsTable->findById($reportId)->all()->first();
64
65 1
        if (! $report) {
66 1
            throw new NotFoundException(__('Invalid report'));
67
        }
68
69 1
        $reportArray = $report->toArray();
70 1
        if (empty($this->request->data)) {
0 ignored issues
show
Deprecated Code introduced by
The property Cake\Http\ServerRequest::$data has been deprecated with message: 3.4.0 This public property will be removed in 4.0.0. Use getData() instead.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
71 1
            $this->set('error_name', $reportArray['error_name']);
72 1
            $this->set('error_message', $reportArray['error_message']);
73
74 1
            return;
75
        }
76
77 1
        $this->autoRender = false;
78
        $data = [
79 1
            'title' => $this->request->data['summary'],
0 ignored issues
show
Deprecated Code introduced by
The property Cake\Http\ServerRequest::$data has been deprecated with message: 3.4.0 This public property will be removed in 4.0.0. Use getData() instead.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
80 1
            'labels' => $this->request->data['labels'] ? explode(',', $this->request->data['labels']) : [],
0 ignored issues
show
Deprecated Code introduced by
The property Cake\Http\ServerRequest::$data has been deprecated with message: 3.4.0 This public property will be removed in 4.0.0. Use getData() instead.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
81
        ];
82 1
        $incidents_query = TableRegistry::get('Incidents')->findByReportId($reportId)->all();
0 ignored issues
show
Deprecated Code introduced by
The method Cake\ORM\TableRegistry::get() has been deprecated with message: 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
83 1
        $incident = $incidents_query->first();
84 1
        $reportArray['exception_type'] = $incident['exception_type'] ? 'php' : 'js';
85 1
        $reportArray['description'] = $this->request->data['description'];
0 ignored issues
show
Deprecated Code introduced by
The property Cake\Http\ServerRequest::$data has been deprecated with message: 3.4.0 This public property will be removed in 4.0.0. Use getData() instead.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
86
87 1
        $data['body']
88 1
            = $this->_getReportDescriptionText($reportId, $reportArray);
89 1
        $data['labels'][] = 'automated-error-report';
90
91 1
        list($issueDetails, $status) = $this->GithubApi->createIssue(
92 1
            Configure::read('GithubRepoPath'),
93
            $data,
94 1
            $this->request->session()->read('access_token')
0 ignored issues
show
Deprecated Code introduced by
The method Cake\Http\ServerRequest::session() has been deprecated with message: 3.5.0 Use getSession() instead. The setter part will be removed.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
95
        );
96
97 1
        if ($this->_handleGithubResponse($status, 1, $reportId, $issueDetails['number'])) {
98
            // Update report status
99 1
            $report->status = $this->_getReportStatusFromIssueState($issueDetails['state']);
100 1
            $reportsTable->save($report);
101
102 1
            $this->redirect(['controller' => 'reports', 'action' => 'view',
103 1
                $reportId,
104
            ]);
105 View Code Duplication
        } else {
106 1
            $flash_class = 'alert alert-error';
107 1
            $this->Flash->default(
108 1
                $this->_getErrors($issueDetails, $status),
109 1
                ['params' => ['class' => $flash_class]]
110
            );
111
        }
112 1
    }
113
114
    /**
115
     * Links error report to existing issue on Github.
116
     *
117
     * @param int $reportId The report Id
118
     * @return void
119
     */
120 1
    public function link_issue($reportId)
121
    {
122 1
        if (! isset($reportId) || ! $reportId) {
123
            throw new NotFoundException(__('Invalid reportId'));
124
        }
125
126 1
        $reportsTable = TableRegistry::get('Reports');
0 ignored issues
show
Deprecated Code introduced by
The method Cake\ORM\TableRegistry::get() has been deprecated with message: 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
127 1
        $report = $reportsTable->findById($reportId)->all()->first();
128
129 1
        if (! $report) {
130 1
            throw new NotFoundException(__('Invalid report'));
131
        }
132
133 1
        $ticket_id = intval($this->request->query['ticket_id']);
0 ignored issues
show
Deprecated Code introduced by
The property Cake\Http\ServerRequest::$query has been deprecated with message: 3.4.0 This public property will be removed in 4.0.0. Use getQuery() or getQueryParams() instead.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
134 1
        if (! $ticket_id) {
135 1
            throw new NotFoundException(__('Invalid Ticket ID!!'));
136
        }
137 1
        $reportArray = $report->toArray();
138
139 1
        $incidents_query = TableRegistry::get('Incidents')->findByReportId($reportId)->all();
0 ignored issues
show
Deprecated Code introduced by
The method Cake\ORM\TableRegistry::get() has been deprecated with message: 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
140 1
        $incident = $incidents_query->first();
141 1
        $reportArray['exception_type'] = $incident['exception_type'] ? 'php' : 'js';
142
143 1
        $commentText = $this->_getReportDescriptionText(
144 1
            $reportId,
145
            $reportArray
146
        );
147 1
        list($commentDetails, $status) = $this->GithubApi->createComment(
148 1
            Configure::read('GithubRepoPath'),
149 1
            ['body' => $commentText],
150
            $ticket_id,
151 1
            $this->request->session()->read('access_token')
0 ignored issues
show
Deprecated Code introduced by
The method Cake\Http\ServerRequest::session() has been deprecated with message: 3.5.0 Use getSession() instead. The setter part will be removed.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
152
        );
153 1
        if ($this->_handleGithubResponse($status, 2, $reportId, $ticket_id)) {
154
            // Update report status
155 1
            $report->status = 'forwarded';
156
157 1
            list($issueDetails, $status) = $this->GithubApi->getIssue(
158 1
                Configure::read('GithubRepoPath'),
159 1
                [],
160
                $ticket_id,
161 1
                $this->request->session()->read('access_token')
0 ignored issues
show
Deprecated Code introduced by
The method Cake\Http\ServerRequest::session() has been deprecated with message: 3.5.0 Use getSession() instead. The setter part will be removed.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
162
            );
163 1
            if ($this->_handleGithubResponse($status, 4, $reportId, $ticket_id)) {
164
                // If linked Github issue state is available, use it to update Report's status
165 1
                $report->status = $this->_getReportStatusFromIssueState(
166 1
                    $issueDetails['state']
167
                );
168
            }
169
170 1
            $reportsTable->save($report);
171 View Code Duplication
        } else {
172 1
            $flash_class = 'alert alert-error';
173 1
            $this->Flash->default(
174 1
                $this->_getErrors($commentDetails, $status),
175 1
                ['params' => ['class' => $flash_class]]
176
            );
177
        }
178
179 1
        $this->redirect(['controller' => 'reports', 'action' => 'view',
180 1
            $reportId,
181
        ]);
182 1
    }
183
184
    /**
185
     * Un-links error report to associated issue on Github.
186
     *
187
     * @param int $reportId The report Id
188
     * @return void
189
     */
190 1
    public function unlink_issue($reportId)
191
    {
192 1
        if (! isset($reportId) || ! $reportId) {
193
            throw new NotFoundException(__('Invalid reportId'));
194
        }
195
196 1
        $reportsTable = TableRegistry::get('Reports');
0 ignored issues
show
Deprecated Code introduced by
The method Cake\ORM\TableRegistry::get() has been deprecated with message: 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
197 1
        $report = $reportsTable->findById($reportId)->all()->first();
198
199 1
        if (! $report) {
200 1
            throw new NotFoundException(__('Invalid report'));
201
        }
202
203 1
        $reportArray = $report->toArray();
204 1
        $ticket_id = $reportArray['sourceforge_bug_id'];
205
206 1
        if (! $ticket_id) {
207 1
            throw new NotFoundException(__('Invalid Ticket ID!!'));
208
        }
209
210
        // "formatted" text of the comment.
211
        $commentText = 'This Issue is no longer associated with [Report#'
212 1
            . $reportId
213 1
            . ']('
214 1
            . Router::url('/reports/view/' . $reportId, true)
215 1
            . ')'
216 1
            . "\n\n*This comment is posted automatically by phpMyAdmin's "
217 1
            . '[error-reporting-server](https://reports.phpmyadmin.net).*';
218
219 1
        list($commentDetails, $status) = $this->GithubApi->createComment(
220 1
            Configure::read('GithubRepoPath'),
221 1
            ['body' => $commentText],
222
            $ticket_id,
223 1
            $this->request->session()->read('access_token')
0 ignored issues
show
Deprecated Code introduced by
The method Cake\Http\ServerRequest::session() has been deprecated with message: 3.5.0 Use getSession() instead. The setter part will be removed.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
224
        );
225
226 1
        if ($this->_handleGithubResponse($status, 3, $reportId)) {
227
            // Update report status
228 1
            $report->status = 'new';
229 1
            $reportsTable->save($report);
230 View Code Duplication
        } else {
231 1
            $flash_class = 'alert alert-error';
232 1
            $this->Flash->default(
233 1
                $this->_getErrors($commentDetails, $status),
234 1
                ['params' => ['class' => $flash_class]]
235
            );
236
        }
237
238 1
        $this->redirect(['controller' => 'reports', 'action' => 'view',
239 1
            $reportId,
240
        ]);
241 1
    }
242
243
    /**
244
     * Returns pretty error message string.
245
     *
246
     * @param object $response the response returned by Github api
247
     * @param int    $status   status returned by Github API
248
     *
249
     * @return string error string
250
     */
251 3
    protected function _getErrors($response, $status)
252
    {
253
        $errorString = 'There were some problems with the issue submission.'
254 3
            . ' Returned status is (' . $status . ')';
255
        $errorString .= '<br/> Here is the dump for the errors field provided by'
256
            . ' github: <br/>'
257
            . '<pre>'
258 3
            . print_r($response, true)
259 3
            . '</pre>';
260
261 3
        return $errorString;
262
    }
263
264
    /**
265
     * Returns the text to be added while creating an issue
266
     *
267
     * @param integer $reportId Report Id
268
     * @param array   $report   Report associative array
269
     *
270
     * @return string
271
     */
272 2
    protected function _getReportDescriptionText($reportId, $report)
273
    {
274 2
        $incident_count = $this->_getTotalIncidentCount($reportId);
275
276
        // "formatted" text of the comment.
277
        $formattedText
278 2
            = array_key_exists('description', $report) ? $report['description'] . "\n\n"
279 2
                : '';
280
        $formattedText .= "\nParam | Value "
281
            . "\n -----------|--------------------"
282 2
            . "\n Error Type | " . $report['error_name']
283 2
            . "\n Error Message |" . $report['error_message']
284 2
            . "\n Exception Type |" . $report['exception_type']
285 2
            . "\n phpMyAdmin version |" . $report['pma_version']
286 2
            . "\n Incident count | " . $incident_count
287 2
            . "\n Link | [Report#"
288 2
                . $reportId
289 2
                . ']('
290 2
                . Router::url('/reports/view/' . $reportId, true)
291 2
                . ')'
292 2
            . "\n\n*This comment is posted automatically by phpMyAdmin's "
293 2
            . '[error-reporting-server](https://reports.phpmyadmin.net).*';
294
295 2
        return $formattedText;
296
    }
297
298
    /**
299
     * Github Response Handler.
300
     *
301
     * @param int $response  the status returned by Github API
302
     * @param int $type      type of response. 1 for create_issue, 2 for link_issue, 3 for unlink_issue,
303
     *                       1 for create_issue,
304
     *                       2 for link_issue,
305
     *                       3 for unlink_issue,
306
     *                       4 for get_issue
307
     * @param int $report_id report id
308
     * @param int $ticket_id ticket id, required for link ticket only
309
     *
310
     * @return bool value. True on success. False on any type of failure.
311
     */
312 5
    protected function _handleGithubResponse($response, $type, $report_id, $ticket_id = 1)
313
    {
314 5
        if (! in_array($type, [1, 2, 3, 4])) {
315
            throw new \InvalidArgumentException('Invalid Argument "$type".');
316
        }
317
318 5
        $updateReport = true;
319
320 5
        if ($type == 4 && $response == 200) {
321
            // issue details fetched successfully
322 3
            return true;
323 4
        } elseif ($response == 201) {
324
            // success
325
            switch ($type) {
326 3
                case 1:
327 1
                    $msg = 'Github issue has been created for this report.';
328 1
                    break;
329 2
                case 2:
330 1
                    $msg = 'Github issue has been linked with this report.';
331 1
                    break;
332 1
                case 3:
333 1
                    $msg = 'Github issue has been unlinked with this report.';
334 1
                    $ticket_id = null;
335 1
                    break;
336
337
                default:
338
                    $msg = 'Something went wrong!';
339
                    break;
340
            }
341
342 3
            if ($updateReport) {
343 3
                $report = TableRegistry::get('Reports')->get($report_id);
0 ignored issues
show
Deprecated Code introduced by
The method Cake\ORM\TableRegistry::get() has been deprecated with message: 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
344 3
                $report->sourceforge_bug_id = $ticket_id;
0 ignored issues
show
Bug introduced by
Accessing sourceforge_bug_id on the interface Cake\Datasource\EntityInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
345 3
                TableRegistry::get('Reports')->save($report);
0 ignored issues
show
Deprecated Code introduced by
The method Cake\ORM\TableRegistry::get() has been deprecated with message: 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
346
            }
347
348 3 View Code Duplication
            if ($msg !== '') {
349 3
                $flash_class = 'alert alert-success';
350 3
                $this->Flash->default(
351 3
                    $msg,
352 3
                    ['params' => ['class' => $flash_class]]
353
                );
354
            }
355
356 3
            return true;
357 4
        } elseif ($response === 403) {
358 1
            $flash_class = 'alert alert-error';
359 1
            $this->Flash->default(
360
                'Unauthorised access to Github. github'
361
                    . ' credentials may be out of date. Please check and try again'
362 1
                    . ' later.',
363 1
                ['params' => ['class' => $flash_class]]
364
            );
365
366 1
            return false;
367 3
        } elseif ($response === 404
368 3
            && $type == 2
369
        ) {
370 1
            $flash_class = 'alert alert-error';
371 1
            $this->Flash->default(
372
                'Bug Issue not found on Github.'
373 1
                    . ' Are you sure the issue number is correct? Please check and try again!',
374 1
                ['params' => ['class' => $flash_class]]
375
            );
376
377 1
            return false;
378
        }
379
380
        // unknown response code
381 2
        $flash_class = 'alert alert-error';
382 2
        $this->Flash->default(
383 2
            'Unhandled response code received: ' . $response,
384 2
            ['params' => ['class' => $flash_class]]
385
        );
386
387 2
        return false;
388
    }
389
390
    /**
391
     * Get Incident counts for a report and
392
     * all its related reports
393
     *
394
     * @param int $reportId The report Id
395
     *
396
     * @return int Total Incident count for a report
397
     */
398 2
    protected function _getTotalIncidentCount($reportId)
399
    {
400 2
        $incidents_query = TableRegistry::get('Incidents')->findByReportId($reportId)->all();
0 ignored issues
show
Deprecated Code introduced by
The method Cake\ORM\TableRegistry::get() has been deprecated with message: 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
401 2
        $incident_count = $incidents_query->count();
402
403
        $params_count = [
404 2
            'fields' => ['inci_count' => 'inci_count'],
405
            'conditions' => [
406 2
                'related_to = ' . $reportId,
407
            ],
408
        ];
409
        $subquery_params_count = [
410
            'fields' => [
411 2
                'report_id' => 'report_id',
412
            ],
413
        ];
414 2
        $subquery_count = TableRegistry::get('Incidents')->find(
0 ignored issues
show
Deprecated Code introduced by
The method Cake\ORM\TableRegistry::get() has been deprecated with message: 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
415 2
            'all',
416
            $subquery_params_count
417
        );
418 2
        $inci_count_related = TableRegistry::get('Reports')->find('all', $params_count)->innerJoin(
0 ignored issues
show
Deprecated Code introduced by
The method Cake\ORM\TableRegistry::get() has been deprecated with message: 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
419 2
            ['incidents' => $subquery_count],
420 2
            ['incidents.report_id = Reports.related_to']
421 2
        )->count();
422
423 2
        return $incident_count + $inci_count_related;
424
    }
425
426
    /**
427
     * Get corresponding report status from Github issue state
428
     *
429
     * @param string $issueState Linked Github issue's state
430
     *
431
     * @return string Corresponding status to which the linked report should be updated to
432
     */
433 4
    protected function _getReportStatusFromIssueState($issueState)
434
    {
435
        // default
436 4
        $reportStatus = '';
0 ignored issues
show
Unused Code introduced by
$reportStatus is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
437 4
        switch ($issueState) {
438 4
            case 'closed':
439 3
                $reportStatus = 'resolved';
440 3
                break;
441
442
            default:
443 4
                $reportStatus = 'forwarded';
444 4
                break;
445
        }
446
447 4
        return $reportStatus;
448
    }
449
450
    /**
451
     * Synchronize Report Statuses from Github issues
452
     *
453
     * To be used as a cron job (using webroot/cron_dispatcher.php).
454
     *
455
     * Can not (& should not) be directly accessed via web.
456
     * @return void
457
     */
458 2
    public function sync_issue_status()
459
    {
460 2 View Code Duplication
        if (! Configure::read('CronDispatcher')) {
461 1
            $flash_class = 'alert alert-error';
462 1
            $this->Flash->default(
463 1
                'Unauthorised action! This action is not available on Web interface',
464 1
                ['params' => ['class' => $flash_class]]
465
            );
466
467 1
            $this->redirect('/');
468 1
            return;
469
        }
470
471 2
        $this->autoRender = false;
472 2
        $reportsTable = TableRegistry::get('Reports');
0 ignored issues
show
Deprecated Code introduced by
The method Cake\ORM\TableRegistry::get() has been deprecated with message: 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
473
474
        // Fetch all linked reports
475 2
        $reports = $reportsTable->find(
476 2
            'all',
477
            [
478
                'conditions' => [
479 2
                    'sourceforge_bug_id IS NOT NULL',
480
                    'NOT' => [
481
                        'status' => 'resolved',
482
                    ]
483
                ],
484
            ]
485
        );
486
487 2
        foreach ($reports as $report) {
488 2
            $report = $report->toArray();
489
490
            // fetch the new issue status
491 2
            list($issueDetails, $status) = $this->GithubApi->getIssue(
492 2
                Configure::read('GithubRepoPath'),
493 2
                [],
494 2
                $report['sourceforge_bug_id'],
495 2
                Configure::read('GithubAccessToken')
496
            );
497
498 2
            if (! $this->_handleGithubResponse($status, 4, $report['id'], $report['sourceforge_bug_id'])) {
499 1
                Log::error(
500
                    'FAILED: Fetching status of Issue #'
501 1
                        . ($report['sourceforge_bug_id'])
502 1
                        . ' associated with Report#'
503 1
                        . ($report['id'])
504 1
                        . '. Status returned: ' . $status,
505 1
                    ['scope' => 'cron_jobs']
506
                );
507 1
                continue;
508
            }
509
510
            // if Github issue state has changed, update the status of report
511 2
            if ($report['status'] !== $issueDetails['state']) {
512 2
                $rep = $reportsTable->get($report['id']);
513 2
                $rep->status = $this->_getReportStatusFromIssueState($issueDetails['state']);
0 ignored issues
show
Bug introduced by
Accessing status on the interface Cake\Datasource\EntityInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
514
515
                // Save the report
516 2
                $reportsTable->save($rep);
517
518 2
                Log::debug(
519
                    'SUCCESS: Updated status of Report #'
520 2
                    . $report['id'] . ' from state of its linked Github issue #'
521 2
                    . $report['sourceforge_bug_id'] . ' to ' . $rep->status,
0 ignored issues
show
Bug introduced by
Accessing status on the interface Cake\Datasource\EntityInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
522 2
                    ['scope' => 'cron_jobs']
523
                );
524
            }
525
        }
526 2
    }
527
}
528