<?php
 class vB_Exception_Database extends vB_Exception { protected $data; private $sql; public function __construct($message = "", $data = [], $code = 0, $connectionfail = false) { $this->sql = $message; $this->data = $data; $mailBody = $this->createMessage(); if (vB::isDebug() AND $this->data) { $message = $mailBody; } if (!empty($this->data['trace'])) { $mailBody .= "\n\n"; $mailBody .= $this->getTraceString($this->data['trace']); } $subject = $this->createSubject(); $config = vB::getConfig(); parent::__construct($message, $code); $timenow = time(); $tempdir = @sys_get_temp_dir(); $unique = 'vb'.md5(vB_Request_Web::$COOKIE_SALT).'.err'; $tempfile = realpath($tempdir).DIRECTORY_SEPARATOR.$unique; if (!empty($data['errno'])) { if ($filedata = @file_get_contents($tempfile)) { $ecode = intval(substr($filedata, 10)); $time = intval(substr($filedata, 0, 10)); if ($time AND ($timenow - $time) < 60 AND intval($data['errno']) == $ecode) { $config['Database']['technicalemail'] = ''; } else { $filedata = $timenow.intval($data['errno']); @file_put_contents($tempfile, $filedata); } } else { $filedata = $timenow.intval($data['errno']); @file_put_contents($tempfile, $filedata); } } if (!empty($config['Database']['technicalemail']) AND ($code !== false)) { try { $mailBody = "<pre>" . vB::getString()->htmlspecialchars($mailBody) . "</pre>"; } catch (Throwable $e) { $mailBody = "<pre>" . htmlspecialchars($mailBody) . "</pre>"; } vB_Mail::create2($config['Database']['technicalemail'], $subject, $mailBody)->sendNow(true); } require_once(DIR . '/includes/functions_log_error.php'); if (!$connectionfail AND function_exists('log_vbulletin_error')) { log_vbulletin_error($mailBody, 'database'); } } public function getSql() { return $this->sql; } public function getData() { if (vB::isDebug()) { return array(); } return $this->data; } private function createSubject() { return "Database Error"; } protected function createMessage() { if (empty($this->data)) { return 'A database error occured, please check the database settings in the config file or enable debug mode for additional information.'; } $message = "
			Database error in {$this->data['appname']} {$this->data['templateversion']}:

			{$this->sql}

			MySQL Error   : {$this->data['error']}
			Error Number  : {$this->data['errno']}
			Request Date  : {$this->data['requestdate']}
			Error Date    : {$this->data['date']}
			Script        : {$this->data['url']}
			Referrer      : {$this->data['referer']}
			IP Address    : {$this->data['ipaddress']}
			Username      : {$this->data['username']}
			Classname     : {$this->data['classname']}
			MySQL Version : {$this->data['mysqlversion']}
		"; return $message; } protected function getTraceString($trace) { $trace_output = "Stack Trace:\n"; foreach ($trace AS $index => $trace_item) { $param = ( in_array($trace_item['function'], array('require', 'require_once', 'include', 'include_once')) ? $trace_item['args'][0] : '' ); foreach (array('file', 'class', 'type', 'function', 'line') AS $key) { if (!isset($trace_item[$key])) { $trace_item[$key] = ''; } } $param = str_replace(DIR, '[path]', $param); $trace_item['file'] = str_replace(DIR, '[path]', $trace_item['file']); $trace_output .= "#$index $trace_item[class]$trace_item[type]$trace_item[function]($param) called in $trace_item[file] on line $trace_item[line]\n"; } $trace_output .= "\n"; return $trace_output; } } 