_writeLog) {
$this->_startTime = date('Y-m-d H:i:s');
}
$this->_idSession = Zend_Session::getId();
$this->_clearOldHistory();
return $this;
}
public function getOption($name)
{
if (isset($this->_options[$name])) {
return $this->_options[$name];
}
return null;
}
public function setLogBacktrace($flag)
{
$this->_logBacktrace = (bool) $flag;
}
public function setWriteLog($flag)
{
$this->_writeLog = (bool) $flag;
}
/**
* @return Qs_Debug
* @throws Qs_Exception
*/
public static function getInstance()
{
if (null === Qs_Debug::$_instance) {
if (!Zend_Registry::isRegistered('config')) {
throw new Qs_Exception('Config is not registered in Zend_Registry');
}
Qs_Debug::$_instance = new Qs_Debug(Zend_Registry::get('config')->debug);
}
return Qs_Debug::$_instance;
}
public function setErrorReporting($errorReporting)
{
$this->_previousErrorReporting = $this->_errorReporting;
$this->_errorReporting = $errorReporting;
error_reporting($errorReporting);
set_error_handler([$this, 'errorHandler'], $this->_errorReporting);
}
public function getErrorReporting()
{
return $this->_errorReporting;
}
public function restoreErrorReporting()
{
$this->_errorReporting = $this->_previousErrorReporting;
set_error_handler([$this, 'errorHandler'], $this->_errorReporting);
}
protected function _clearOldHistory()
{
if ($this->_writeLog) {
if ($this->_count > $this->getOption('clearOverflow')) {
$select = $this->_db->select();
$select->from($this->_tableName, 'id')
->order('id DESC')
->limit(1, $this->getOption('clearLimit') - 1);
if (false !== ($maxId = $this->_db->fetchOne($select))) {
$this->_db->delete($this->_tableName, 'id < ' . $this->_db->quote($maxId, Qs_Db::INT_TYPE));
}
}
}
}
public function errorHandler($errNo, $errMsg, $filename, $linenNum, $errContext)
{
// Ignore warnings and notices from lib/Zend
if (in_array($errNo, [E_WARNING, E_NOTICE]) && false !== strpos($filename, '/Zend/')) {
return true;
}
$this->_writeLog([
//Деякі меседжі містять в собі шляхи до файлів
'message' => $this->_filterFilePaths($errMsg),
'errorNumber' => $errNo,
'file' => $this->_filterFilePaths($filename),
'line' => $linenNum,
]);
return true;
}
/**
* @param $message
* @param int $errNo
* @deprecated It doesn't pass file name and line number. Please, use trigger_error function instead.
* @throws Qs_Exception
*/
public static function log($message, $errNo = E_WARNING)
{
Qs_Debug::getInstance()->errorHandler($errNo, $message, null, null, null);
}
public static function logStdError($message)
{
if (false !== ($handle = fopen('php://stderr', 'w'))) {
fwrite($handle, $message);
fclose($handle);
}
}
protected function _writeLog(array $data)
{
if (!$this->_writeLog) {
return false;
}
if (!isset($data['message'])) {
return false;
}
if (!isset($data['errorNumber'])) {
$data['errorNumber'] = 0;
}
ksort($data);
$uid = md5(implode('', $data));
$data = array_merge($data, [
'uid' => $uid,
'backtrace' => $this->_logBacktrace ? gzcompress(serialize(Qs_Debug::_getBackTrace()), 9) : null,
'ip' => $_SERVER['REMOTE_ADDR'],
'count' => new Zend_Db_Expr('count + 1'),
'idSession' => $this->_idSession,
'serverName' => $_SERVER['SERVER_NAME'],
'url' => (string) Qs_Request::getUrl(),
'added' => date('Y-m-d H:i:s'),
]);
$db = Qs_Db::getInstance();
$table = Qs_Db::getTableName('Log');
$updated = $db->update($table, $data, $db->quoteInto('uid = ?', $uid));
if (!$updated) {
$data['count'] = 1;
$db->insert($table, $data);
}
$this->_writed = true;
return true;
}
/**
* Remove objects instances from array
* (раніше приймав занчення по посиланню, в РНР 5.4 вилізла проблема, debug_backtrace повертає масив з посиланнями
* на об'єкти, тому зміни в $array моломи сайт)
* @param array $array
* @return array
*/
protected static function _removeObjects(array $array)
{
$result = [];
foreach ($array as $key => $value) {
if (is_array($value)) {
$result[$key] = Qs_Debug::_removeObjects($value);
} else if (is_object($value)) {
$result[$key] = get_class($value) . ' Object';
} else {
$result[$key] = $value;
}
}
return $result;
}
protected static function _getBackTrace()
{
$backtrace = debug_backtrace();
array_shift($backtrace);
array_shift($backtrace);
array_shift($backtrace);
$backtrace = Qs_Debug::_removeObjects($backtrace);
return $backtrace;
}
public function getDebugInformation()
{
if (!$this->_writeLog || !$this->_writed) {
return [];
}
$select = $this->_db->select();
$select->from($this->_getPair(), ['added', 'errorNumber', 'message', 'file', 'line']);
$select->where("`{$this->_tableAlias}`.`added` >= " . $this->_db->quote($this->_startTime));
$select->where("`{$this->_tableAlias}`.`idSession` = " . $this->_db->quote($this->_idSession));
$select->order($this->_tableAlias . '.id');
$list = $this->_db->fetchAll($select);
$errorTypes = $this->getConfigArray('errorTypes');
foreach ($list as &$row) {
$row['errorType'] = Qs_Array::get($errorTypes, $row['errorNumber']);
}
return $list;
}
public function getSessionErrorsCount()
{
if (!$this->_writeLog) {
return [];
}
$select = $this->_db->select();
$select->from($this->_getPair(null, 'l'), 'COUNT(*)');
$select->where("`l`.`idSession` = ?", $this->_idSession);
return $this->_db->fetchOne($select);
}
public static function getExceptionMessage(Exception $e)
{
$firstTrace = current($e->getTrace());
$fileFullName = str_replace(realpath(constant('BASE_PATH') . '/../') . '/', '', $e->getFile());
$html = '
'
. 'Uncaught ' . get_class($e) . ' exception in
'
. 'File: '
. $fileFullName . ': ' . $e->getLine() . '
'
. 'Method: ' . $firstTrace['class'] . $firstTrace['type'] . $firstTrace['function'] . '
'
. 'Message: '
. nl2br(strip_tags($e->getMessage()))
. ''
. '
';
if ($e instanceof Zend_Db_Statement_Exception
&& false !== ($lastQueryProfile = Qs_Db::getInstance()->getProfiler()->getLastQueryProfile())
) {
if (Qs_Request::isXmlHttpRequest()) {
$html .= "\nLast Query:\n" . Qs_SqlFormatter::format($lastQueryProfile->getQuery(), false);
} else {
$html .= '
Last query:
' . print_r($debugBacktrace, true) . ''; } protected function _sendExceptionNotification($exception) { $message = Qs_Debug::getExceptionMessage($exception); $backtrace = Qs_Debug::getExceptionBacktrace($exception); $html = $message . '
' . htmlspecialchars(print_r($GLOBALS[$name], true)) . ''; } $html .= '
' . ($index + 1) . ' | '; Qs_Debug::dumpSql($query->getQuery()); echo ' |