Passed
Push — master ( 1aba9a...2acbdd )
by William
04:40
created

IncidentsTable::_getClosestReport()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 18
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 13
nc 2
nop 2
dl 0
loc 18
ccs 12
cts 12
cp 1
crap 3
rs 9.8333
c 1
b 0
f 0
1
<?php
2
/* vim: set expandtab sw=4 ts=4 sts=4: */
3
4
/**
5
 * An incident a representing a single incident of a submited bug.
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\Model\Table;
21
22
use Cake\Log\Log;
23
use Cake\Model\Model;
0 ignored issues
show
Bug introduced by
The type Cake\Model\Model was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
24
use Cake\ORM\Table;
25
use Cake\ORM\TableRegistry;
26
27
/**
28
 * An incident a representing a single incident of a submited bug.
29
 */
30
class IncidentsTable extends Table
31
{
32
    /**
33
     * @var array
34
     *
35
     * @see http://book.cakephp.org/2.0/en/models/behaviors.html#using-behaviors
36
     * @see Model::$actsAs
37
     */
38
    public $actsAs = ['Summarizable'];
39
40
    /**
41
     * @var array
42
     *
43
     * @see http://book.cakephp.org/2.0/en/models/model-attributes.html#validate
44
     * @see http://book.cakephp.org/2.0/en/models/data-validation.html
45
     * @see Model::$validate
46
     */
47
    public $validate = [
48
        'pma_version' => [
49
            'rule' => 'notEmpty',
50
            'required' => true,
51
        ],
52
        'php_version' => [
53
            'rule' => 'notEmpty',
54
            'required' => true,
55
        ],
56
        'full_report' => [
57
            'rule' => 'notEmpty',
58
            'required' => true,
59
        ],
60
        'stacktrace' => [
61
            'rule' => 'notEmpty',
62
            'required' => true,
63
        ],
64
        'browser' => [
65
            'rule' => 'notEmpty',
66
            'required' => true,
67
        ],
68
        'stackhash' => [
69
            'rule' => 'notEmpty',
70
            'required' => true,
71
        ],
72
        'user_os' => [
73
            'rule' => 'notEmpty',
74
            'required' => true,
75
        ],
76
        'locale' => [
77
            'rule' => 'notEmpty',
78
            'required' => true,
79
        ],
80
        'script_name' => [
81
            'rule' => 'notEmpty',
82
            'required' => true,
83
        ],
84
        'server_software' => [
85
            'rule' => 'notEmpty',
86
            'required' => true,
87
        ],
88
        'configuration_storage' => [
89
            'rule' => 'notEmpty',
90
            'required' => true,
91
        ],
92
    ];
93
94
    /**
95
     * @var array
96
     *
97
     * @see http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#belongsto
98
     * @see Model::$belongsTo
99
     */
100
101
    /**
102
     * The fields which are summarized in the report page with charts and are also
103
     * used in the overall stats and charts for the website.
104
     *
105
     * @var array
106
     */
107
    public $summarizableFields = [
108
        'browser',
109
        'pma_version',
110
        'php_version',
111
        'locale',
112
        'server_software',
113
        'user_os',
114
        'script_name',
115
        'configuration_storage',
116
    ];
117
118 25
    public function __construct($id = false)
119
    {
120 25
        parent::__construct($id);
121
122 25
        $this->filterTimes = [
0 ignored issues
show
Bug Best Practice introduced by
The property filterTimes does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
123 25
            'all_time' => [
124
                'label' => 'All Time',
125
                'limit' => null,
126
                'group' => "DATE_FORMAT(Incidents.created, '%m %Y')",
127
            ],
128
            'day' => [
129 25
                'label' => 'Last Day',
130 25
                'limit' => date('Y-m-d', strtotime('-1 day')),
131 25
                'group' => "DATE_FORMAT(Incidents.created, '%a %b %d %Y %H')",
132
            ],
133
            'week' => [
134 25
                'label' => 'Last Week',
135 25
                'limit' => date('Y-m-d', strtotime('-1 week')),
136 25
                'group' => "DATE_FORMAT(Incidents.created, '%a %b %d %Y')",
137
            ],
138
            'month' => [
139 25
                'label' => 'Last Month',
140 25
                'limit' => date('Y-m-d', strtotime('-1 month')),
141 25
                'group' => "DATE_FORMAT(Incidents.created, '%a %b %d %Y')",
142
            ],
143
            'year' => [
144 25
                'label' => 'Last Year',
145 25
                'limit' => date('Y-m-d', strtotime('-1 year')),
146 25
                'group' => "DATE_FORMAT(Incidents.created, '%b %u %Y')",
147
            ],
148
        ];
149 25
    }
150
151
    /**
152
     * creates an incident/report record given a raw bug report object.
153
     *
154
     * This gets a decoded bug report from the submitted json body. This has not
155
     * yet been santized. It either adds it as an incident to another report or
156
     * creates a new report if nothing matches.
157
     *
158
     * @param array $bugReport the bug report being submitted
159
     *
160
     * @return array of:
161
     *          1. array of inserted incident ids. If the report/incident was not
162
     *               correctly saved, false is put in it place.
163
     *          2. array of newly created report ids. If no new report was created,
164
     *               an empty array is returned
165
     */
166 1
    public function createIncidentFromBugReport($bugReport)
167
    {
168 1
        if ($bugReport == null) {
169
            return [
170
                'incidents' => [false],
171
                'reports' => []
172
            ];
173
        }
174 1
        $incident_ids = [];    // array to hold ids of all the inserted incidents
175 1
        $new_report_ids = []; // array to hold ids of all newly created reports
176
177
        // Avoid storing too many errors from single report
178 1
        if (isset($bugReport['errors']) && count($bugReport['errors']) > 40) {
179 1
            $bugReport['errors'] = array_slice($bugReport['errors'], 0, 40);
180
        }
181 1
        if (isset($bugReport['exception']['stack']) && count($bugReport['exception']['stack']) > 40) {
182 1
            $bugReport['exception']['stack'] = array_slice($bugReport['exception']['stack'], 0, 40);
183
        }
184
185
        // Also sanitizes the bug report
186 1
        $schematizedIncidents = $this->_getSchematizedIncidents($bugReport);
187 1
        $incidentsTable = TableRegistry::get('Incidents');
0 ignored issues
show
Deprecated Code introduced by
The function Cake\ORM\TableRegistry::get() has been deprecated: 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

187
        $incidentsTable = /** @scrutinizer ignore-deprecated */ TableRegistry::get('Incidents');

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

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

Loading history...
188 1
        $reportsTable = TableRegistry::get('Reports');
0 ignored issues
show
Deprecated Code introduced by
The function Cake\ORM\TableRegistry::get() has been deprecated: 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

188
        $reportsTable = /** @scrutinizer ignore-deprecated */ TableRegistry::get('Reports');

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

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

Loading history...
189 1
        foreach ($schematizedIncidents as $index => $si) {
190
            // find closest report. If not found, create a new report.
191 1
            $closestReport = $this->_getClosestReport($bugReport, $index);
192 1
            if ($closestReport) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $closestReport of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
193 1
                $si['report_id'] = $closestReport['id'];
194 1
                $si = $incidentsTable->newEntity($si);
195 1
                $si->created = date('Y-m-d H:i:s', time());
0 ignored issues
show
Bug introduced by
Accessing created on the interface Cake\Datasource\EntityInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
196 1
                $si->modified = date('Y-m-d H:i:s', time());
0 ignored issues
show
Bug introduced by
Accessing modified on the interface Cake\Datasource\EntityInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
197
198 1
                $this->_logLongIncidentSubmissions($si, $incident_ids);
0 ignored issues
show
Bug introduced by
$si of type Cake\Datasource\EntityInterface is incompatible with the type array expected by parameter $si of App\Model\Table\Incident...ngIncidentSubmissions(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

198
                $this->_logLongIncidentSubmissions(/** @scrutinizer ignore-type */ $si, $incident_ids);
Loading history...
199 1
                if (in_array(false, $incident_ids)) {
200 1
                    break;
201
                }
202
            } else {
203
                // no close report. Create a new report.
204 1
                $report = $this->_getReportDetails($bugReport, $index);
205
206 1
                $this->_logLongIncidentSubmissions($si, $incident_ids);
207 1
                if (in_array(false, $incident_ids)) {
208
                    break;
209
                }
210
211 1
                $report = $reportsTable->newEntity($report);
212 1
                $report->created = date('Y-m-d H:i:s', time());
213 1
                $report->modified = date('Y-m-d H:i:s', time());
214 1
                $reportsTable->save($report);
215
216 1
                $si['report_id'] = $report->id;
217 1
                $new_report_ids[] = $report->id;
218 1
                $si = $incidentsTable->newEntity($si);
219 1
                $si->created = date('Y-m-d H:i:s', time());
220 1
                $si->modified = date('Y-m-d H:i:s', time());
221
            }
222
223 1
            $isSaved = $incidentsTable->save($si);
224 1
            if ($isSaved) {
225 1
                array_push($incident_ids, $si->id);
226 1
                if (! $closestReport) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $closestReport of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
227
                    // add notifications entry
228 1
                    $tmpIncident = $incidentsTable->findById($si->id)->all()->first();
229 1
                    if (! TableRegistry::get('Notifications')->addNotifications(intval($tmpIncident['report_id']))) {
0 ignored issues
show
Deprecated Code introduced by
The function Cake\ORM\TableRegistry::get() has been deprecated: 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

229
                    if (! /** @scrutinizer ignore-deprecated */ TableRegistry::get('Notifications')->addNotifications(intval($tmpIncident['report_id']))) {

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

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

Loading history...
230
                        Log::write(
231
                            'error',
232
                            'ERRORED: Notification::addNotifications() failed on Report#'
233
                                . $tmpIncident['report_id'],
234 1
                            'alert'
235
                        );
236
                    }
237
                }
238
            } else {
239 1
                array_push($incident_ids, false);
240
            }
241
        }
242
243
        return [
244 1
            'incidents' => $incident_ids,
245 1
            'reports' => $new_report_ids
246
        ];
247
    }
248
249
    /**
250
     * retrieves the closest report to a given bug report.
251
     *
252
     * it checks for another report with the same line number, filename and
253
     * pma_version
254
     *
255
     * @param array $bugReport the bug report being checked
256
     *                         Integer $index: for php exception type
257
     * @param int   $index     The report index
258
     *
259
     * @return array the first similar report or null
260
     */
261 2
    protected function _getClosestReport($bugReport, $index = 0)
262
    {
263 2
        if (isset($bugReport['exception_type'])
264 2
            && $bugReport['exception_type'] == 'php'
265
        ) {
266 1
            $location = $bugReport['errors'][$index]['file'];
267 1
            $linenumber = $bugReport['errors'][$index]['lineNum'];
268
        } else {
269
            list($location, $linenumber) =
270 2
                    $this->_getIdentifyingLocation($bugReport['exception']['stack']);
271
        }
272 2
        $report = TableRegistry::get('Reports')->findByLocationAndLinenumberAndPmaVersion(
0 ignored issues
show
Deprecated Code introduced by
The function Cake\ORM\TableRegistry::get() has been deprecated: 3.6.0 Use \Cake\ORM\Locator\TableLocator::get() instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

272
        $report = /** @scrutinizer ignore-deprecated */ TableRegistry::get('Reports')->findByLocationAndLinenumberAndPmaVersion(

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

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

Loading history...
273 2
            $location,
274 2
            $linenumber,
275 2
            $this->getStrippedPmaVersion($bugReport['pma_version'])
276 2
        )->all()->first();
277
278 2
        return $report;
279
    }
280
281
    /**
282
     * creates the report data from an incident that has no related report.
283
     *
284
     * @param array $bugReport the bug report the report record is being created for
285
     *                         Integer $index: for php exception type
286
     * @param int   $index     The report index
287
     *
288
     * @return array an array with the report fields can be used with Report->save
289
     */
290 2
    protected function _getReportDetails($bugReport, $index = 0)
291
    {
292 2
        if (isset($bugReport['exception_type'])
293 2
            && $bugReport['exception_type'] == 'php'
294
        ) {
295 2
            $location = $bugReport['errors'][$index]['file'];
296 2
            $linenumber = $bugReport['errors'][$index]['lineNum'];
297
            $reportDetails = [
298 2
                'error_message' => $bugReport['errors'][$index]['msg'],
299 2
                'error_name' => $bugReport['errors'][$index]['type'],
300
            ];
301 2
            $exception_type = 1;
302
        } else {
303
            list($location, $linenumber) =
304 2
                $this->_getIdentifyingLocation($bugReport['exception']['stack']);
305
306
            $reportDetails = [
307 2
                'error_message' => $bugReport['exception']['message'],
308 2
                'error_name' => $bugReport['exception']['name'],
309
            ];
310 2
            $exception_type = 0;
311
        }
312
313 2
        $reportDetails = array_merge(
314 2
            $reportDetails,
315
            [
316 2
                'status' => 'new',
317 2
                'location' => $location,
318 2
                'linenumber' => is_null($linenumber) ? 0 : $linenumber,
319 2
                'pma_version' => $this->getStrippedPmaVersion($bugReport['pma_version']),
320 2
                'exception_type' => $exception_type,
321
            ]
322
        );
323
324 2
        return $reportDetails;
325
    }
326
327
    /**
328
     * creates the incident data from the submitted bug report.
329
     *
330
     * @param array $bugReport the bug report the report record is being created for
331
     *
332
     * @return array an array of schematized incident.
333
     *               Can be used with Incident->save
334
     */
335 2
    protected function _getSchematizedIncidents($bugReport)
336
    {
337
        //$bugReport = Sanitize::clean($bugReport, array('escape' => false));
338 2
        $schematizedReports = [];
339
        $schematizedCommonReport = [
340 2
            'pma_version' => $this->getStrippedPmaVersion($bugReport['pma_version']),
341 2
            'php_version' => $this->_getSimpleVersion($bugReport['php_version'], 2),
342 2
            'browser' => $bugReport['browser_name'] . ' '
343 2
                    . $this->_getSimpleVersion($bugReport['browser_version'], 1),
344 2
            'user_os' => $bugReport['user_os'],
345 2
            'locale' => $bugReport['locale'],
346 2
            'configuration_storage' => $bugReport['configuration_storage'],
347 2
            'server_software' => $this->_getServer($bugReport['server_software']),
348 2
            'full_report' => json_encode($bugReport),
349
        ];
350
351 2
        if (isset($bugReport['exception_type'])
352 2
            && $bugReport['exception_type'] == 'php'
353
        ) {
354
            // for each "errors"
355 2
            foreach ($bugReport['errors'] as $error) {
356 2
                $tmpReport = array_merge(
357 2
                    $schematizedCommonReport,
358
                    [
359 2
                        'error_name' => $error['type'],
360 2
                        'error_message' => $error['msg'],
361 2
                        'script_name' => $error['file'],
362 2
                        'stacktrace' => json_encode($error['stackTrace']),
363 2
                        'stackhash' => $error['stackhash'],
364 2
                        'exception_type' => 1,         // 'php'
365
                    ]
366
                );
367 2
                array_push($schematizedReports, $tmpReport);
368
            }
369
        } else {
370 2
            $tmpReport = array_merge(
371 2
                $schematizedCommonReport,
372
                [
373 2
                    'error_name' => $bugReport['exception']['name'],
374 2
                    'error_message' => $bugReport['exception']['message'],
375 2
                    'script_name' => $bugReport['script_name'],
376 2
                    'stacktrace' => json_encode($bugReport['exception']['stack']),
377 2
                    'stackhash' => $this->getStackHash($bugReport['exception']['stack']),
378 2
                    'exception_type' => 0,     //'js'
379
                ]
380
            );
381
382 2
            if (isset($bugReport['steps'])) {
383 2
                $tmpReport['steps'] = $bugReport['steps'];
384
            }
385 2
            array_push($schematizedReports, $tmpReport);
386
        }
387
388 2
        return $schematizedReports;
389
    }
390
391
    /**
392
     * Gets the identifiying location info from a stacktrace.
393
     *
394
     * This is used to skip stacktrace levels that are within the error reporting js
395
     * files that sometimes appear in the stacktrace but are not related to the bug
396
     * report
397
     *
398
     * returns two things in an array:
399
     * - the first element is the filename/scriptname of the error
400
     * - the second element is the linenumber of the error
401
     *
402
     * @param array $stacktrace the stacktrace being examined
403
     *
404
     * @return array an array with the filename/scriptname and linenumber of the
405
     *               error
406
     */
407 4
    protected function _getIdentifyingLocation($stacktrace)
408
    {
409
        $fallback = [
410 4
            'UNKNOWN',
411
            0,
412
        ];
413 4
        foreach ($stacktrace as $level) {
414 4
            if (isset($level['filename'])) {
415
                // ignore unrelated files that sometimes appear in the error report
416 4
                if ($level['filename'] === 'tracekit/tracekit.js') {
417 1
                    continue;
418 4
                } elseif ($level['filename'] === 'error_report.js') {
419
                    // in case the error really is in the error_report.js file save it for
420
                    // later
421 1
                    if ($fallback[0] == 'UNKNOWN') {
422
                        $fallback = [
423 1
                            $level['filename'],
424 1
                            $level['line'],
425
                        ];
426
                    }
427 1
                    continue;
428
                }
429
430
                return [
431 4
                    $level['filename'],
432 4
                    $level['line'],
433
                ];
434 1
            } elseif (isset($level['scriptname'])) {
435
                return [
436 1
                    $level['scriptname'],
437 1
                    $level['line'],
438
                ];
439
            }
440 1
            continue;
441
        }
442
443 1
        return $fallback;
444
    }
445
446
    /**
447
     * Gets a part of a version string according to the specified version Length.
448
     *
449
     * @param string $versionString the version string
450
     * @param string $versionLength the number of version components to return. eg
451
     *                              1 for major version only and 2 for major and
452
     *                              minor version
453
     *
454
     * @return string the major and minor version part
455
     */
456 3
    protected function _getSimpleVersion($versionString, $versionLength)
457
    {
458 3
        $versionLength = (int) $versionLength;
459 3
        if ($versionLength < 1) {
460 1
            $versionLength = 1;
461
        }
462
        /* modify the re to accept a variable number of version components. I
463
         * atleast take one component and optionally get more components if need be.
464
         * previous code makes sure that the $versionLength variable is a positive
465
         * int
466
         */
467 3
        $result = preg_match(
468 3
            "/^(\d+\.){" . ($versionLength - 1) . "}\d+/",
469 3
            $versionString,
470 3
            $matches
471
        );
472 3
        if ($result) {
473 3
            $simpleVersion = $matches[0];
474
475 3
            return $simpleVersion;
476
        }
477
478
        return $versionString;
479
    }
480
481
    /**
482
     * Returns the version string stripped of
483
     * 'deb', 'ubuntu' and other suffixes
484
     *
485
     * @param string $versionString phpMyAdmin version
486
     *
487
     * @return string stripped phpMyAdmin version
488
     */
489 11
    public function getStrippedPmaVersion($versionString)
490
    {
491 11
        $allowedRegexp = '/^(\d+)(\.\d+){0,3}(\-.*)?/';
492 11
        $matches = [];
493
494
        // Check if $versionString matches the regexp
495
        // and store the matched strings
496 11
        if (preg_match($allowedRegexp, $versionString, $matches)) {
497 11
            return $matches[0];
498
        }
499
500
        // If $versionString does not match the regexp at all,
501
        // leave it as it is
502
        return $versionString;
503
    }
504
505
    /**
506
     * Gets the server name and version from the server signature.
507
     *
508
     * @param string $signature the server signature
509
     *
510
     * @return string the server name and version or UNKNOWN
511
     */
512 3
    protected function _getServer($signature)
513
    {
514 3
        if (preg_match(
515
            "/(apache\/\d+\.\d+)|(nginx\/\d+\.\d+)|(iis\/\d+\.\d+)"
516 3
                . "|(lighttpd\/\d+\.\d+)/i",
517 3
            $signature,
518 3
            $matches
519
        )) {
520 3
            return $matches[0];
521
        }
522
523 1
        return 'UNKNOWN';
524
    }
525
526
    /**
527
     * returns the hash pertaining to a stacktrace.
528
     *
529
     * @param array $stacktrace the stacktrace in question
530
     *
531
     * @return string the hash string of the stacktrace
532
     */
533 3
    public function getStackHash($stacktrace)
534
    {
535 3
        $handle = hash_init('md5');
536 3
        foreach ($stacktrace as $level) {
537
            $elements = [
538 3
                'filename',
539
                'scriptname',
540
                'line',
541
                'func',
542
                'column',
543
            ];
544 3
            foreach ($elements as $element) {
545 3
                if (! isset($level[$element])) {
546 3
                    continue;
547
                }
548 3
                hash_update($handle, $level[$element]);
549
            }
550
        }
551
552 3
        return hash_final($handle);
553
    }
554
555
    /**
556
     * Checks the length of stacktrace and full_report
557
     * and logs if it is greater than what it can hold
558
     *
559
     * @param array $si           submitted incident
560
     * @param array $incident_ids incident IDs
561
     *
562
     * @return array $incident_ids
563
     */
564 1
    private function _logLongIncidentSubmissions($si, &$incident_ids)
565
    {
566
567 1
        $stacktraceLength = mb_strlen($si['stacktrace']);
568 1
        $fullReportLength = mb_strlen($si['full_report']);
569 1
        $errorMessageLength = mb_strlen($si['error_message']);
570
571 1
        if ($stacktraceLength > 65535
572 1
            || $fullReportLength > 65535
573 1
            || $errorMessageLength > 200 // length of field in 'incidents' table
574
        ) {
575
            // If length of report is longer than
576
            // what can fit in the table field,
577
            // we log it and don't save it in the database
578 1
            Log::error(
579
                'Too long data submitted in the incident. The length of stacktrace: '
580 1
                . $stacktraceLength . ', the length of bug report: '
581 1
                . $fullReportLength . ', the length of error message: '
582 1
                . $errorMessageLength . '. The full incident reported was as follows: '
583 1
                . json_encode($si)
584
            );
585
586
            // add a 'false' to the return array
587 1
            array_push($incident_ids, false);
588
        }
589 1
    }
590
}
591