Index: branches/5.2.x/core/kernel/utility/logger.php
===================================================================
diff -u
--- branches/5.2.x/core/kernel/utility/logger.php (revision 0)
+++ branches/5.2.x/core/kernel/utility/logger.php (revision 15552)
@@ -0,0 +1,1364 @@
+_debugMode = $this->Application->isDebugMode();
+ $this->setState(isset($vars['EnableSystemLog']) ? $vars['EnableSystemLog'] : self::STATE_DISABLED);
+ $this->_maxLogLevel = isset($vars['SystemLogMaxLevel']) ? (int)$vars['SystemLogMaxLevel'] : self::LL_NOTICE;
+
+ foreach ($methods_to_call as $method_to_call) {
+ call_user_func_array(Array ($this, $method_to_call[0]), $method_to_call[1]);
+ }
+
+ if ( !kUtil::constOn('DBG_ZEND_PRESENT') && !$this->Application->isDebugMode() ) {
+ // don't report error on screen if debug mode is turned off
+ error_reporting(0);
+ ini_set('display_errors', 0);
+ }
+
+ register_shutdown_function(Array ($this, 'catchLastError'));
+ }
+
+ /**
+ * Sets state of the logged (enabled/user-only/disabled)
+ *
+ * @param $new_state
+ * @return void
+ * @access public
+ */
+ public function setState($new_state = null)
+ {
+ if ( isset($new_state) ) {
+ $this->_state = (int)$new_state;
+ }
+
+ if ( $this->_state === self::STATE_ENABLED ) {
+ $this->_enableErrorHandling();
+ }
+ elseif ( $this->_state === self::STATE_DISABLED ) {
+ $this->_disableErrorHandling();
+ }
+ }
+
+ /**
+ * Enable error/exception handling capabilities
+ *
+ * @return void
+ * @access protected
+ */
+ protected function _enableErrorHandling()
+ {
+ $this->_disableErrorHandling();
+
+ $this->_handlers[self::LL_ERROR] = new kErrorHandlerStack($this);
+ $this->_handlers[self::LL_CRITICAL] = new kExceptionHandlerStack($this);
+ }
+
+ /**
+ * Disables error/exception handling capabilities
+ *
+ * @return void
+ * @access protected
+ */
+ protected function _disableErrorHandling()
+ {
+ foreach ($this->_handlers as $index => $handler) {
+ $this->_handlers[$index]->__destruct();
+ unset($this->_handlers[$index]);
+ }
+ }
+
+ /**
+ * Initializes new log record. Use "kLogger::write" to save to db/disk
+ *
+ * @param string $message
+ * @param int $code
+ * @return kLogger
+ * @access public
+ */
+ public function prepare($message = '', $code = null)
+ {
+ $this->_logRecord = Array (
+ 'LogUniqueId' => kUtil::generateId(),
+ 'LogMessage' => $message,
+ 'LogLevel' => self::LL_INFO,
+ 'LogCode' => $code,
+ 'LogType' => self::LT_OTHER,
+ 'LogHostname' => $_SERVER['HTTP_HOST'],
+ 'LogRequestSource' => php_sapi_name() == 'cli' ? 2 : 1,
+ 'LogRequestURI' => php_sapi_name() == 'cli' ? implode(' ', $GLOBALS['argv']) : $_SERVER['REQUEST_URI'],
+ 'LogUserId' => USER_GUEST,
+ 'IpAddress' => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '',
+ 'LogSessionKey' => 0,
+ 'LogProcessId' => getmypid(),
+ 'LogUserData' => '',
+ 'LogNotificationStatus' => self::LNS_DISABLED,
+ );
+
+ if ( $this->Application->isAdmin ) {
+ $this->_logRecord['LogInterface'] = defined('CRON') && CRON ? self::LI_CRON_ADMIN : self::LI_ADMIN;
+ }
+ else {
+ $this->_logRecord['LogInterface'] = defined('CRON') && CRON ? self::LI_CRON_FRONT : self::LI_FRONT;
+ }
+
+ if ( $this->Application->InitDone ) {
+ $this->_logRecord['LogUserId'] = $this->Application->RecallVar('user_id');
+ $this->_logRecord['LogSessionKey'] = $this->Application->GetSID();
+ }
+
+ return $this;
+ }
+
+ /**
+ * Sets one or more fields of log record
+ *
+ * @param string|Array $field_name
+ * @param string|null $field_value
+ * @return kLogger
+ * @access public
+ * @throws UnexpectedValueException
+ */
+ public function setLogField($field_name, $field_value = null)
+ {
+ if ( isset($field_value) ) {
+ $this->_logRecord[$field_name] = $field_value;
+ }
+ elseif ( is_array($field_name) ) {
+ $this->_logRecord = array_merge($this->_logRecord, $field_name);
+ }
+ else {
+ throw new UnexpectedValueException('Invalid arguments');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Sets user data
+ *
+ * @param string $data
+ * @param bool $as_array
+ * @return kLogger
+ * @access public
+ */
+ public function setUserData($data, $as_array = false)
+ {
+ if ( $as_array ) {
+ $data = serialize((array)$data);
+ }
+
+ return $this->setLogField('LogUserData', $data);
+ }
+
+ /**
+ * Add user data
+ *
+ * @param string $data
+ * @param bool $as_array
+ * @return kLogger
+ * @access public
+ */
+ public function addUserData($data, $as_array = false)
+ {
+ $new_data = $this->_logRecord['LogUserData'];
+
+ if ( $as_array ) {
+ $new_data = $new_data ? unserialize($new_data) : Array ();
+ $new_data[] = $data;
+ $new_data = serialize($new_data);
+ }
+ else {
+ $new_data .= ($new_data ? PHP_EOL : '') . $data;
+ }
+
+ return $this->setLogField('LogUserData', $new_data);
+ }
+
+ /**
+ * Adds event to log record
+ *
+ * @param kEvent $event
+ * @return kLogger
+ * @access public
+ */
+ public function addEvent(kEvent $event)
+ {
+ $this->_logRecord['LogEventName'] = (string)$event;
+
+ return $this;
+ }
+
+ /**
+ * Adds log source file & file to log record
+ *
+ * @param string|Array $file_or_trace file path
+ * @param int $line file line
+ * @return kLogger
+ * @access public
+ */
+ public function addSource($file_or_trace = '', $line = 0)
+ {
+ if ( is_array($file_or_trace) ) {
+ $trace_info = $file_or_trace[0];
+ $this->_logRecord['LogSourceFilename'] = $trace_info['file'];
+ $this->_logRecord['LogSourceFileLine'] = $trace_info['line'];
+ }
+ else {
+ $this->_logRecord['LogSourceFilename'] = $file_or_trace;
+ $this->_logRecord['LogSourceFileLine'] = $line;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Adds session contents to log record
+ *
+ * @param bool $include_optional Include optional session variables
+ * @return kLogger
+ * @access public
+ */
+ public function addSessionData($include_optional = false)
+ {
+ if ( $this->Application->InitDone ) {
+ $this->_logRecord['LogSessionData'] = serialize($this->Application->Session->getSessionData($include_optional));
+ }
+
+ return $this;
+ }
+
+ /**
+ * Adds user request information to log record
+ *
+ * @return kLogger
+ * @access public
+ */
+ public function addRequestData()
+ {
+ $request_data = Array ();
+ $request_variables = Array ('_GET' => $_GET, '_POST' => $_POST, '_COOKIE' => $_COOKIE);
+
+ foreach ($request_variables as $title => $data) {
+ if ( !$data ) {
+ continue;
+ }
+
+ $request_data[$title] = $data;
+ }
+
+ $this->_logRecord['LogRequestData'] = serialize($request_data);
+
+ return $this;
+ }
+
+ /**
+ * Adds trace to log record
+ *
+ * @param Array $trace
+ * @param int $skip_levels
+ * @param Array $skip_files
+ * @return kLogger
+ * @access public
+ */
+ public function addTrace($trace = null, $skip_levels = 1, $skip_files = null)
+ {
+ $trace = $this->createTrace($trace, $skip_levels, $skip_files);
+
+ foreach ($trace as $trace_index => $trace_info) {
+ if ( isset($trace_info['args']) ) {
+ $trace[$trace_index]['args'] = $this->_implodeObjects($trace_info['args']);
+ }
+ }
+
+ $this->_logRecord['LogBacktrace'] = serialize($this->_removeObjectsFromTrace($trace));
+
+ return $this;
+ }
+
+ /**
+ * Remove objects from trace, since before PHP 5.2.5 there wasn't possible to remove them initially
+ *
+ * @param Array $trace
+ * @return Array
+ * @access protected
+ */
+ protected function _removeObjectsFromTrace($trace)
+ {
+ if ( version_compare(PHP_VERSION, '5.3', '>=') ) {
+ return $trace;
+ }
+
+ $trace_indexes = array_keys($trace);
+
+ foreach ($trace_indexes as $trace_index) {
+ unset($trace[$trace_index]['object']);
+ }
+
+ return $trace;
+ }
+
+ /**
+ * Implodes object to prevent memory leaks
+ *
+ * @param Array $array
+ * @return Array
+ * @access protected
+ */
+ protected function _implodeObjects($array)
+ {
+ $ret = Array ();
+
+ foreach ($array as $key => $value) {
+ if ( is_array($value) ) {
+ $ret[$key] = $this->_implodeObjects($value);
+ }
+ elseif ( is_object($value) ) {
+ if ( $value instanceof kEvent ) {
+ $ret[$key] = 'Event: ' . (string)$value;
+ }
+ elseif ( $value instanceof kBase ) {
+ $ret[$key] = (string)$value;
+ }
+ else {
+ $ret[$key] = 'Class: ' . get_class($value);
+ }
+ }
+ else {
+ $ret[$key] = $value;
+ }
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Removes first N levels from trace
+ *
+ * @param Array $trace
+ * @param int $levels
+ * @param Array $files
+ * @return Array
+ * @access public
+ */
+ public function createTrace($trace = null, $levels = null, $files = null)
+ {
+ if ( !isset($trace) ) {
+ $trace = debug_backtrace(false);
+ }
+
+ if ( !$trace ) {
+ // no trace information
+ return $trace;
+ }
+
+ if ( isset($levels) && is_numeric($levels) ) {
+ for ($i = 0; $i < $levels; $i++) {
+ array_shift($trace);
+ }
+ }
+
+ if ( isset($files) && is_array($files) ) {
+ while (true) {
+ $trace_info = $trace[0];
+ $file = isset($trace_info['file']) ? basename($trace_info['file']) : '';
+
+ if ( !in_array($file, $files) ) {
+ break;
+ }
+
+ array_shift($trace);
+ }
+ }
+
+ return $trace;
+ }
+
+ /**
+ * Adds PHP error to log record
+ *
+ * @param int $errno
+ * @param string $errstr
+ * @param string $errfile
+ * @param int $errline
+ * @return kLogger
+ * @access public
+ */
+ public function addError($errno, $errstr, $errfile = null, $errline = null)
+ {
+ $errstr = self::expandMessage($errstr, !$this->_debugMode);
+ $this->_logRecord['LogLevel'] = $this->_getLogLevelByErrorNo($errno);
+
+ if ( $this->isLogType(self::LT_DATABASE, $errstr) ) {
+ list ($errno, $errstr, $sql) = self::parseDatabaseError($errstr);
+
+ $this->_logRecord['LogType'] = self::LT_DATABASE;
+ $this->_logRecord['LogUserData'] = $sql;
+
+ $trace = $this->createTrace(null, 4, $this->_ignoreInTrace);
+ $this->addSource($trace);
+ $this->addTrace($trace, 0);
+ }
+ else {
+ $this->_logRecord['LogType'] = self::LT_PHP;
+
+ $this->addSource((string)$errfile, $errline);
+ $this->addTrace(null, 4);
+ }
+
+ $this->_logRecord['LogCode'] = $errno;
+ $this->_logRecord['LogMessage'] = $errstr;
+
+ return $this;
+ }
+
+ /**
+ * Adds PHP exception to log record
+ *
+ * @param Exception $exception
+ * @return kLogger
+ * @access public
+ */
+ public function addException($exception)
+ {
+ $errstr = self::expandMessage($exception->getMessage(), !$this->_debugMode);
+ $this->_logRecord['LogLevel'] = self::LL_CRITICAL;
+
+ if ( $this->isLogType(self::LT_DATABASE, $errstr) ) {
+ list ($errno, $errstr, $sql) = self::parseDatabaseError($errstr);
+
+ $this->_logRecord['LogType'] = self::LT_DATABASE;
+ $this->_logRecord['LogUserData'] = $sql;
+
+ $trace = $this->createTrace($exception->getTrace(), null, $this->_ignoreInTrace);
+ $this->addSource($trace);
+ $this->addTrace($trace, 0);
+ }
+ else {
+ $this->_logRecord['LogType'] = self::LT_PHP;
+ $errno = $exception->getCode();
+
+ $this->addSource((string)$exception->getFile(), $exception->getLine());
+ $this->addTrace($exception->getTrace(), 0);
+ }
+
+ $this->_logRecord['LogCode'] = $errno;
+ $this->_logRecord['LogMessage'] = $errstr;
+
+ return $this;
+ }
+
+ /**
+ * Allows to map PHP error numbers to syslog log level
+ *
+ * @param int $errno
+ * @return int
+ * @access protected
+ */
+ protected function _getLogLevelByErrorNo($errno)
+ {
+ $error_number_mapping = Array (
+ self::LL_ERROR => Array (E_RECOVERABLE_ERROR, E_USER_ERROR, E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE),
+ self::LL_WARNING => Array (E_WARNING, E_USER_WARNING, E_CORE_WARNING, E_COMPILE_WARNING),
+ self::LL_NOTICE => Array (E_NOTICE, E_USER_NOTICE, E_STRICT),
+ );
+
+ if ( version_compare(PHP_VERSION, '5.3.0', '>=') ) {
+ $error_number_mapping[self::LL_NOTICE][] = E_DEPRECATED;
+ $error_number_mapping[self::LL_NOTICE][] = E_USER_DEPRECATED;
+ }
+
+ foreach ($error_number_mapping as $log_level => $error_numbers) {
+ if ( in_array($errno, $error_numbers) ) {
+ return $log_level;
+ }
+ }
+
+ return self::LL_ERROR;
+ }
+
+ /**
+ * Changes log level of a log record
+ *
+ * @param int $log_level
+ * @return kLogger
+ * @access public
+ */
+ public function setLogLevel($log_level)
+ {
+ $this->_logRecord['LogLevel'] = $log_level;
+
+ return $this;
+ }
+
+ /**
+ * Writes prepared log to database or disk, when database isn't available
+ *
+ * @param int $storage_medium
+ * @return bool|int
+ * @access public
+ * @throws InvalidArgumentException
+ */
+ public function write($storage_medium = self::LS_AUTOMATIC)
+ {
+ if ( !$this->_logRecord || $this->_logRecord['LogLevel'] > $this->_maxLogLevel || $this->_state == self::STATE_DISABLED ) {
+ // nothing to save OR less detailed logging requested OR disabled
+ return true;
+ }
+
+ $this->_logRecord['LogMemoryUsed'] = memory_get_usage();
+ $this->_logRecord['LogTimestamp'] = adodb_mktime();
+ $this->_logRecord['LogDate'] = adodb_date('Y-m-d H:i:s');
+
+ if ( $storage_medium == self::LS_AUTOMATIC ) {
+ $storage_medium = $this->Conn->connectionOpened() ? self::LS_DATABASE : self::LS_DISK;
+ }
+
+ if ( $storage_medium == self::LS_DATABASE ) {
+ $result = $this->Conn->doInsert($this->_logRecord, TABLE_PREFIX . 'SystemLog');
+ }
+ elseif ( $storage_medium == self::LS_DISK ) {
+ $result = $this->_saveToFile(RESTRICTED . '/system.log');
+ }
+ else {
+ throw new InvalidArgumentException('Unknown storage medium "' . $storage_medium . '"');
+ }
+
+ $unique_id = $this->_logRecord['LogUniqueId'];
+
+ if ( $this->_logRecord['LogNotificationStatus'] == self::LNS_SENT ) {
+ $this->_sendNotification($unique_id);
+ }
+
+ $this->_logRecord = Array ();
+
+ return $result ? $unique_id : false;
+ }
+
+ /**
+ * Catches last error happened before script ended
+ *
+ * @return void
+ * @access public
+ */
+ public function catchLastError()
+ {
+ $this->write();
+ $last_error = error_get_last();
+
+ if ( !is_null($last_error) ) {
+ $handler = $this->_handlers[self::LL_ERROR];
+ /* @var $handler kErrorHandlerStack */
+
+ $handler->handle($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']);
+ }
+ }
+
+ /**
+ * Deletes log with given id from database or disk, when database isn't available
+ *
+ * @param int $unique_id
+ * @param int $storage_medium
+ * @return void
+ * @access public
+ * @throws InvalidArgumentException
+ */
+ public function delete($unique_id, $storage_medium = self::LS_AUTOMATIC)
+ {
+ if ( $storage_medium == self::LS_AUTOMATIC ) {
+ $storage_medium = $this->Conn->connectionOpened ? self::LS_DATABASE : self::LS_DISK;
+ }
+
+ if ( $storage_medium == self::LS_DATABASE ) {
+ $sql = 'DELETE FROM ' . TABLE_PREFIX . 'SystemLog
+ WHERE LogUniqueId = ' . $unique_id;
+ $this->Conn->Query($sql);
+ }
+ elseif ( $storage_medium == self::LS_DISK ) {
+ // TODO: no way to delete a line from a file
+ }
+ else {
+ throw new InvalidArgumentException('Unknown storage medium "' . $storage_medium . '"');
+ }
+ }
+
+ /**
+ * Send notification (delayed or instant) about log record to e-mail from configuration
+ *
+ * @param bool $instant
+ * @return kLogger
+ * @access public
+ */
+ public function notify($instant = false)
+ {
+ $this->_logRecord['LogNotificationStatus'] = $instant ? self::LNS_SENT : self::LNS_PENDING;
+
+ return $this;
+ }
+
+ /**
+ * Sends notification e-mail about message with given $unique_id
+ *
+ * @param int $unique_id
+ * @return void
+ * @access protected
+ */
+ protected function _sendNotification($unique_id)
+ {
+ $notification_email = $this->Application->ConfigValue('SystemLogNotificationEmail');
+
+ if ( !$notification_email ) {
+ trigger_error('System Log notification E-mail not specified', E_USER_NOTICE);
+
+ return;
+ }
+
+ $send_params = Array (
+ 'to_name' => $notification_email,
+ 'to_email' => $notification_email,
+ );
+
+ // initialize list outside of e-mail event with right settings
+ $this->Application->recallObject('system-log.email', 'system-log_List', Array ('unique_id' => $unique_id));
+
+ $this->Application->EmailEventAdmin('SYSTEM.LOG.NOTIFY', null, $send_params);
+ $this->Application->removeObject('system-log.email');
+ }
+
+ /**
+ * Adds error/exception handler
+ *
+ * @param string|Array $handler
+ * @param bool $is_exception
+ * @return void
+ * @access public
+ */
+ public function addErrorHandler($handler, $is_exception = false)
+ {
+ $this->_handlers[$is_exception ? self::LL_CRITICAL : self::LL_ERROR]->add($handler);
+ }
+
+ /**
+ * SQL Error Handler
+ *
+ * When not debug mode, then fatal database query won't break anything.
+ *
+ * @param int $code
+ * @param string $msg
+ * @param string $sql
+ * @return bool
+ * @access public
+ * @throws RuntimeException
+ */
+ public function handleSQLError($code, $msg, $sql)
+ {
+ $error_msg = self::shortenMessage(self::DB_ERROR_PREFIX . ' #' . $code . ' - ' . $msg . '. SQL: ' . trim($sql));
+
+ if ( isset($this->Application->Debugger) ) {
+ if ( kUtil::constOn('DBG_SQL_FAILURE') && !defined('IS_INSTALL') ) {
+ throw new RuntimeException($error_msg);
+ }
+ else {
+ $this->Application->Debugger->appendTrace();
+ }
+ }
+
+ // next line also trigger attached error handlers
+ trigger_error($error_msg, E_USER_WARNING);
+
+ return true;
+ }
+
+ /**
+ * Packs information about error into a single line
+ *
+ * @param string $errno
+ * @param bool $strip_tags
+ * @return string
+ * @access public
+ */
+ public function toString($errno = null, $strip_tags = false)
+ {
+ if ( !isset($errno) ) {
+ $errno = $this->_logRecord['LogCode'];
+ }
+
+ $errstr = $this->_logRecord['LogMessage'];
+ $errfile = $this->_logRecord['LogSourceFilename'];
+ $errline = $this->_logRecord['LogSourceFileLine'];
+
+ $result = '' . $errno . ': ' . "{$errstr} in {$errfile} on line {$errline}";
+
+ return $strip_tags ? strip_tags($result) : $result;
+ }
+
+ /**
+ * Saves log to file (e.g. when not possible to save into database)
+ *
+ * @param $filename
+ * @return bool
+ * @access protected
+ */
+ protected function _saveToFile($filename)
+ {
+ $time = adodb_date('Y-m-d H:i:s');
+ $log_file = new SplFileObject($filename, 'a');
+
+ return $log_file->fwrite('[' . $time . '] #' . $this->toString(null, true) . PHP_EOL) > 0;
+ }
+
+ /**
+ * Checks if log type of current log record matches given one
+ *
+ * @param int $log_type
+ * @param string $log_message
+ * @return bool
+ * @access public
+ */
+ public function isLogType($log_type, $log_message = null)
+ {
+ if ( $this->_logRecord['LogType'] == $log_type ) {
+ return true;
+ }
+
+ if ( $log_type == self::LT_DATABASE ) {
+ if ( !isset($log_message) ) {
+ $log_message = $this->_logRecord['LogMessage'];
+ }
+
+ return strpos($log_message, self::DB_ERROR_PREFIX) !== false;
+ }
+
+ return false;
+ }
+
+ /**
+ * Shortens message
+ *
+ * @param string $message
+ * @return string
+ * @access public
+ */
+ public static function shortenMessage($message)
+ {
+ $max_len = ini_get('log_errors_max_len');
+
+ if ( strlen($message) > $max_len ) {
+ $long_key = kUtil::generateId();
+ self::$_longMessages[$long_key] = $message;
+
+ return mb_substr($message, 0, $max_len - strlen($long_key) - 2) . ' #' . $long_key;
+ }
+
+ return $message;
+ }
+
+ /**
+ * Expands shortened message
+ *
+ * @param string $message
+ * @param bool $clear_cache Allow debugger to expand message after it's been expanded by kLogger
+ * @return string
+ * @access public
+ */
+ public static function expandMessage($message, $clear_cache = true)
+ {
+ if ( preg_match('/(.*)#([\d]+)$/', $message, $regs) ) {
+ $long_key = $regs[2];
+
+ if ( isset(self::$_longMessages[$long_key]) ) {
+ $message = self::$_longMessages[$long_key];
+
+ if ( $clear_cache ) {
+ unset(self::$_longMessages[$long_key]);
+ }
+ }
+ }
+
+ return $message;
+ }
+
+ /**
+ * Parses database error message into error number, error message and sql that caused that error
+ *
+ * @static
+ * @param string $message
+ * @return Array
+ * @access public
+ */
+ public static function parseDatabaseError($message)
+ {
+ $regexp = '/' . preg_quote(self::DB_ERROR_PREFIX) . ' #(.*?) - (.*?)\. SQL: (.*?)$/s';
+
+ if ( preg_match($regexp, $message, $regs) ) {
+ // errno, errstr, sql
+ return Array ($regs[1], $regs[2], $regs[3]);
+ }
+
+ return Array (0, $message, '');
+ }
+}
+
+
+/**
+ * Base class for error or exception handling
+ */
+abstract class kHandlerStack extends kBase {
+
+ /**
+ * List of added handlers
+ *
+ * @var Array
+ * @access protected
+ */
+ protected $_handlers = Array ();
+
+ /**
+ * Reference to event log, which created this object
+ *
+ * @var kLogger
+ * @access protected
+ */
+ protected $_logger;
+
+ /**
+ * Remembers if handler is activated
+ *
+ * @var bool
+ * @access protected
+ */
+ protected $_enabled = false;
+
+ public function __construct(kLogger $logger)
+ {
+ parent::__construct();
+
+ $this->_logger = $logger;
+
+ if ( !kUtil::constOn('DBG_ZEND_PRESENT') ) {
+ $this->attach();
+ $this->_enabled = true;
+ }
+ }
+
+ /**
+ * Detaches from error handling routines on class destruction
+ *
+ * @return void
+ * @access public
+ */
+ public function __destruct()
+ {
+ if ( !$this->_enabled ) {
+ return;
+ }
+
+ $this->detach();
+ $this->_enabled = false;
+ }
+
+ /**
+ * Attach to error handling routines
+ *
+ * @abstract
+ * @return void
+ * @access protected
+ */
+ abstract protected function attach();
+
+ /**
+ * Detach from error handling routines
+ *
+ * @abstract
+ * @return void
+ * @access protected
+ */
+ abstract protected function detach();
+
+ /**
+ * Adds new handler to the stack
+ *
+ * @param callable $handler
+ * @return void
+ * @access public
+ */
+ public function add($handler)
+ {
+ $this->_handlers[] = $handler;
+ }
+
+ protected function _handleFatalError($errno)
+ {
+ $debug_mode = defined('DEBUG_MODE') && DEBUG_MODE;
+ $skip_reporting = defined('DBG_SKIP_REPORTING') && DBG_SKIP_REPORTING;
+
+ if ( !$this->_handlers || ($debug_mode && $skip_reporting) ) {
+ // when debugger absent OR it's present, but we actually can't see it's error report (e.g. during ajax request)
+
+ if ( $this->_isFatalError($errno) ) {
+ $this->_displayFatalError($errno);
+ }
+
+ if ( !$this->_handlers ) {
+ return true;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Determines if given error is a fatal
+ *
+ * @abstract
+ * @param Exception|int $errno
+ * @return bool
+ */
+ abstract protected function _isFatalError($errno);
+
+ /**
+ * Displays div with given error message
+ *
+ * @param string $errno
+ * @return void
+ * @access protected
+ */
+ protected function _displayFatalError($errno)
+ {
+ $errno = $this->_getFatalErrorTitle($errno);
+
+ $margin = $this->Application->isAdmin ? '8px' : 'auto';
+ echo '
' . $this->_logger->toString($errno) . '
';
+ exit;
+ }
+
+ /**
+ * Returns title to show for a fatal
+ *
+ * @abstract
+ * @param Exception|int $errno
+ * @return string
+ */
+ abstract protected function _getFatalErrorTitle($errno);
+}
+
+
+/**
+ * Class, that handles errors
+ */
+class kErrorHandlerStack extends kHandlerStack {
+
+ /**
+ * Attach to error handling routines
+ *
+ * @return void
+ * @access protected
+ */
+ protected function attach()
+ {
+ // set as error handler
+ $error_handler = set_error_handler(Array ($this, 'handle'));
+
+ if ( $error_handler ) {
+ // wrap around previous error handler, if any was set
+ $this->_handlers[] = $error_handler;
+ }
+ }
+
+ /**
+ * Detach from error handling routines
+ *
+ * @return void
+ * @access protected
+ */
+ protected function detach()
+ {
+ restore_error_handler();
+ }
+
+ /**
+ * Determines if given error is a fatal
+ *
+ * @param int $errno
+ * @return bool
+ * @access protected
+ */
+ protected function _isFatalError($errno)
+ {
+ $fatal_errors = Array (E_USER_ERROR, E_RECOVERABLE_ERROR, E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE);
+
+ return in_array($errno, $fatal_errors);
+ }
+
+ /**
+ * Returns title to show for a fatal
+ *
+ * @param int $errno
+ * @return string
+ * @access protected
+ */
+ protected function _getFatalErrorTitle($errno)
+ {
+ return 'Fatal Error';
+ }
+
+ /**
+ * Default error handler
+ *
+ * @param int $errno
+ * @param string $errstr
+ * @param string $errfile
+ * @param int $errline
+ * @param Array $errcontext
+ * @return bool
+ * @access public
+ */
+ public function handle($errno, $errstr, $errfile = null, $errline = null, $errcontext = Array ())
+ {
+ $log = $this->_logger->prepare()->addError($errno, $errstr, $errfile, $errline);
+
+ if ( $this->_handleFatalError($errno) ) {
+ $log->write();
+
+ return true;
+ }
+
+ $log->write();
+
+ $res = false;
+ /* @var $handler Closure */
+
+ foreach ($this->_handlers as $handler) {
+ if ( is_array($handler) ) {
+ $object =& $handler[0];
+ $method = $handler[1];
+ $res = $object->$method($errno, $errstr, $errfile, $errline, $errcontext);
+ }
+ else {
+ $res = $handler($errno, $errstr, $errfile, $errline, $errcontext);
+ }
+ }
+
+ return $res;
+ }
+}
+
+
+/**
+ * Class, that handles exceptions
+ */
+class kExceptionHandlerStack extends kHandlerStack {
+
+ /**
+ * Attach to error handling routines
+ *
+ * @return void
+ * @access protected
+ */
+ protected function attach()
+ {
+ // set as exception handler
+ $exception_handler = set_exception_handler(Array ($this, 'handle'));
+
+ if ( $exception_handler ) {
+ // wrap around previous exception handler, if any was set
+ $this->_handlers[] = $exception_handler;
+ }
+ }
+
+ /**
+ * Detach from error handling routines
+ *
+ * @return void
+ * @access protected
+ */
+ protected function detach()
+ {
+ restore_exception_handler();
+ }
+
+ /**
+ * Determines if given error is a fatal
+ *
+ * @param Exception $errno
+ * @return bool
+ */
+ protected function _isFatalError($errno)
+ {
+ return true;
+ }
+
+ /**
+ * Returns title to show for a fatal
+ *
+ * @param Exception $errno
+ * @return string
+ */
+ protected function _getFatalErrorTitle($errno)
+ {
+ return get_class($errno);
+ }
+
+ /**
+ * Handles exception
+ *
+ * @param Exception $exception
+ * @return bool
+ * @access public
+ */
+ public function handle($exception)
+ {
+ $log = $this->_logger->prepare()->addException($exception);
+
+ if ( $exception instanceof kRedirectException ) {
+ /* @var $exception kRedirectException */
+
+ $exception->run();
+ }
+
+ if ( $this->_handleFatalError($exception) ) {
+ $log->write();
+
+ return true;
+ }
+
+ $log->write();
+
+ $res = false;
+ /* @var $handler Closure */
+
+ foreach ($this->_handlers as $handler) {
+ if ( is_array($handler) ) {
+ $object =& $handler[0];
+ $method = $handler[1];
+ $res = $object->$method($exception);
+ }
+ else {
+ $res = $handler($exception);
+ }
+ }
+
+ return $res;
+ }
+}
\ No newline at end of file
Index: branches/5.2.x/core/kernel/utility/email.php
===================================================================
diff -u -r15542 -r15552
--- branches/5.2.x/core/kernel/utility/email.php (.../email.php) (revision 15542)
+++ branches/5.2.x/core/kernel/utility/email.php (.../email.php) (revision 15552)
@@ -1,6 +1,6 @@
Application->ConfigValue('EmailLogRotationInterval') != '';
+ return $this->Application->ConfigValue('EnableEmailLog');
}
/**
Index: branches/5.2.x/core/install/steps_db.xml
===================================================================
diff -u -r15445 -r15552
--- branches/5.2.x/core/install/steps_db.xml (.../steps_db.xml) (revision 15445)
+++ branches/5.2.x/core/install/steps_db.xml (.../steps_db.xml) (revision 15552)
@@ -148,6 +148,10 @@
but can set to other encoding also (see wikipedia.org options).
It's highly recommended to have Website Encoding match the Database Encoding (specified on DB step).
+ Enable "System Log" - "System Log" has capability to record PHP Exceptions, Errors, Warnings, Notices, Database/SQL
+ Errors and Warnings, and User defined messages that happened on your website. It has 3 modes - Enabled (logs everything, including user
+ defined messages), User-only (user defined messages only), and Disabled (don't log anything at all - default setting).
+
]]>
Index: branches/5.2.x/core/kernel/kbase.php
===================================================================
diff -u -r15252 -r15552
--- branches/5.2.x/core/kernel/kbase.php (.../kbase.php) (revision 15252)
+++ branches/5.2.x/core/kernel/kbase.php (.../kbase.php) (revision 15552)
@@ -1,6 +1,6 @@
prefixSpecial;
}
+
+ /**
+ * Creates string representation of a class (for logging)
+ *
+ * @return string
+ * @access public
+ */
+ public function __toString()
+ {
+ return 'ClassName: ' . get_class($this) . '; PrefixSpecial: ' . $this->getPrefixSpecial();
+ }
}
Index: branches/5.2.x/core/kernel/startup.php
===================================================================
diff -u -r15445 -r15552
--- branches/5.2.x/core/kernel/startup.php (.../startup.php) (revision 15445)
+++ branches/5.2.x/core/kernel/startup.php (.../startup.php) (revision 15552)
@@ -1,6 +1,6 @@
Data->AddParams( $this->Storage->LoadData() );
}
- function PrintSession($comment = '')
+ /**
+ * Returns information about session contents
+ *
+ * @param bool $include_optional
+ * @return array
+ * @access public
+ */
+ public function getSessionData($include_optional = true)
{
- if (defined('DEBUG_MODE') && $this->Application->isDebugMode() && kUtil::constOn('DBG_SHOW_SESSIONDATA')) {
- // dump session data
- $this->Application->Debugger->appendHTML('SessionStorage [' . ($this->RecallVar('admin') == 1 ? 'Admin' : 'Front-End') . '] ('.$comment.'):');
- $session_data = $this->Data->GetParams();
- ksort($session_data);
+ $session_data = $this->Data->GetParams();
+ ksort($session_data);
+
+ foreach ($session_data as $session_key => $session_value) {
+ if ( kUtil::IsSerialized($session_value) ) {
+ $session_data[$session_key] = unserialize($session_value);
+ }
+ }
+
+ if ( !$include_optional ) {
+ $optional_keys = array_keys($this->OptionalData);
+
foreach ($session_data as $session_key => $session_value) {
- if (kUtil::IsSerialized($session_value)) {
- $session_data[$session_key] = unserialize($session_value);
+ if ( in_array($session_key, $optional_keys) ) {
+ unset($session_data[$session_key]);
}
}
+ }
+
+ return $session_data;
+ }
+
+ /**
+ * Returns real session data, that was saved
+ *
+ * @param Array $session_data
+ * @return Array
+ * @access protected
+ */
+ protected function _getRealSessionData($session_data)
+ {
+ $data_keys = array_keys($session_data);
+ $optional_keys = array_keys($this->OptionalData);
+ $real_keys = array_diff($data_keys, $optional_keys);
+
+ if ( !$real_keys ) {
+ return Array ();
+ }
+
+ $ret = Array ();
+
+ foreach ($real_keys as $real_key) {
+ $ret[$real_key] = $session_data[$real_key];
+ }
+
+ return $ret;
+ }
+
+ function PrintSession($comment = '')
+ {
+ if ( defined('DEBUG_MODE') && $this->Application->isDebugMode() && kUtil::constOn('DBG_SHOW_SESSIONDATA') ) {
+ // dump session data
+ $this->Application->Debugger->appendHTML('SessionStorage [' . ($this->RecallVar('admin') == 1 ? 'Admin' : 'Front-End') . '] (' . $comment . '):');
+
+ $session_data = $this->getSessionData();
$this->Application->Debugger->dumpVars($session_data);
- if (!$this->RecallVar('admin')) {
+ if ( !$this->RecallVar('admin') ) {
// dump real keys (only for front-end)
- $data_keys = array_keys($session_data);
- $optional_keys = array_keys($this->OptionalData);
- $real_keys = array_diff($data_keys, $optional_keys);
+ $real_session_data = $this->_getRealSessionData($session_data);
- if ($real_keys) {
- $ret = '';
- foreach ($real_keys as $real_key) {
- $ret .= '[' . $real_key . '] = [' . $session_data[$real_key] . '] ';
- }
-
- $this->Application->Debugger->appendHTML('Real Keys: ' . $ret);
+ if ( $real_session_data ) {
+ $this->Application->Debugger->appendHTML('Real Keys:');
+ $this->Application->Debugger->dumpVars($real_session_data);
}
}
}
- if (defined('DEBUG_MODE') && $this->Application->isDebugMode() && kUtil::constOn('DBG_SHOW_PERSISTENTDATA')) {
+ if ( defined('DEBUG_MODE') && $this->Application->isDebugMode() && kUtil::constOn('DBG_SHOW_PERSISTENTDATA') ) {
// dump persistent session data
- if ($this->Storage->PersistentVars) {
+ if ( $this->Storage->PersistentVars ) {
$this->Application->Debugger->appendHTML('Persistant Session:');
$session_data = $this->Storage->PersistentVars;
ksort($session_data);
foreach ($session_data as $session_key => $session_value) {
- if (kUtil::IsSerialized($session_value)) {
+ if ( kUtil::IsSerialized($session_value) ) {
$session_data[$session_key] = unserialize($session_value);
}
}
Index: branches/5.2.x/core/kernel/db/db_load_balancer.php
===================================================================
diff -u -r15242 -r15552
--- branches/5.2.x/core/kernel/db/db_load_balancer.php (.../db_load_balancer.php) (revision 15242)
+++ branches/5.2.x/core/kernel/db/db_load_balancer.php (.../db_load_balancer.php) (revision 15552)
@@ -1,6 +1,6 @@
openConnection(isset($i) ? $i : $this->getMasterIndex());
+
+ return $conn ? $conn->connectionOpened : false;
+ }
+
+ /**
* Really opens a connection.
* Returns a database object whether or not the connection was successful.
*
Index: branches/5.2.x/core/install/install_schema.sql
===================================================================
diff -u -r15461 -r15552
--- branches/5.2.x/core/install/install_schema.sql (.../install_schema.sql) (revision 15461)
+++ branches/5.2.x/core/install/install_schema.sql (.../install_schema.sql) (revision 15552)
@@ -421,6 +421,38 @@
KEY `timestamp` (SentOn)
);
+CREATE TABLE SystemLog (
+ LogId int(11) NOT NULL AUTO_INCREMENT,
+ LogUniqueId int(11) DEFAULT NULL,
+ LogLevel tinyint(4) NOT NULL DEFAULT '7',
+ LogType tinyint(4) NOT NULL DEFAULT '3',
+ LogCode int(11) DEFAULT NULL,
+ LogMessage longtext,
+ LogTimestamp int(11) DEFAULT NULL,
+ LogDate datetime DEFAULT NULL,
+ LogEventName varchar(100) NOT NULL DEFAULT '',
+ LogHostname varchar(255) NOT NULL DEFAULT '',
+ LogRequestSource tinyint(4) DEFAULT NULL,
+ LogRequestURI varchar(255) NOT NULL DEFAULT '',
+ LogRequestData longtext,
+ LogUserId int(11) DEFAULT NULL,
+ LogInterface tinyint(4) DEFAULT NULL,
+ IpAddress varchar(15) NOT NULL DEFAULT '',
+ LogSessionKey int(11) DEFAULT NULL,
+ LogSessionData longtext,
+ LogBacktrace longtext,
+ LogSourceFilename varchar(255) NOT NULL DEFAULT '',
+ LogSourceFileLine int(11) DEFAULT NULL,
+ LogProcessId bigint(20) unsigned DEFAULT NULL,
+ LogMemoryUsed bigint(20) unsigned NOT NULL,
+ LogUserData longtext NOT NULL,
+ LogNotificationStatus tinyint(4) NOT NULL DEFAULT '0',
+ PRIMARY KEY (LogId),
+ KEY LogLevel (LogLevel),
+ KEY LogType (LogType),
+ KEY LogNotificationStatus (LogNotificationStatus)
+);
+
CREATE TABLE SystemCache (
VarName varchar(255) NOT NULL default '',
Data longtext,
Index: branches/5.2.x/core/units/helpers/mailing_list_helper.php
===================================================================
diff -u -r15230 -r15552
--- branches/5.2.x/core/units/helpers/mailing_list_helper.php (.../mailing_list_helper.php) (revision 15230)
+++ branches/5.2.x/core/units/helpers/mailing_list_helper.php (.../mailing_list_helper.php) (revision 15552)
@@ -1,6 +1,6 @@
SetTo($email, $email);
- if ( $this->Application->ConfigValue('EmailLogRotationInterval') != '' ) {
+ if ( $this->Application->ConfigValue('EnableEmailLog') ) {
// 4. write to log
$log_fields_hash = Array (
'From' => $mailing_data['FromName'] . '(' . $mailing_data['FromEmail'] . ')',
Index: branches/5.2.x/core/units/logs/system_logs/system_logs_config.php
===================================================================
diff -u
--- branches/5.2.x/core/units/logs/system_logs/system_logs_config.php (revision 0)
+++ branches/5.2.x/core/units/logs/system_logs/system_logs_config.php (revision 15552)
@@ -0,0 +1,205 @@
+ 'system-log',
+ 'ItemClass' => Array('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'),
+ 'ListClass' => Array('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'),
+ 'EventHandlerClass' => Array ('class' => 'SystemLogEventHandler', 'file' => 'system_log_eh.php', 'build_event' => 'OnBuild'),
+ 'TagProcessorClass' => Array ('class' => 'SystemLogTagProcessor', 'file' => 'system_log_tp.php', 'build_event' => 'OnBuild'),
+
+ 'AutoLoad' => true,
+
+ 'QueryString' => Array (
+ 1 => 'id',
+ 2 => 'Page',
+ 3 => 'PerPage',
+ 4 => 'event',
+ 5 => 'mode',
+ ),
+
+ 'ScheduledTasks' => Array (
+ 'system_log_notifications' => Array('EventName' => 'OnSendNotifications', 'RunSchedule' => '0 * * * *'),
+ 'rotate_system_logs' => Array('EventName' => 'OnRotate', 'RunSchedule' => '0 0 * * *'),
+ ),
+
+ 'IDField' => 'LogId',
+ //'StatusField' => Array ('Status'),
+ 'TableName' => TABLE_PREFIX . 'SystemLog',
+
+ 'TitlePresets' => Array (
+ 'default' => Array (
+ 'edit_status_labels' => Array ('system-log' => '!la_title_ViewingSystemLog!'),
+ ),
+
+ 'system_log_list' => Array (
+ 'prefixes' => Array('system-log_List'), 'format' => '!la_tab_SystemLog!',
+ 'toolbar_buttons' => Array ('edit', 'delete', 'reset', 'view', 'dbl-click'),
+ ),
+
+ 'system_log_edit' => Array (
+ 'prefixes' => Array('system-log'), 'format' => '#system-log_status# "#system-log_titlefield#"',
+ 'toolbar_buttons' => Array ('select', 'cancel', 'reset_edit', 'prev', 'next'),
+ ),
+ ),
+
+ 'PermSection' => Array ('main' => 'in-portal:system_logs'),
+
+ 'Sections' => Array (
+ 'in-portal:system_logs' => Array (
+ 'parent' => 'in-portal:reports',
+ 'icon' => 'system_log',
+ 'label' => 'la_tab_SystemLog',
+ 'url' => Array('t' => 'logs/system_logs/system_log_list', 'pass' => 'm'),
+ 'permissions' => Array('view', 'edit', 'delete'),
+ 'priority' => 6.1,
+ 'type' => stTREE,
+ ),
+ ),
+
+ 'TitleField' => 'LogMessage',
+
+ 'ListSQLs' => Array (
+ '' => ' SELECT %1$s.* %2$s
+ FROM %1$s
+ LEFT JOIN '.TABLE_PREFIX.'Users AS u ON u.PortalUserId = %1$s.LogUserId',
+ ),
+
+ 'ListSortings' => Array (
+ '' => Array (
+ 'Sorting' => Array ('LogId' => 'desc'),
+ )
+ ),
+
+ 'CalculatedFields' => Array (
+ '' => Array (
+ 'Username' => 'CASE %1$s.LogUserId WHEN ' . USER_ROOT . ' THEN "root" WHEN ' . USER_GUEST . ' THEN "Guest" ELSE IF(CONCAT(u.FirstName, u.LastName) <> "", CONCAT(u.FirstName, " ", u.LastName), u.Username) END',
+ ),
+ ),
+
+ 'ForceDontLogChanges' => true,
+
+ 'Fields' => Array (
+ 'LogId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
+ 'LogUniqueId' => Array ('type' => 'int', 'default' => NULL),
+ 'LogLevel' => Array (
+ 'type' => 'int',
+ 'formatter' => 'kOptionsFormatter', 'options' => Array (
+ kLogger::LL_EMERGENCY => 'emergency',
+ kLogger::LL_ALERT => 'alert',
+ kLogger::LL_CRITICAL => 'critical',
+ kLogger::LL_ERROR => 'error',
+ kLogger::LL_WARNING => 'warning',
+ kLogger::LL_NOTICE => 'notice',
+ kLogger::LL_INFO => 'info',
+ kLogger::LL_DEBUG => 'debug'
+ ),
+ 'not_null' => 1, 'default' => kLogger::LL_INFO
+ ),
+ 'LogType' => Array (
+ 'type' => 'int',
+ 'formatter' => 'kOptionsFormatter', 'options' => Array (
+ kLogger::LT_PHP => 'la_opt_LogTypePhp',
+ kLogger::LT_DATABASE => 'la_opt_LogTypeDatabase',
+ kLogger::LT_OTHER => 'la_opt_LogTypeOther',
+ ), 'use_phrases' => 1,
+ 'not_null', 'default' => kLogger::LT_OTHER
+ ),
+ 'LogCode' => Array ('type' => 'int', 'default' => NULL),
+ 'LogMessage' => Array ('type' => 'string', 'default' => NULL),
+ 'LogTimestamp' => Array (
+ 'type' => 'int',
+ 'formatter' => 'kDateFormatter',
+ 'default' => NULL
+ ),
+ 'LogDate' => Array ('type' => 'string', 'default' => NULL),
+ 'LogEventName' => Array ('type' => 'string', 'max_len' => 100, 'not_null' => 1, 'default' => ''),
+ 'LogHostname' => Array ('type' => 'string', 'max_len' => 255, 'not_null' => 1, 'default' => ''),
+ 'LogRequestSource' => Array (
+ 'type' => 'int',
+ 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'Web', 2 => 'CLI'),
+ 'default' => NULL
+ ),
+ 'LogRequestURI' => Array ('type' => 'string', 'max_len' => 255, 'not_null' => 1, 'default' => ''),
+ 'LogRequestData' => Array ('type' => 'string', 'default' => NULL),
+ 'LogUserId' => Array (
+ 'type' => 'int',
+ 'default' => NULL
+ ),
+ 'LogInterface' => Array (
+ 'type' => 'int',
+ 'formatter' => 'kOptionsFormatter', 'options' => Array (
+ kLogger::LI_FRONT => 'Front',
+ kLogger::LI_ADMIN => 'Admin',
+ kLogger::LI_CRON_FRONT => 'Cron (Front)',
+ kLogger::LI_CRON_ADMIN => 'Cron (Admin)',
+ kLogger::LI_API => 'API',
+ ),
+ 'not_null' => 1, 'default' => 0
+ ),
+ 'IpAddress' => Array ('type' => 'string', 'max_len' => 15, 'not_null' => 1, 'default' => ''),
+ 'LogSessionKey' => Array ('type' => 'int', 'default' => NULL),
+ 'LogSessionData' => Array ('type' => 'string', 'default' => NULL),
+ 'LogBacktrace' => Array ('type' => 'string', 'default' => NULL),
+ 'LogSourceFilename' => Array ('type' => 'string', 'max_len' => 255, 'not_null' => 1, 'default' => ''),
+ 'LogSourceFileLine' => Array ('type' => 'int', 'default' => NULL),
+ 'LogProcessId' => Array ('type' => 'int', 'default' => NULL),
+ 'LogMemoryUsed' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
+ 'LogUserData' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''),
+ 'LogNotificationStatus' => Array (
+ 'type' => 'int',
+ 'formatter' => 'kOptionsFormatter', 'options' => Array (
+ kLogger::LNS_DISABLED => 'la_opt_LogNotificationDisabled',
+ kLogger::LNS_PENDING => 'la_opt_LogNotificationPending',
+ kLogger::LNS_SENT => 'la_opt_LogNotificationSent'
+ ), 'use_phrases' => 1,
+ 'not_null' => 1, 'default' => kLogger::LNS_DISABLED
+ )
+ ),
+
+ 'VirtualFields' => Array (
+ 'Username' => Array ('type' => 'string', 'default' => ''),
+ ),
+
+ 'Grids' => Array (
+ 'Default' => Array (
+// 'Icons' => Array ('default' => 'icon16_item.png'),
+ 'Fields' => Array (
+ 'LogId' => Array ('title' => 'column:la_fld_Id', 'filter_block' => 'grid_range_filter', 'width' => 80),
+ 'LogLevel' => Array ('filter_block' => 'grid_options_filter', 'width' => 100),
+ 'LogType' => Array ('filter_block' => 'grid_options_filter', 'width' => 80),
+ 'LogCode' => Array ('filter_block' => 'grid_range_filter', 'width' => 80),
+ 'LogMessage' => Array ('filter_block' => 'grid_like_filter', 'width' => 250),
+ 'LogTimestamp' => Array ('filter_block' => 'grid_date_range_filter', 'width' => 170),
+ 'LogEventName' => Array ('filter_block' => 'grid_like_filter'),
+ 'LogHostname' => Array ('filter_block' => 'grid_like_filter'),
+ 'LogRequestSource' => Array ('filter_block' => 'grid_options_filter'),
+ 'LogRequestURI' => Array ('data_block' => 'grid_uri_td', 'filter_block' => 'grid_like_filter'),
+ 'Username' => Array ('filter_block' => 'grid_range_filter', 'width' => 80),
+ 'LogInterface' => Array ('filter_block' => 'grid_options_filter'),
+ 'IpAddress' => Array ('filter_block' => 'grid_like_filter'),
+ 'LogSessionKey' => Array ('filter_block' => 'grid_range_filter', 'width' => 80),
+ 'LogSourceFilename' => Array ('data_block' => 'grid_filename_td', 'filter_block' => 'grid_like_filter', 'width' => 200),
+ 'LogSourceFileLine' => Array ('filter_block' => 'grid_range_filter', 'width' => 80),
+ 'LogProcessId' => Array ('filter_block' => 'grid_range_filter', 'width' => 80),
+ 'LogMemoryUsed' => Array ('data_block' => 'grid_memory_td', 'filter_block' => 'grid_range_filter'),
+ 'LogUserData' => Array ('filter_block' => 'grid_like_filter', 'nl2br' => 1),
+ 'LogNotificationStatus' => Array ('filter_block' => 'grid_options_filter'),
+ 'LogBacktrace' => Array ('data_block' => 'grid_backtrace_td', 'filter_block' => 'grid_empty_filter', 'width' => 500, 'hidden' => 1),
+ ),
+ ),
+ ),
+);
Index: branches/5.2.x/core/install/english.lang
===================================================================
diff -u -r15471 -r15552
--- branches/5.2.x/core/install/english.lang (.../english.lang) (revision 15471)
+++ branches/5.2.x/core/install/english.lang (.../english.lang) (revision 15552)
@@ -164,7 +164,8 @@
RGVmYXVsdCAiUGVyIFBhZ2UiIHNldHRpbmcgaW4gR3JpZHM=
RGVmYXVsdCBSZWdpc3RyYXRpb24gQ291bnRyeQ==
RGVmYXVsdCBBbmFseXRpY3MgVHJhY2tpbmcgQ29kZQ==
- S2VlcCBFbWFpbCBMb2cgZm9y
+ S2VlcCAiRS1tYWlsIExvZyIgZm9y
+ RW5hYmxlICJFLW1haWwgTG9nIg==
RW5hYmxlIFJldmlzaW9uIENvbnRyb2wgZm9yIFNlY3Rpb24gQ29udGVudA==
VGVtcGxhdGUgZm9yICJGaWxlIG5vdCBmb3VuZCAoNDA0KSIgRXJyb3I=
RXhjbHVkZSB0ZW1wbGF0ZSBiYXNlZCBTZWN0aW9ucyBmcm9tIFNlYXJjaCBSZXN1bHRzIChpZS4gVXNlciBSZWdpc3RyYXRpb24p
@@ -207,6 +208,8 @@
VGVtcGxhdGUgZm9yIFNvZnQgTWFpbnRlbmFuY2U=
U1NMIEZ1bGwgVVJMIChodHRwczovL3d3dy5kb21haW4uY29tL3BhdGgp
VXNlIFN0aWNreSBHcmlkIFNlbGVjdGlvbg==
+ U2VuZCBVc2VyLWRlZmluZWQgIlN5c3RlbSBMb2ciIG1lc3NhZ2VzIHRv
+ S2VlcCAiU3lzdGVtIExvZyIgZm9y
VGh1bWJuYWlsIEhlaWdodA==
VGh1bWJuYWlsIFdpZHRo
VHJpbSBSZXF1aXJlZCBGaWVsZHM=
@@ -512,10 +515,30 @@
TG9jYWxl
TG9jYWwgTmFtZQ==
TG9jYXRpb24=
+ QmFja3RyYWNl
+ Q29kZQ==
+ RXZlbnQgTmFtZQ==
+ SG9zdG5hbWU=
TG9naW4=
+ SW50ZXJmYWNl
+ TG9nIExldmVs
+ TWVtb3J5IFVzZWQ=
+ TWVzc2FnZQ==
+ Tm90aWZpY2F0aW9uIFN0YXR1cw==
TG9nbyBpbWFnZQ==
Qm90dG9tIExvZ28gSW1hZ2U=
TG9nbyBMb2dpbg==
+ UHJvY2VzcyBJRA==
+ UmVxdWVzdCBEYXRh
+ UmVxdWVzdCBTb3VyY2U=
+ UmVxdWVzdCBVUkk=
+ U2Vzc2lvbiBEYXRh
+ U2Vzc2lvbiBLZXk=
+ U291cmNlIEZpbGUgTGluZQ==
+ U291cmNlIEZpbGVuYW1l
+ VGltZXN0YW1w
+ VHlwZQ==
+ VXNlciBEYXRh
TWFyZ2luIEJvdHRvbQ==
TWFyZ2luIExlZnQ=
TWFyZ2luIFJpZ2h0
@@ -737,6 +760,7 @@
TGludXg=
TG9jYWw=
TG9jYWwgSW1hZ2U=
+ RnVuY3Rpb24=
TG9nZ2VkIGluIGFz
TG9naW4=
TG9nb3V0
@@ -779,6 +803,7 @@
T2Zm
T24=
T25lIFdheQ==
+ b24gbGluZQ==
Y3JlYXRlZA==
ZGVsZXRlZA==
dXBkYXRlZA==
@@ -857,7 +882,6 @@
RS1tYWlsIEJvZHk=
RS1tYWlsIEV2ZW50cw==
Rm9yZXZlciAobmV2ZXIgZGVsZXRlZCBhdXRvbWF0aWNhbGx5KQ==
- TmV2ZXIgKHR1cm5lZCBvZmYp
RS1tYWlsIFN1YmplY3Q=
RXZlcnlvbmU=
RXhhY3Q=
@@ -881,6 +905,12 @@
SnVuZQ==
TGFzdCBOYW1l
TG9nZ2VkIE91dA==
+ RGlzYWJsZWQ=
+ UGVuZGluZw==
+ U2VudA==
+ RGF0YWJhc2U=
+ T3RoZXI=
+ UEhQ
TWFudWFs
TWFyY2g=
TWF5
@@ -926,6 +956,7 @@
RnJvbSBvdGhlcnM=
VG8gb3RoZXJz
U3lzdGVt
+ Rm9yZXZlciAobmV2ZXIgZGVsZXRlZCBhdXRvbWF0aWNhbGx5KQ==
VGFi
VGVtcGxhdGU=
MyBtb250aHM=
@@ -1159,6 +1190,7 @@
M3JkIFBhcnR5IEFQSSBTZXR0aW5ncw==
QWRtaW4gQ29uc29sZSBTZXR0aW5ncw==
Q1NWIEV4cG9ydCBTZXR0aW5ncw==
+ TG9ncyBTZXR0aW5ncw==
TWFpbGluZyBTZXR0aW5ncw==
TWFpbnRlbmFuY2UgU2V0dGluZ3M=
U2Vzc2lvbiBTZXR0aW5ncw==
@@ -1259,6 +1291,7 @@
V2Vic2l0ZSAmIENvbnRlbnQ=
QWRtaW4gU2tpbnM=
U3VtbWFyeQ==
+ U3lzdGVtIExvZw==
Q29uZmlndXJhdGlvbg==
VGFnIGxpYnJhcnk=
VGhlbWVz
@@ -1446,6 +1479,10 @@
TGFuZ3VhZ2UgUGFja3M=
TGFuZ3VhZ2VzIE1hbmFnZW1lbnQ=
TG9hZGluZyAuLi4=
+ T3RoZXI=
+ UmVxdWVzdA==
+ U2Vzc2lvbg==
+ U291cmNl
TWFpbGluZ3M=
TWVzc2FnZXM=
TW9kdWxlcw==
@@ -1514,6 +1551,7 @@
Vmlld2luZyBNYWlsaW5nIExpc3Q=
Vmlld2luZyBSZXBseQ==
Vmlld2luZyBSZXZpc2lvbiAjJXMgKCVzKQ==
+ Vmlld2luZyBTeXN0ZW0gTG9n
VmlzaXRz
V2Vic2l0ZQ==
dG8=
@@ -1747,6 +1785,11 @@
Um9vdCBSZXNldCBQYXNzd29yZA==
WW91ciBuZXcgcGFzc3dvcmQgaXM6IDxpbnAyOm1fUGFyYW0gbmFtZT0icGFzc3dvcmQiLz4=
+
+ U3lzdGVtIExvZyBOb3RpZmljYXRpb25zICg8aW5wMjpzeXN0ZW0tbG9nLmVtYWlsX1RvdGFsUmVjb3Jkcy8+KQ==
+ PGlucDI6bV9EZWZpbmVFbGVtZW50IG5hbWU9ImJhY2t0cmFjZV9lbGVtZW50Ij4NCgk8bGk+PGlucDI6bV9QaHJhc2UgbmFtZT0ibGFfTG9nQmFja3RyYWNlRnVuY3Rpb24iLz46IDxpbnAyOm1fUGFyYW0gbmFtZT0iZmlsZV9pbmZvIi8+PC9saT4NCjwvaW5wMjptX0RlZmluZUVsZW1lbnQ+DQoNCjxpbnAyOm1fRGVmaW5lRWxlbWVudCBuYW1lPSJzeXN0ZW1fbG9nX2VsZW1lbnQiPg0KCTxoND48aW5wMjpGaWVsZCBuYW1lPSJMb2dUaW1lc3RhbXAiIGZvcm1hdD0iTSBkIEg6aTpzIi8+IDxpbnAyOkZpZWxkIG5hbWU9IkxvZ0hvc3RuYW1lIi8+IDxpbnAyOlJlcXVlc3RVUkkgaHRtbF9lc2NhcGU9IjEiLz5bUElEPTxpbnAyOkZpZWxkIG5hbWU9IkxvZ1Byb2Nlc3NJZCIvPixVSUQ9PGlucDI6RmllbGQgbmFtZT0iTG9nVW5pcXVlSWQiLz5dPC9oND4NCglbPGlucDI6RmllbGQgbmFtZT0iTG9nTGV2ZWwiLz5dICM8aW5wMjpGaWVsZCBuYW1lPSJMb2dDb2RlIi8+OiA8aW5wMjpGaWVsZCBuYW1lPSJMb2dNZXNzYWdlIiBub19zcGVjaWFsPSIxIi8+IGluIDxpbnAyOkZpbGVuYW1lLz4gb24gbGluZSA8aW5wMjpGaWVsZCBuYW1lPSJMb2dTb3VyY2VGaWxlTGluZSIvPjxici8+DQoNCgk8aW5wMjptX2lmIGNoZWNrPSJGaWVsZCIgbmFtZT0iTG9nQmFja3RyYWNlIiBkYj0iZGIiPg0KCQk8YnIvPkJhY2t0cmFjZToNCg0KCQk8b2wgc3R5bGU9Im1hcmdpbjogMDsgcGFkZGluZy1sZWZ0OiAyNXB4OyBmb250LXNpemU6IDEycHg7Ij4NCgkJCTxpbnAyOlByaW50QmFja3RyYWNlIHJlbmRlcl9hcz0iYmFja3RyYWNlX2VsZW1lbnQiLz4NCgkJPC9vbD4NCgk8L2lucDI6bV9pZj4NCg0KCTxpbnAyOm1faWZub3QgY2hlY2s9Im1fUGFyYW0iIG5hbWU9ImlzX2xhc3QiPjxoci8+PC9pbnAyOm1faWZub3Q+DQo8L2lucDI6bV9EZWZpbmVFbGVtZW50Pg0KDQo8aW5wMjpzeXN0ZW0tbG9nLmVtYWlsX1ByaW50TGlzdCByZW5kZXJfYXM9InN5c3RlbV9sb2dfZWxlbWVudCIvPg==
+ PGlucDI6bV9EZWZpbmVFbGVtZW50IG5hbWU9ImJhY2t0cmFjZV9wbGFpbl9lbGVtZW50Ij4NCjxpbnAyOkJhY2t0cmFjZUluZGV4Lz4uIDxpbnAyOm1fUGhyYXNlIG5hbWU9ImxhX0xvZ0JhY2t0cmFjZUZ1bmN0aW9uIi8+OiA8aW5wMjptX1BhcmFtIG5hbWU9ImZpbGVfaW5mbyIvPg0KPGlucDI6bV9pZm5vdCBjaGVjaz0ibV9QYXJhbSIgbmFtZT0iaXNfbGFzdCI+DQoNCjwvaW5wMjptX2lmbm90Pg0KPC9pbnAyOm1fRGVmaW5lRWxlbWVudD4NCjxpbnAyOm1fRGVmaW5lRWxlbWVudCBuYW1lPSJzeXN0ZW1fbG9nX3BsYWluX2VsZW1lbnQiPg0KPGlucDI6RmllbGQgbmFtZT0iTG9nVGltZXN0YW1wIiBmb3JtYXQ9Ik0gZCBIOmk6cyIvPiA8aW5wMjpGaWVsZCBuYW1lPSJMb2dIb3N0bmFtZSIvPiA8aW5wMjpSZXF1ZXN0VVJJLz5bUElEPTxpbnAyOkZpZWxkIG5hbWU9IkxvZ1Byb2Nlc3NJZCIvPixVSUQ9PGlucDI6RmllbGQgbmFtZT0iTG9nVW5pcXVlSWQiLz5dDQpbPGlucDI6RmllbGQgbmFtZT0iTG9nTGV2ZWwiLz5dICM8aW5wMjpGaWVsZCBuYW1lPSJMb2dDb2RlIi8+OiA8aW5wMjpGaWVsZCBuYW1lPSJMb2dNZXNzYWdlIiBub19zcGVjaWFsPSIxIi8+IGluIDxpbnAyOkZpbGVuYW1lLz4gb24gbGluZSA8aW5wMjpGaWVsZCBuYW1lPSJMb2dTb3VyY2VGaWxlTGluZSIvPg0KPGlucDI6bV9pZiBjaGVjaz0iRmllbGQiIG5hbWU9IkxvZ0JhY2t0cmFjZSIgZGI9ImRiIj4NCg0KQmFja3RyYWNlOg0KPGlucDI6UHJpbnRCYWNrdHJhY2UgcmVuZGVyX2FzPSJiYWNrdHJhY2VfcGxhaW5fZWxlbWVudCIgc3RyaXBfdGFncz0iMSIvPjwvaW5wMjptX2lmPg0KPGlucDI6bV9pZm5vdCBjaGVjaz0ibV9QYXJhbSIgbmFtZT0iaXNfbGFzdCI+DQotLS0tLS0tLS0tLS0tDQoNCjwvaW5wMjptX2lmbm90Pg0KPC9pbnAyOm1fRGVmaW5lRWxlbWVudD4NCjxpbnAyOnN5c3RlbS1sb2cuZW1haWxfUHJpbnRMaXN0IHJlbmRlcl9hcz0ic3lzdGVtX2xvZ19wbGFpbl9lbGVtZW50Ii8+
+
SW4tcG9ydGFsIHJlZ2lzdHJhdGlvbg==
RGVhciA8aW5wMjp1LnJlZ2lzdGVyX0ZpZWxkIG5hbWU9IkZpcnN0TmFtZSIgLz4gPGlucDI6dS5yZWdpc3Rlcl9GaWVsZCBuYW1lPSJMYXN0TmFtZSIgLz4sDQoNClRoYW5rIHlvdSBmb3IgcmVnaXN0ZXJpbmcgb24gPGlucDI6bV9MaW5rIHRlbXBsYXRlPSJpbmRleCIvPi4gWW91ciByZWdpc3RyYXRpb24gaXMgbm93IGFjdGl2ZS4NCjxpbnAyOm1faWYgY2hlY2s9InUucmVnaXN0ZXJfRmllbGQiIG5hbWU9IkVtYWlsIj4NCjxici8+PGJyLz4NClBsZWFzZSBjbGljayBoZXJlIHRvIHZlcmlmeSB5b3VyIEUtbWFpbCBhZGRyZXNzOg0KPGEgaHJlZj0iPGlucDI6dS5yZWdpc3Rlcl9Db25maXJtUGFzc3dvcmRMaW5rIHQ9InBsYXRmb3JtL215X2FjY291bnQvdmVyaWZ5X2VtYWlsIiBub19hbXA9IjEiLz4iPjxpbnAyOnUucmVnaXN0ZXJfQ29uZmlybVBhc3N3b3JkTGluayB0PSJwbGF0Zm9ybS9teV9hY2NvdW50L3ZlcmlmeV9lbWFpbCIgbm9fYW1wPSIxIi8+PC9hPjxici8+PGJyLz4NCjwvaW5wMjptX2lmPg==
Index: branches/5.2.x/core/units/logs/system_logs/system_log_tp.php
===================================================================
diff -u
--- branches/5.2.x/core/units/logs/system_logs/system_log_tp.php (revision 0)
+++ branches/5.2.x/core/units/logs/system_logs/system_log_tp.php (revision 15552)
@@ -0,0 +1,175 @@
+getObject($params);
+ /* @var $object kDBItem */
+
+ $filename = $object->GetDBField('LogSourceFilename');
+
+ if ( !$filename ) {
+ return '';
+ }
+
+ return preg_replace('/^' . preg_quote(FULL_PATH, '/') . '/', '...', $filename, 1);
+ }
+
+ /**
+ * Displays filename
+ *
+ * @param Array $params
+ * @return string
+ * @access protected
+ */
+ protected function RequestURI($params)
+ {
+ $object = $this->getObject($params);
+ /* @var $object kDBItem */
+
+ $request_uri = $object->GetDBField('LogRequestURI');
+
+ if ( !$request_uri ) {
+ return '';
+ }
+
+ return preg_replace('/^' . preg_quote(BASE_PATH, '/') . '/', '...', $request_uri, 1);
+ }
+
+ /**
+ * Displays used memory
+ *
+ * @param Array $params
+ * @return string
+ * @access protected
+ */
+ protected function MemoryUsage($params)
+ {
+ $object = $this->getObject($params);
+ /* @var $object kDBItem */
+
+ return kUtil::formatSize($object->GetDBField('LogMemoryUsed'));
+ }
+
+ /**
+ * Prints serialized array
+ *
+ * @param Array $params
+ * @return string
+ * @access protected
+ */
+ protected function PrintArray($params)
+ {
+ $object = $this->getObject($params);
+ /* @var $object kDBItem */
+
+ $field = $params['field'];
+ $value = $object->GetDBField($field);
+
+ if ( !$value ) {
+ return '';
+ }
+
+ $value = print_r(unserialize($value), true);
+
+ return $this->highlightString($value);
+ }
+
+ /**
+ * Prints backtrace result
+ *
+ * @param Array $params
+ * @return string
+ * @access protected
+ */
+ protected function PrintBacktrace($params)
+ {
+ $object = $this->getObject($params);
+ /* @var $object kDBItem */
+
+ $value = $object->GetDBField('LogBacktrace');
+
+ if ( !$value ) {
+ return '';
+ }
+
+ $ret = '';
+ $trace = unserialize($value);
+ $include_args = isset($params['include_args']) ? $params['include_args'] : false;
+ $strip_tags = isset($params['strip_tags']) ? $params['strip_tags'] : false;
+
+ $block_params = $this->prepareTagParams($params);
+ $block_params['name'] = $params['render_as'];
+
+ foreach ($trace as $index => $trace_info) {
+ $block_params['index'] = $index;
+
+ if ( isset($trace_info['file']) ) {
+ $function_name = isset($trace_info['class']) ? $trace_info['class'] . $trace_info['type'] . $trace_info['function'] : $trace_info['function'];
+ $block_params['file_info'] = $function_name . ' in ' . basename($trace_info['file']) . ' on line ' . $trace_info['line'] . ' ';
+
+ if ( $strip_tags ) {
+ $block_params['file_info'] = strip_tags($block_params['file_info']);
+ }
+ }
+ else {
+ $block_params['file_info'] = 'no file information available';
+ }
+
+ $block_params['has_args'] = isset($trace_info['args']);
+
+ if ( $include_args ) {
+ $block_params['args'] = $block_params['has_args'] ? $this->highlightString(print_r($trace_info['args'], true)) : '';
+ }
+
+ $ret .= $this->Application->ParseBlock($block_params);
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Prints backtrace record index
+ *
+ * @param Array $params
+ * @return string
+ * @access protected
+ */
+ protected function BacktraceIndex($params)
+ {
+ $index = $this->Application->Parser->GetParam('index') + 1;
+
+ return str_pad($index, 3, ' ', STR_PAD_LEFT);
+ }
+
+ public function highlightString($string)
+ {
+ $string = str_replace(Array ('\\', '/'), Array ('_nms1_', '_nms2_'), $string);
+ $string = highlight_string('', true);
+ $string = str_replace(Array ('_nms1_', '_nms2_'), Array ('\\', '/'), $string);
+
+ return str_replace(Array ('<?php ', '?>'), '', $string);
+ }
+}
Index: branches/5.2.x/core/admin_templates/logs/system_logs/system_log_list.tpl
===================================================================
diff -u
--- branches/5.2.x/core/admin_templates/logs/system_logs/system_log_list.tpl (revision 0)
+++ branches/5.2.x/core/admin_templates/logs/system_logs/system_log_list.tpl (revision 15552)
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ :
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: branches/5.2.x/core/kernel/utility/debugger.php
===================================================================
diff -u -r15530 -r15552
--- branches/5.2.x/core/kernel/utility/debugger.php (.../debugger.php) (revision 15530)
+++ branches/5.2.x/core/kernel/utility/debugger.php (.../debugger.php) (revision 15552)
@@ -1,6 +1,6 @@
profileStart('script_runtime', 'Script runtime', $start);
$this->LastMoment = $start;
- error_reporting(E_ALL);
+ error_reporting(E_ALL & ~E_STRICT);
// show errors on screen in case if not in Zend Studio debugging
ini_set('display_errors', DebuggerUtil::constOn('DBG_ZEND_PRESENT') ? 0 : 1);
@@ -403,7 +403,6 @@
'DBG_WINDOW_WIDTH' => 700, // set width of debugger window (in pixels) for better viewing large amount of debug data
'DBG_USE_SHUTDOWN_FUNC' => DBG_ZEND_PRESENT ? 0 : 1, // use shutdown function to include debugger code into output
'DBG_HANDLE_ERRORS' => DBG_ZEND_PRESENT ? 0 : 1, // handle all allowed by php (see php manual) errors instead of default handler
- 'DBG_IGNORE_STRICT_ERRORS' => 0, // ignore PHP5 errors about private/public view modified missing in class declarations
'DBG_DOMVIEWER' => '/temp/domviewer.html', // path to DOMViewer on website
'DOC_ROOT' => str_replace('\\', '/', realpath($_SERVER['DOCUMENT_ROOT']) ), // windows hack
'DBG_LOCAL_BASE_PATH' => 'w:', // replace DOC_ROOT in filenames (in errors) using this path
@@ -481,21 +480,6 @@
}
/**
- * Allows to overcome short error message problem in tigger_error function
- *
- * @param string $msg
- * @return int
- * @access public
- */
- public function mapLongError($msg)
- {
- $key = $this->generateID();
- $this->longErrors[$key] = $msg;
-
- return $key;
- }
-
- /**
* Appends all passed variable values (without variable names) to debug output
*
* @return void
@@ -1337,24 +1321,15 @@
private function getErrorNameByCode($error_code)
{
$error_map = Array (
- 'Fatal Error' => Array (E_USER_ERROR),
- 'Warning' => Array (E_WARNING, E_USER_WARNING),
- 'Notice' => Array (E_NOTICE, E_USER_NOTICE),
+ 'Fatal Error' => Array (E_RECOVERABLE_ERROR, E_USER_ERROR, E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE),
+ 'Warning' => Array (E_WARNING, E_USER_WARNING, E_CORE_WARNING, E_COMPILE_WARNING),
+ 'Notice' => Array (E_NOTICE, E_USER_NOTICE, E_STRICT),
);
- if ( defined('E_STRICT') ) {
- // since PHP 5
- $error_map['PHP5 Strict'] = Array (E_STRICT);
- }
-
- if ( defined('E_RECOVERABLE_ERROR') ) {
- // since PHP 5.2
- $error_map['Fatal Error (recoverable)'] = Array (E_RECOVERABLE_ERROR);
- }
-
if ( defined('E_DEPRECATED') ) {
// since PHP 5.3
- $error_map['PHP5 Depricated'] = Array (E_DEPRECATED, E_USER_DEPRECATED);
+ $error_map['Notice'][] = E_DEPRECATED;
+ $error_map['Notice'][] = E_USER_DEPRECATED;
}
foreach ($error_map as $error_name => $error_codes) {
@@ -1429,6 +1404,13 @@
return '';
}
+ $last_error = error_get_last();
+
+ if ( !is_null($last_error) && !$this->_lastErrorProcessed ) {
+ $this->_lastErrorProcessed = true;
+ $this->saveError($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']);
+ }
+
$this->profileFinish('script_runtime');
$this->breakOutofBuffering(!$returnResult);
@@ -1713,10 +1695,6 @@
$this->appendTrace(4);
}
- if ( DebuggerUtil::constOn('DBG_IGNORE_STRICT_ERRORS') && defined('E_STRICT') && ($errno == E_STRICT) ) {
- return false;
- }
-
$this->expandError($errstr, $errfile, $errline);
$this->Data[] = Array (
@@ -1795,11 +1773,11 @@
*/
private function expandError(&$errstr, &$errfile, &$errline)
{
- if ( preg_match('/(.*)#([\d]+)$/', $errstr, $rets) ) {
- // replace short message with long one (due triger_error limitations on message size)
- $long_id = $rets[2];
- $errstr = $this->longErrors[$long_id];
- unset($this->longErrors[$long_id]);
+ $errstr = kLogger::expandMessage($errstr);
+ list ($errno, $errstr, $sql) = kLogger::parseDatabaseError($errstr);
+
+ if ( $errno != 0 ) {
+ $errstr = '' . $errstr . ' (' . $errno . ') SQL : ' . $this->formatSQL($sql);
}
if ( strpos($errfile, 'eval()\'d code') !== false ) {
@@ -1886,20 +1864,14 @@
}
if ( class_exists('kApplication') ) {
- // replace application error/exception handler with own
- restore_error_handler();
- restore_exception_handler();
-
$this->Application =& kApplication::Instance();
- $this->Application->Debugger =& $this;
-
- $this->Application->errorHandlers[] = Array (&$this, 'saveError');
- $this->Application->exceptionHandlers[] = Array (&$this, 'saveException');
+ $this->Application->Debugger = $this;
}
- else {
- set_error_handler( Array (&$this, 'saveError') );
- set_exception_handler( Array (&$this, 'saveException') );
- }
+
+ // kLogger will auto-detect these automatically
+ // error/exception handlers registered before debugger will be removed!
+ set_error_handler( Array ($this, 'saveError') );
+ set_exception_handler( Array ($this, 'saveException') );
}
/**
Index: branches/5.2.x/core/install/install_data.sql
===================================================================
diff -u -r15524 -r15552
--- branches/5.2.x/core/install/install_data.sql (.../install_data.sql) (revision 15524)
+++ branches/5.2.x/core/install/install_data.sql (.../install_data.sql) (revision 15552)
@@ -89,7 +89,6 @@
INSERT INTO SystemSettings VALUES(DEFAULT, 'MailingListQueuePerStep', '10', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsMailling', 'la_config_MailingListQueuePerStep', 'text', NULL, NULL, 50.08, 0, 0, NULL);
INSERT INTO SystemSettings VALUES(DEFAULT, 'MailingListSendPerStep', '10', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsMailling', 'la_config_MailingListSendPerStep', 'text', NULL, NULL, 50.09, 0, 0, NULL);
INSERT INTO SystemSettings VALUES(DEFAULT, 'DefaultEmailRecipients', '', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsMailling', 'la_config_DefaultEmailRecipients', 'text', NULL, NULL, 50.10, 0, 0, NULL);
-INSERT INTO SystemSettings VALUES(DEFAULT, 'EmailLogRotationInterval', '2419200', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsMailling', 'la_config_EmailLogRotationInterval', 'select', NULL, '=la_opt_EmailLogKeepNever||86400=la_opt_OneDay||604800=la_opt_OneWeek||1209600=la_opt_TwoWeeks||2419200=la_opt_OneMonth||7257600=la_opt_ThreeMonths||29030400=la_opt_OneYear||-1=la_opt_EmailLogKeepForever', 50.11, 0, 0, 'hint:la_config_EmailLogRotationInterval');
INSERT INTO SystemSettings VALUES(DEFAULT, 'UseOutputCompression', '1', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsSystem', 'la_config_UseOutputCompression', 'checkbox', '', '', 60.01, 0, 1, NULL);
INSERT INTO SystemSettings VALUES(DEFAULT, 'OutputCompressionLevel', '7', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsSystem', 'la_config_OutputCompressionLevel', 'text', '', '', 60.02, 0, 1, NULL);
INSERT INTO SystemSettings VALUES(DEFAULT, 'UseTemplateCompression', '0', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsSystem', 'la_config_UseTemplateCompression', 'checkbox', '', '', 60.03, 0, 1, NULL);
@@ -99,6 +98,10 @@
INSERT INTO SystemSettings VALUES(DEFAULT, 'Backup_Path', '/home/alex/web/in-portal.rc/system/backupdata', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsSystem', 'la_config_backup_path', 'text', '', '', 60.07, 0, 1, NULL);
INSERT INTO SystemSettings VALUES(DEFAULT, 'SystemTagCache', '0', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsSystem', 'la_prompt_syscache_enable', 'checkbox', NULL, NULL, 60.08, 0, 0, NULL);
INSERT INTO SystemSettings VALUES(DEFAULT, 'SocketBlockingMode', '0', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsSystem', 'la_prompt_socket_blocking_mode', 'checkbox', NULL, NULL, 60.09, 0, 0, NULL);
+INSERT INTO SystemSettings VALUES(DEFAULT, 'EnableEmailLog', '1', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_EnableEmailLog', 'radio', NULL, '1=la_Yes||0=la_No', 65.01, 0, 1, 'hint:la_config_EnableEmailLog');
+INSERT INTO SystemSettings VALUES(DEFAULT, 'EmailLogRotationInterval', '2419200', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_EmailLogRotationInterval', 'select', NULL, '86400=la_opt_OneDay||604800=la_opt_OneWeek||1209600=la_opt_TwoWeeks||2419200=la_opt_OneMonth||7257600=la_opt_ThreeMonths||29030400=la_opt_OneYear||-1=la_opt_EmailLogKeepForever', 65.02, 0, 0, 'hint:la_config_EmailLogRotationInterval');
+INSERT INTO SystemSettings VALUES(DEFAULT, 'SystemLogRotationInterval', '2419200', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_SystemLogRotationInterval', 'select', NULL, '86400=la_opt_OneDay||604800=la_opt_OneWeek||1209600=la_opt_TwoWeeks||2419200=la_opt_OneMonth||7257600=la_opt_ThreeMonths||29030400=la_opt_OneYear||-1=la_opt_SystemLogKeepForever', 65.03, 0, 1, 'hint:la_config_SystemLogRotationInterval');
+INSERT INTO SystemSettings VALUES(DEFAULT, 'SystemLogNotificationEmail', '', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_SystemLogNotificationEmail', 'text', 'a:5:{s:4:"type";s:6:"string";s:9:"formatter";s:10:"kFormatter";s:6:"regexp";s:85:"/^([-a-zA-Z0-9!\\#$%&*+\\/=?^_`{|}~.]+@[a-zA-Z0-9]{1}[-.a-zA-Z0-9_]*\\.[a-zA-Z]{2,6})$/i";s:10:"error_msgs";a:1:{s:14:"invalid_format";s:18:"!la_invalid_email!";}s:7:"default";s:0:"";}', NULL, 65.04, 0, 1, 'hint:la_config_SystemLogNotificationEmail');
INSERT INTO SystemSettings VALUES(DEFAULT, 'CSVExportDelimiter', '1', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsCSVExport', 'la_config_CSVExportDelimiter', 'select', NULL, '0=la_opt_Tab||1=la_opt_Comma||2=la_opt_Semicolon||3=la_opt_Space||4=la_opt_Colon', 70.01, 0, 1, NULL);
INSERT INTO SystemSettings VALUES(DEFAULT, 'CSVExportEnclosure', '0', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsCSVExport', 'la_config_CSVExportEnclosure', 'radio', NULL, '0=la_Doublequotes||1=la_Quotes', 70.02, 0, 1, NULL);
INSERT INTO SystemSettings VALUES(DEFAULT, 'CSVExportSeparator', '0', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsCSVExport', 'la_config_CSVExportSeparator', 'radio', NULL, '0=la_Linux||1=la_Windows', 70.03, 0, 1, NULL);
@@ -183,6 +186,7 @@
INSERT INTO EmailEvents (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, Module, Description, Type, AllowChangingSender, AllowChangingRecipient) VALUES(DEFAULT, 'ROOT.RESET.PASSWORD', NULL, 1, 0, 'Core', 'Root Reset Password', 1, 1, 0);
INSERT INTO EmailEvents (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, Module, Description, Type, AllowChangingSender, AllowChangingRecipient) VALUES(DEFAULT, 'USER.EMAIL.CHANGE.VERIFY', NULL, 1, 0, 'Core', 'Changed E-mail Verification', 0, 1, 1);
INSERT INTO EmailEvents (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, Module, Description, Type, AllowChangingSender, AllowChangingRecipient) VALUES(DEFAULT, 'USER.EMAIL.CHANGE.UNDO', NULL, 1, 0, 'Core', 'Changed E-mail Rollback', 0, 1, 1);
+INSERT INTO EmailEvents (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, Module, Description, Type, AllowChangingSender, AllowChangingRecipient) VALUES(DEFAULT, 'SYSTEM.LOG.NOTIFY', NULL, 1, 0, 'Core', 'Notification about message added to System Log', 1, 1, 1);
INSERT INTO IdGenerator VALUES ('100');
Index: branches/5.2.x/tools/debug_sample.php
===================================================================
diff -u -r15435 -r15552
--- branches/5.2.x/tools/debug_sample.php (.../debug_sample.php) (revision 15435)
+++ branches/5.2.x/tools/debug_sample.php (.../debug_sample.php) (revision 15552)
@@ -1,6 +1,6 @@
getObject();
+ /* @var $object kDBList */
+
+ if ( $event->Special == 'email' ) {
+ $unique_id = $event->getEventParam('unique_id');
+
+ if ( $unique_id !== false ) {
+ $object->addFilter('notification_filter', '%1$s.LogNotificationStatus = ' . kLogger::LNS_SENT);
+ $object->addFilter('unique_filter', '%1$s.LogUniqueId = ' . $unique_id);
+ }
+ else {
+ $object->addFilter('notification_filter', '%1$s.LogNotificationStatus = ' . kLogger::LNS_PENDING);
+ }
+ }
+ }
+
+ /**
+ * [SCHEDULED TASK] Sends delayed notification of system log messages
+ *
+ * @param kEvent $event
+ * @return void
+ * @access protected
+ */
+ protected function OnSendNotifications(kEvent $event)
+ {
+ // initialize list outside of e-mail event with right settings
+ $list = $this->Application->recallObject($event->Prefix . '.email', $event->Prefix . '_List', Array ('per_page' => 20));
+ /* @var $list kDBList */
+
+ if ( !$list->GetRecordsCount() ) {
+ // no messages, that needs to be sent
+ return;
+ }
+
+ $notification_email = $this->Application->ConfigValue('SystemLogNotificationEmail');
+
+ if ( !$notification_email ) {
+ $this->Application->removeObject($event->Prefix . '.email');
+ trigger_error('System Log notification E-mail not specified', E_USER_NOTICE);
+
+ return;
+ }
+
+ $send_params = Array (
+ 'to_name' => $notification_email,
+ 'to_email' => $notification_email,
+ );
+
+ $this->Application->EmailEventAdmin('SYSTEM.LOG.NOTIFY', null, $send_params);
+ $this->Application->removeObject($event->Prefix . '.email');
+
+ $object = $event->getObject(Array ('skip_autoload' => true));
+ /* @var $object kDBItem */
+
+ foreach ($list as $fields_hash) {
+ $object->LoadFromHash($fields_hash);
+ $object->SetDBField('LogNotificationStatus', kLogger::LNS_SENT);
+ $object->Update();
+ }
+ }
+
+ /**
+ * [SCHEDULED TASK] Will remove old system logs
+ *
+ * @param kEvent $event
+ * @return void
+ * @access protected
+ */
+ protected function OnRotate(kEvent $event)
+ {
+ $rotation_interval = (int)$this->Application->ConfigValue('SystemLogRotationInterval');
+
+ if ( $rotation_interval === -1 ) {
+ // forever
+ return;
+ }
+
+ $sql = 'SELECT ' . $this->Application->getUnitOption($event->Prefix, 'IDField') . '
+ FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . '
+ WHERE ' . TIMENOW . ' - LogTimestamp > ' . $rotation_interval . '
+ LIMIT 0,50';
+ $ids = $this->Conn->GetCol($sql);
+
+ if ( $ids ) {
+ $temp_handler = $this->Application->recallObject($event->getPrefixSpecial() . '_TempHandler', 'kTempTablesHandler', Array ('parent_event' => $event));
+ /* @var $temp_handler kTempTablesHandler */
+
+ $temp_handler->DeleteItems($event->Prefix, $event->Special, $ids);
+ }
+ }
+}
Index: branches/5.2.x/core/kernel/application.php
===================================================================
diff -u -r15543 -r15552
--- branches/5.2.x/core/kernel/application.php (.../application.php) (revision 15543)
+++ branches/5.2.x/core/kernel/application.php (.../application.php) (revision 15552)
@@ -1,6 +1,6 @@
Debugger->appendMemoryUsage('Application before Init:');
}
- if ( !$this->isDebugMode() && !kUtil::constOn('DBG_ZEND_PRESENT') ) {
- error_reporting(0);
- ini_set('display_errors', 0);
- }
-
- if ( !kUtil::constOn('DBG_ZEND_PRESENT') ) {
- $error_handler = set_error_handler(Array (&$this, 'handleError'));
- if ( $error_handler ) {
- // wrap around previous error handler, if any was set
- $this->errorHandlers[] = $error_handler;
- }
-
- $exception_handler = set_exception_handler(Array (&$this, 'handleException'));
- if ( $exception_handler ) {
- // wrap around previous exception handler, if any was set
- $this->exceptionHandlers[] = $exception_handler;
- }
- }
-
+ $this->_logger = new kLogger($this->_logger);
$this->Factory = new $factory_class();
$this->registerDefaultClasses();
$vars = kUtil::parseConfig(true);
$db_class = isset($vars['Databases']) ? 'kDBLoadBalancer' : ($this->isDebugMode() ? 'kDBConnectionDebug' : 'kDBConnection');
- $this->Conn = $this->Factory->makeClass($db_class, Array (SQL_TYPE, Array (&$this, 'handleSQLError')));
+ $this->Conn = $this->Factory->makeClass($db_class, Array (SQL_TYPE, Array ($this->_logger, 'handleSQLError')));
$this->Conn->setup($vars);
$this->cacheManager = $this->makeClass('kCacheManager');
@@ -752,6 +726,7 @@
$this->registerClass('kTempTablesHandler', KERNEL_PATH . '/utility/temp_handler.php');
$this->registerClass('kValidator', KERNEL_PATH . '/utility/validator.php');
$this->registerClass('kOpenerStack', KERNEL_PATH . '/utility/opener_stack.php');
+ $this->registerClass('kLogger', KERNEL_PATH . '/utility/logger.php');
$this->registerClass('kUnitConfigReader', KERNEL_PATH . '/utility/unit_config_reader.php');
@@ -2404,224 +2379,15 @@
* @param string $sql
* @return bool
* @access public
+ * @throws Exception
+ * @deprecated
*/
public function handleSQLError($code, $msg, $sql)
{
- if ( isset($this->Debugger) ) {
- $long_error_msg = '' . $msg . ' (' . $code . ') SQL : ' . $this->Debugger->formatSQL($sql);
- $long_id = $this->Debugger->mapLongError($long_error_msg);
- $error_msg = mb_substr($msg . ' (' . $code . ') [' . $sql . ']', 0, 1000) . ' #' . $long_id;
-
- if ( kUtil::constOn('DBG_SQL_FAILURE') && !defined('IS_INSTALL') ) {
- throw new Exception($error_msg);
- }
- else {
- $this->Debugger->appendTrace();
- }
- }
- else {
- // when not debug mode, then fatal database query won't break anything
- $error_msg = 'SQL Error in sql: ' . $sql . ', code ' . $code . ' (' . $msg . ')';
- }
-
- trigger_error($error_msg, E_USER_WARNING);
-
- return true;
+ return $this->_logger->handleSQLError($code, $msg, $sql);
}
/**
- * Default error handler
- *
- * @param int $errno
- * @param string $errstr
- * @param string $errfile
- * @param int $errline
- * @param Array $errcontext
- * @return bool
- * @access public
- */
- public function handleError($errno, $errstr, $errfile = null, $errline = null, $errcontext = Array ())
- {
- $this->errorLogSilent($errno, $errstr, $errfile, $errline);
-
- $debug_mode = defined('DEBUG_MODE') && DEBUG_MODE;
- $skip_reporting = defined('DBG_SKIP_REPORTING') && DBG_SKIP_REPORTING;
-
- if ( !$this->errorHandlers || ($debug_mode && $skip_reporting) ) {
- // when debugger absent OR it's present, but we actually can't see it's error report (e.g. during ajax request)
- if ( $errno == E_USER_ERROR ) {
- $this->errorDisplayFatal('Fatal Error: ' . "{$errstr} in {$errfile} on line {$errline}");
- }
-
- if ( !$this->errorHandlers ) {
- return true;
- }
- }
-
- $res = false;
- /* @var $handler Closure */
-
- foreach ($this->errorHandlers as $handler) {
- if ( is_array($handler) ) {
- $object =& $handler[0];
- $method = $handler[1];
- $res = $object->$method($errno, $errstr, $errfile, $errline, $errcontext);
- }
- else {
- $res = $handler($errno, $errstr, $errfile, $errline, $errcontext);
- }
- }
-
- return $res;
- }
-
- /**
- * Handles exception
- *
- * @param Exception $exception
- * @return bool
- * @access public
- */
- public function handleException($exception)
- {
- // transform exception to regular error (no need to rewrite existing error handlers)
- $errno = $exception->getCode();
- $errstr = $exception->getMessage();
- $errfile = $exception->getFile();
- $errline = $exception->getLine();
-
- $this->errorLogSilent($errno, $errstr, $errfile, $errline);
-
- $debug_mode = defined('DEBUG_MODE') && DEBUG_MODE;
- $skip_reporting = defined('DBG_SKIP_REPORTING') && DBG_SKIP_REPORTING;
-
- if ( $exception instanceof kRedirectException ) {
- /* @var $exception kRedirectException */
-
- $exception->run();
- }
-
- if ( !$this->exceptionHandlers || ($debug_mode && $skip_reporting) ) {
- // when debugger absent OR it's present, but we actually can't see it's error report (e.g. during ajax request)
- $this->errorDisplayFatal('' . get_class($exception) . ': ' . "{$errstr} in {$errfile} on line {$errline}");
-
- if ( !$this->exceptionHandlers ) {
- return true;
- }
- }
-
- $res = false;
- /* @var $handler Closure */
-
- foreach ($this->exceptionHandlers as $handler) {
- if ( is_array($handler) ) {
- $object =& $handler[0];
- $method = $handler[1];
- $res = $object->$method($exception);
- }
- else {
- $res = $handler($exception);
- }
- }
-
- return $res;
- }
-
- /**
- * Silently saves each given error message to "silent_log.txt" file, when silent log mode is enabled
- * @param int $errno
- * @param string $errstr
- * @param string $errfile
- * @param int $errline
- * @return void
- * @access protected
- */
- protected function errorLogSilent($errno, $errstr = '', $errfile = '', $errline = null)
- {
- if ( !defined('SILENT_LOG') || !SILENT_LOG ) {
- return;
- }
-
- if ( !(defined('DBG_IGNORE_STRICT_ERRORS') && DBG_IGNORE_STRICT_ERRORS && defined('E_STRICT') && ($errno == E_STRICT)) ) {
- $time = adodb_date('d/m/Y H:i:s');
-
- $fp = fopen((defined('RESTRICTED') ? RESTRICTED : FULL_PATH) . '/silent_log.txt', 'a');
- fwrite($fp, '[' . $time . '] #' . $errno . ': ' . strip_tags($errstr) . ' in [' . $errfile . '] on line ' . $errline . "\n");
- fclose($fp);
- }
- }
-
- /**
- * Displays div with given error message
- *
- * @param string $msg
- * @return void
- * @access protected
- */
- protected function errorDisplayFatal($msg)
- {
- $margin = $this->isAdmin ? '8px' : 'auto';
- echo '' . $msg . '
';
- exit;
- }
-
- /**
- * Prints trace, when debug mode is not available
- *
- * @param bool $return_result
- * @param int $skip_levels
- * @return string
- * @access public
- */
- public function printTrace($return_result = false, $skip_levels = 1)
- {
- $ret = Array ();
- $trace = debug_backtrace(false);
-
- for ($i = 0; $i < $skip_levels; $i++) {
- array_shift($trace);
- }
-
- foreach ($trace as $level => $trace_info) {
- if ( isset($trace_info['class']) ) {
- $object = $trace_info['class'];
- }
- elseif ( isset($trace_info['object']) ) {
- $object = get_class($trace_info['object']);
- }
- else {
- $object = '';
- }
-
- $args = '';
- $type = isset($trace_info['type']) ? $trace_info['type'] : '';
-
- if ( isset($trace_info['args']) ) {
- foreach ($trace_info['args'] as $argument) {
- if ( is_object($argument) ) {
- $args .= get_class($argument) . ' instance, ';
- }
- else {
- $args .= is_array($argument) ? 'Array' : substr($argument, 0, 10) . ' ..., ';
- }
- }
-
- $args = substr($args, 0, -2);
- }
-
- $ret[] = '#' . $level . ' ' . $object . $type . $trace_info['function'] . '(' . $args . ') called at [' . $trace_info['file'] . ':' . $trace_info['line'] . ']';
- }
-
- if ( $return_result ) {
- return implode("\n", $ret);
- }
-
- echo implode("\n", $ret);
-
- return '';
- }
-
- /**
* Returns & blocks next ResourceId available in system
*
* @return int
@@ -3238,4 +3004,38 @@
$already_set = true;
header($header);
}
+
+ /**
+ * Posts message to event log
+ *
+ * @param string $message
+ * @param int $code
+ * @param bool $write_now Allows further customization of log record by returning kLog object
+ * @return bool|int|kLogger
+ * @access public
+ */
+ public function log($message, $code = null, $write_now = false)
+ {
+ $log = $this->_logger->prepare($message, $code)->addSource($this->_logger->createTrace(null, 1));
+
+ if ( $write_now ) {
+ return $log->write();
+ }
+
+ return $log;
+ }
+
+ /**
+ * Deletes log with given id from database or disk, when database isn't available
+ *
+ * @param int $unique_id
+ * @param int $storage_medium
+ * @return void
+ * @access public
+ * @throws InvalidArgumentException
+ */
+ public function deleteLog($unique_id, $storage_medium = kLogger::LS_AUTOMATIC)
+ {
+ $this->_logger->delete($unique_id, $storage_medium);
+ }
}
\ No newline at end of file
Index: branches/5.2.x/core/units/logs/email_logs/email_log_eh.php
===================================================================
diff -u -r15230 -r15552
--- branches/5.2.x/core/units/logs/email_logs/email_log_eh.php (.../email_log_eh.php) (revision 15230)
+++ branches/5.2.x/core/units/logs/email_logs/email_log_eh.php (.../email_log_eh.php) (revision 15552)
@@ -1,6 +1,6 @@
Application->ConfigValue('EmailLogRotationInterval');
+ $rotation_interval = (int)$this->Application->ConfigValue('EmailLogRotationInterval');
- if ( $rotation_interval == '' || $rotation_interval == -1 ) {
- // never OR forever
+ if ( $rotation_interval === -1 ) {
+ // forever
return;
}
Index: branches/5.2.x/core/install/remove_schema.sql
===================================================================
diff -u -r15268 -r15552
--- branches/5.2.x/core/install/remove_schema.sql (.../remove_schema.sql) (revision 15268)
+++ branches/5.2.x/core/install/remove_schema.sql (.../remove_schema.sql) (revision 15552)
@@ -20,6 +20,7 @@
DROP TABLE UserGroupRelations;
DROP TABLE UserSessions;
DROP TABLE EmailLog;
+DROP TABLE SystemLog;
DROP TABLE SystemCache;
DROP TABLE CountryStates;
DROP TABLE Categories;
Index: branches/5.2.x/core/install/upgrades.sql
===================================================================
diff -u -r15550 -r15552
--- branches/5.2.x/core/install/upgrades.sql (.../upgrades.sql) (revision 15550)
+++ branches/5.2.x/core/install/upgrades.sql (.../upgrades.sql) (revision 15552)
@@ -2806,3 +2806,53 @@
INSERT INTO EmailEvents (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, Module, Description, Type, AllowChangingSender, AllowChangingRecipient) VALUES(DEFAULT, 'USER.NEW.PASSWORD', NULL, 1, 0, 'Core', 'Sends new password to an existing user', 0, 1, 0);
INSERT INTO EmailEvents (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, Module, Description, Type, AllowChangingSender, AllowChangingRecipient) VALUES(DEFAULT, 'USER.ADD.BYADMIN', NULL, 1, 0, 'Core', 'Sends password to a new user', 0, 1, 0);
+
+CREATE TABLE SystemLog (
+ LogId int(11) NOT NULL AUTO_INCREMENT,
+ LogUniqueId int(11) DEFAULT NULL,
+ LogLevel tinyint(4) NOT NULL DEFAULT '7',
+ LogType tinyint(4) NOT NULL DEFAULT '3',
+ LogCode int(11) DEFAULT NULL,
+ LogMessage longtext,
+ LogTimestamp int(11) DEFAULT NULL,
+ LogDate datetime DEFAULT NULL,
+ LogEventName varchar(100) NOT NULL DEFAULT '',
+ LogHostname varchar(255) NOT NULL DEFAULT '',
+ LogRequestSource tinyint(4) DEFAULT NULL,
+ LogRequestURI varchar(255) NOT NULL DEFAULT '',
+ LogRequestData longtext,
+ LogUserId int(11) DEFAULT NULL,
+ LogInterface tinyint(4) DEFAULT NULL,
+ IpAddress varchar(15) NOT NULL DEFAULT '',
+ LogSessionKey int(11) DEFAULT NULL,
+ LogSessionData longtext,
+ LogBacktrace longtext,
+ LogSourceFilename varchar(255) NOT NULL DEFAULT '',
+ LogSourceFileLine int(11) DEFAULT NULL,
+ LogProcessId bigint(20) unsigned DEFAULT NULL,
+ LogMemoryUsed bigint(20) unsigned NOT NULL,
+ LogUserData longtext NOT NULL,
+ LogNotificationStatus tinyint(4) NOT NULL DEFAULT '0',
+ PRIMARY KEY (LogId),
+ KEY LogLevel (LogLevel),
+ KEY LogType (LogType),
+ KEY LogNotificationStatus (LogNotificationStatus)
+);
+
+INSERT INTO SystemSettings VALUES(DEFAULT, 'EnableEmailLog', '1', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_EnableEmailLog', 'radio', NULL, '1=la_Yes||0=la_No', 65.01, 0, 1, 'hint:la_config_EnableEmailLog');
+
+UPDATE SystemSettings
+SET DisplayOrder = 65.02, Heading = 'la_section_SettingsLogs', ValueList = '86400=la_opt_OneDay||604800=la_opt_OneWeek||1209600=la_opt_TwoWeeks||2419200=la_opt_OneMonth||7257600=la_opt_ThreeMonths||29030400=la_opt_OneYear||-1=la_opt_EmailLogKeepForever'
+WHERE VariableName = 'EmailLogRotationInterval';
+
+UPDATE LanguageLabels
+SET
+ l<%PRIMARY_LANGUAGE%>_Translation = 'Keep "E-mail Log" for',
+ l<%PRIMARY_LANGUAGE%>_HintTranslation = 'This setting allows you to control for how long "E-mail Log" messages will be stored in the log and then automatically deleted. Use option "Forever" with caution since it will completely disable automatic log cleanup and can lead to large size of database table that stores e-mail messages.'
+WHERE PhraseKey = 'LA_CONFIG_EMAILLOGROTATIONINTERVAL' AND l<%PRIMARY_LANGUAGE%>_Translation = 'Keep Email Log for';
+
+DELETE FROM LanguageLabels WHERE PhraseKey = 'LA_OPT_EMAILLOGKEEPNEVER';
+
+INSERT INTO SystemSettings VALUES(DEFAULT, 'SystemLogRotationInterval', '2419200', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_SystemLogRotationInterval', 'select', NULL, '86400=la_opt_OneDay||604800=la_opt_OneWeek||1209600=la_opt_TwoWeeks||2419200=la_opt_OneMonth||7257600=la_opt_ThreeMonths||29030400=la_opt_OneYear||-1=la_opt_SystemLogKeepForever', 65.03, 0, 1, 'hint:la_config_SystemLogRotationInterval');
+INSERT INTO SystemSettings VALUES(DEFAULT, 'SystemLogNotificationEmail', '', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_SystemLogNotificationEmail', 'text', 'a:5:{s:4:"type";s:6:"string";s:9:"formatter";s:10:"kFormatter";s:6:"regexp";s:85:"/^([-a-zA-Z0-9!\\#$%&*+\\/=?^_`{|}~.]+@[a-zA-Z0-9]{1}[-.a-zA-Z0-9_]*\\.[a-zA-Z]{2,6})$/i";s:10:"error_msgs";a:1:{s:14:"invalid_format";s:18:"!la_invalid_email!";}s:7:"default";s:0:"";}', NULL, 65.04, 0, 1, 'hint:la_config_SystemLogNotificationEmail');
+INSERT INTO EmailEvents (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, Module, Description, Type, AllowChangingSender, AllowChangingRecipient) VALUES(DEFAULT, 'SYSTEM.LOG.NOTIFY', NULL, 1, 0, 'Core', 'Notification about message added to System Log', 1, 1, 1);
Index: branches/5.2.x/core/kernel/db/db_connection.php
===================================================================
diff -u -r15518 -r15552
--- branches/5.2.x/core/kernel/db/db_connection.php (.../db_connection.php) (revision 15518)
+++ branches/5.2.x/core/kernel/db/db_connection.php (.../db_connection.php) (revision 15552)
@@ -1,6 +1,6 @@
connectionOpened;
+ }
+
+ /**
* Setups the connection according given configuration
*
* @param Array $config
Index: branches/5.2.x/core/admin_templates/logs/system_logs/system_log_edit.tpl
===================================================================
diff -u
--- branches/5.2.x/core/admin_templates/logs/system_logs/system_log_edit.tpl (revision 0)
+++ branches/5.2.x/core/admin_templates/logs/system_logs/system_log_edit.tpl (revision 15552)
@@ -0,0 +1,193 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ :
+
+
+
+
+
+ :
+
+
+
+
+
+
+
+
+
\ No newline at end of file
Index: branches/5.2.x/core/install/step_templates/sys_config.tpl
===================================================================
diff -u -r15445 -r15552
--- branches/5.2.x/core/install/step_templates/sys_config.tpl (.../sys_config.tpl) (revision 15445)
+++ branches/5.2.x/core/install/step_templates/sys_config.tpl (.../sys_config.tpl) (revision 15552)
@@ -11,10 +11,17 @@
'MemcacheServers' => Array ('type' => 'text', 'title' => 'Location of Memcache Servers', 'section' => 'Misc', 'default' => 'localhost:11211'),
'CompressionEngine' => Array ('type' => 'select', 'title' => 'CSS/JS Compression Engine', 'section' => 'Misc', 'default' => ''),
'WebsiteCharset' => Array ('type' => 'text', 'title' => 'Website Charset', 'section' => 'Misc', 'required' => 1, 'default' => 'utf-8'),
+ 'EnableSystemLog' => Array ('type' => 'radio', 'title' => 'Enable "System Log"', 'section' => 'Misc', 'required' => 1, 'default' => '0'),
+ 'SystemLogMaxLevel' => Array ('type' => 'select', 'title' => 'Highest "Log Level", that will be saved in "System Log"', 'section' => 'Misc', 'required' => 1, 'default' => '5'),
);
$settings['CacheHandler']['options'] = $this->toolkit->getWorkingCacheHandlers();
$settings['CompressionEngine']['options'] = $this->toolkit->getWorkingCompressionEngines();
+ $settings['EnableSystemLog']['options'] = Array (1 => 'Enabled', 2 => 'User-only', 0 => 'Disabled');
+ $settings['SystemLogMaxLevel']['options'] = Array (
+ 0 => 'emergency', 1 => 'alert', 2 => 'critical', 3 => 'error',
+ 4 => 'warning', 5 => 'notice', 6 => 'info', 7 => 'debug'
+ );
$row_class = 'table-color2';
@@ -29,26 +36,36 @@
toolkit->getSystemConfig($output_params['section'], $config_var, $output_params['default']);
- if ( $output_params['type'] == 'text' ) {
- echo ' ';
- }
- else {
- echo '';
+ switch ( $output_params['type'] ) {
+ case 'text':
+ echo ' ';
+ break;
- if ( $output_params['options'][$config_value] == 'None' ) {
- $tmp_values = array_keys($output_params['options']);
+ case 'select':
+ echo '';
- if ( count($tmp_values) > 1 ) {
- $config_value = $tmp_values[1];
+ if ( $output_params['options'][$config_value] == 'None' ) {
+ $tmp_values = array_keys($output_params['options']);
+
+ if ( count($tmp_values) > 1 ) {
+ $config_value = $tmp_values[1];
+ }
}
- }
- foreach($output_params['options'] as $option_key => $option_value) {
- $selected = $option_key == $config_value ? ' selected' : '';
- echo '' . $option_value . ' ';
- }
+ foreach($output_params['options'] as $option_key => $option_value) {
+ $selected = $option_key == $config_value ? ' selected' : '';
+ echo '' . $option_value . ' ';
+ }
- echo ' ';
+ echo ' ';
+ break;
+
+ case 'radio':
+ foreach($output_params['options'] as $option_key => $option_value) {
+ $selected = $option_key == $config_value ? ' checked' : '';
+ echo ' ' . $option_value;
+ }
+ break;
}
?>