<commit_before><?php
/* vim: set noexpandtab sw=2 ts=2 sts=2: */

App::uses('AppModel', 'Model');
App::uses('Sanitize', 'Utility');

class Incident extends AppModel {

	public $validate = array(
		'error_message' => array(
			'rule' => 'notEmpty',
			'required'	 => true,
		),
		'pma_version' => array(
			'rule' => 'notEmpty',
			'required'	 => true,
		),
		'php_version' => array(
			'rule' => 'notEmpty',
			'required'	 => true,
		),
		'full_report' => array(
			'rule' => 'notEmpty',
			'required'	 => true,
		),
		'stacktrace' => array(
			'rule' => 'notEmpty',
			'required'	 => true,
		),
		'browser' => array(
			'rule' => 'notEmpty',
			'required'	 => true,
		),
	);

	public $belongsTo = array('Report');

	public $findMethods = array(
		'groupedCount'=> true
	);

	public function createIncidentFromBugReport($bugReport) {
		$schematizedIncident = $this->_getSchematizedIncident($bugReport);
		$closestReport = $this->_getClosestReport($bugReport);

		if($closestReport) {
			$schematizedIncident["report_id"] = $closestReport["Report"]["id"];

			$this->Report->read(null, $closestReport["Report"]["id"]);
			$incidents = $this->Report->getIncidentsWithDifferentStacktrace();
			$schematizedIncident["different_stacktrace"] =
					$this->_hasDifferentStacktrace($schematizedIncident, $incidents);
			return $this->save($schematizedIncident);
		} else {
			$report = $this->_getReportDetails($bugReport);
			$schematizedIncident["different_stacktrace"] = 1;
			$data = array(
				'Incident' => $schematizedIncident,
				'Report' => $report
			);
			return $this->saveAssociated($data);
		}
	}

	protected function _hasDifferentStacktrace($newIncident, $incidents) {
		$newIncident["stacktrace"] = json_decode($newIncident["stacktrace"], true);
		foreach ($incidents as $incident) {
			$incident["Incident"]["stacktrace"] =
					json_decode($incident["Incident"]["stacktrace"], true);
			if ($this->_isSameStacktrace($newIncident["stacktrace"],
					$incident["Incident"]["stacktrace"])) {
				return false;
			}
		}
		return true;
	}

	protected function _getClosestReport($bugReport) {
		List($location, $linenumber) =
				$this->_getIdentifyingLocation($bugReport['exception']['stack']);
		$report = $this->Report->findByLocationAndLinenumberAndPmaVersion(
				$location, $linenumber, $bugReport['pma_version']);
		return $report;
	}

	protected function _getReportDetails($bugReport) {
		List($location, $linenumber) =
				$this->_getIdentifyingLocation($bugReport["exception"]["stack"]);

		$reportDetails = array(
			'error_message' => $bugReport['exception']['message'],
			'error_name' => $bugReport['exception']['name'],
			'status' => 'new',
			'location' => $location,
			'linenumber' => $linenumber,
			'pma_version' => $bugReport['pma_version'],
		);
		return $reportDetails;
	}

	protected function _getSchematizedIncident($bugReport) {
		$bugReport = Sanitize::clean($bugReport);
		$schematizedReport = array(
			'pma_version' => $bugReport['pma_version'],
			'php_version' => $this->_getSimplePhpVersion($bugReport['php_version']),
			'steps' => $bugReport['steps'],
			'error_message' => $bugReport['exception']['message'],
			'error_name' => $bugReport['exception']['name'],
			'browser' => $bugReport['browser_name'] . " "
					. $this->_getMajorVersion($bugReport['browser_version']),
			'user_os' => $bugReport['user_os'],
			'script_name' => $bugReport['script_name'],
			'configuration_storage' => $bugReport['configuration_storage'],
			'server_software' => $this->_getServer($bugReport['server_software']),
			'full_report' => json_encode($bugReport),
			'stacktrace' => json_encode($bugReport['exception']['stack']),
		);

		return $schematizedReport;
	}

	protected function _getIdentifyingLocation($stacktrace) {
		foreach ($stacktrace as $level) {
			if (isset($level["filename"])) {
				if ($level["filename"] !== "tracekit.js"
						&& $level["filename"] !== "error_report.js") {
					return array($level["filename"], $level["line"]);
				} else {
					continue;
				}
			}
			if (isset($level["uri"])) {
				return array($level["uri"], $level["line"]);
			} else {
				return array($level["url"], $level["line"]);
			}
		}
	}

	protected function _getMajorVersion($fullVersion) {
		preg_match("/^\d+/", $fullVersion, $matches);
		$simpleVersion = $matches[0];
		return $simpleVersion;
	}

	protected function _getSimplePhpVersion($phpVersion) {
		preg_match("/^\d+\.\d+/", $phpVersion, $matches);
		$simpleVersion = $matches[0];
		return $simpleVersion;
	}

	protected function _getServer($signature) {
		if (preg_match("/(apache\/\d+\.\d+)|(nginx\/\d+\.\d+)|(iis\/\d+\.\d+)"
				. "|(lighttpd\/\d+\.\d+)/i",
				$signature, $matches)) {
			return $matches[0];
		} else {<commit_msg>Added fallback if error occurs in error_report.js<commit_after><?php
/* vim: set noexpandtab sw=2 ts=2 sts=2: */

App::uses('AppModel', 'Model');
App::uses('Sanitize', 'Utility');

class Incident extends AppModel {

	public $validate = array(
		'error_message' => array(
			'rule' => 'notEmpty',
			'required'	 => true,
		),
		'pma_version' => array(
			'rule' => 'notEmpty',
			'required'	 => true,
		),
		'php_version' => array(
			'rule' => 'notEmpty',
			'required'	 => true,
		),
		'full_report' => array(
			'rule' => 'notEmpty',
			'required'	 => true,
		),
		'stacktrace' => array(
			'rule' => 'notEmpty',
			'required'	 => true,
		),
		'browser' => array(
			'rule' => 'notEmpty',
			'required'	 => true,
		),
	);

	public $belongsTo = array('Report');

	public $findMethods = array(
		'groupedCount'=> true
	);

	public function createIncidentFromBugReport($bugReport) {
		$schematizedIncident = $this->_getSchematizedIncident($bugReport);
		$closestReport = $this->_getClosestReport($bugReport);

		if($closestReport) {
			$schematizedIncident["report_id"] = $closestReport["Report"]["id"];

			$this->Report->read(null, $closestReport["Report"]["id"]);
			$incidents = $this->Report->getIncidentsWithDifferentStacktrace();
			$schematizedIncident["different_stacktrace"] =
					$this->_hasDifferentStacktrace($schematizedIncident, $incidents);
			return $this->save($schematizedIncident);
		} else {
			$report = $this->_getReportDetails($bugReport);
			$schematizedIncident["different_stacktrace"] = 1;
			$data = array(
				'Incident' => $schematizedIncident,
				'Report' => $report
			);
			return $this->saveAssociated($data);
		}
	}

	protected function _hasDifferentStacktrace($newIncident, $incidents) {
		$newIncident["stacktrace"] = json_decode($newIncident["stacktrace"], true);
		foreach ($incidents as $incident) {
			$incident["Incident"]["stacktrace"] =
					json_decode($incident["Incident"]["stacktrace"], true);
			if ($this->_isSameStacktrace($newIncident["stacktrace"],
					$incident["Incident"]["stacktrace"])) {
				return false;
			}
		}
		return true;
	}

	protected function _getClosestReport($bugReport) {
		List($location, $linenumber) =
				$this->_getIdentifyingLocation($bugReport['exception']['stack']);
		$report = $this->Report->findByLocationAndLinenumberAndPmaVersion(
				$location, $linenumber, $bugReport['pma_version']);
		return $report;
	}

	protected function _getReportDetails($bugReport) {
		List($location, $linenumber) =
				$this->_getIdentifyingLocation($bugReport["exception"]["stack"]);

		$reportDetails = array(
			'error_message' => $bugReport['exception']['message'],
			'error_name' => $bugReport['exception']['name'],
			'status' => 'new',
			'location' => $location,
			'linenumber' => $linenumber,
			'pma_version' => $bugReport['pma_version'],
		);
		return $reportDetails;
	}

	protected function _getSchematizedIncident($bugReport) {
		$bugReport = Sanitize::clean($bugReport);
		$schematizedReport = array(
			'pma_version' => $bugReport['pma_version'],
			'php_version' => $this->_getSimplePhpVersion($bugReport['php_version']),
			'steps' => $bugReport['steps'],
			'error_message' => $bugReport['exception']['message'],
			'error_name' => $bugReport['exception']['name'],
			'browser' => $bugReport['browser_name'] . " "
					. $this->_getMajorVersion($bugReport['browser_version']),
			'user_os' => $bugReport['user_os'],
			'script_name' => $bugReport['script_name'],
			'configuration_storage' => $bugReport['configuration_storage'],
			'server_software' => $this->_getServer($bugReport['server_software']),
			'full_report' => json_encode($bugReport),
			'stacktrace' => json_encode($bugReport['exception']['stack']),
		);

		return $schematizedReport;
	}

	protected function _getIdentifyingLocation($stacktrace) {
		foreach ($stacktrace as $level) {
			if (isset($level["filename"])) {
				// ignore unrelated files that sometimes appear in the error report
				if ($level["filename"] === "tracekit.js") {
					continue;
				} elseif($level["filename"] === "error_report.js") {
					// incase the error is in the error_report.js file
					if(!isset($fallback)) {
						$fallback = array($level["filename"], $level["line"]);
					}
					continue;
				} else {
					return array($level["filename"], $level["line"]);
				}
			} elseif (isset($level["scriptname"])) {
				return array($level["scriptname"], $level["line"]);
			} else {
				continue;
			}
		}
		return $fallback;
	}

	protected function _getMajorVersion($fullVersion) {
		preg_match("/^\d+/", $fullVersion, $matches);
		$simpleVersion = $matches[0];
		return $simpleVersion;
	}

	protected function _getSimplePhpVersion($phpVersion) {
		preg_match("/^\d+\.\d+/", $phpVersion, $matches);
		$simpleVersion = $matches[0];
		return $simpleVersion;
	}

	protected function _getServer($signature) {
		if (preg_match("/(apache\/\d+\.\d+)|(nginx\/\d+\.\d+)|(iis\/\d+\.\d+)"
				. "|(lighttpd\/\d+\.\d+)/i",
				$signature, $matches)) {
			return $matches[0];
		} else {
{'fraction_non_alphanumeric': 0.1933627863967944, 'fraction_numerical': 0.0014384054248433166, 'mean_word_length': 4.902971497877502, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 117, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3789704', 'n_tokens_mistral': 3754, 'n_tokens_neox': 3259, 'n_words': 515}