2019-03-29 19:13:32 -05:00
< ? php
/**
* e107 website system
*
* Copyright ( C ) 2008 - 2010 e107 Inc ( e107 . org )
* Released under the terms and conditions of the
* GNU General Public License ( http :// www . gnu . org / licenses / gpl . txt )
*
* Admin Log Handler
*
* USAGE :
*
* @ example Log and Add to Message Handler : e107 :: getAdminLog () -> addSuccess ( " Successfully executed " ) -> save ( 'PREF_01' );
* @ example Log Only : e107 :: getAdminLog () -> addSuccess ( " Successfully executed " , false ) -> save ( 'PREF_01' );
* @ example Log Array Diff : e107 :: getAdminLog () -> addArray ( $array1 , $array2 ) -> save ( 'PREF_01' );
* @ example Log Array Diff and Add to Message Handler : e107 :: getAdminLog () -> addArray ( $array1 , $array2 , E_MESSAGE_ERROR ) -> save ( 'PREF_01' );
*
*/
if ( ! defined ( 'e107_INIT' ))
{
exit ;
}
define ( 'LOG_MESSAGE_NODISPLAY' , 'nodisplay' );
/**
* Admin logging class .
*
* @ package e107
* @ subpackage e107_handlers
* @ version $Id $ ;
* @ author e107steved
*/
class e_admin_log
{
/**
* Contains default class options , plus any that are overidden by the constructor
*
* @ var array
*/
protected $_options = array ( 'log_level' => 2 , 'backtrace' => false , );
protected $rldb = NULL ; // Database used by logging routine
protected $logFile = null ;
/**
* Log messages
* @ var array
*/
protected $_messages ;
protected $_allMessages ; // similar to $_messages except it is never flushed.
protected $_current_plugin = null ;
2020-12-18 09:39:02 -08:00
private $_roll_log_active = false ;
private $_roll_log_days = 0 ;
2019-03-29 19:13:32 -05:00
/**
* Constructor . Sets up constants and overwrites default options where set .
*
* @ param array $options
2020-03-06 13:57:33 -08:00
* @ return null
2019-03-29 19:13:32 -05:00
*/
public function __construct ( $options = array ())
{
if ( ! empty ( $options ))
{
foreach ( $options as $key => $val )
{
$this -> _options [ $key ] = $val ;
}
}
2020-12-18 09:39:02 -08:00
if ( ! defined ( 'E_LOG_INFORMATIVE' ))
{
define ( 'E_LOG_INFORMATIVE' , 0 ); // Minimal Log Level, including really minor stuff
define ( 'E_LOG_NOTICE' , 1 ); // More important than informative, but less important than notice
define ( 'E_LOG_WARNING' , 2 ); // Not anything serious, but important information
define ( 'E_LOG_FATAL' , 3 ); // An event so bad your site ceased execution.
define ( 'E_LOG_PLUGIN' , 4 ); // Plugin information
// Logging actions
define ( 'LOG_TO_ADMIN' , 1 );
define ( 'LOG_TO_AUDIT' , 2 );
define ( 'LOG_TO_ROLLING' , 4 );
2019-03-29 19:13:32 -05:00
2020-12-18 09:39:02 -08:00
// User audit logging (intentionally start at 10 - stick to 2 digits)
// The last two digits must match that for the corresponding log message
define ( 'USER_AUDIT_ADMIN' , 10 ); // User data changed by admin
define ( 'USER_AUDIT_SIGNUP' , 11 ); // User signed up
define ( 'USER_AUDIT_EMAILACK' , 12 ); // User responded to registration email
define ( 'USER_AUDIT_LOGIN' , 13 ); // User logged in
define ( 'USER_AUDIT_LOGOUT' , 14 ); // User logged out
define ( 'USER_AUDIT_NEW_DN' , 15 ); // User changed display name
define ( 'USER_AUDIT_NEW_PW' , 16 ); // User changed password
define ( 'USER_AUDIT_NEW_EML' , 17 ); // User changed email
define ( 'USER_AUDIT_PW_RES' , 18 ); // Password reset/resent activation email
define ( 'USER_AUDIT_NEW_SET' , 19 ); // User changed other settings
define ( 'USER_AUDIT_ADD_ADMIN' , 20 ); // User added by admin
define ( 'USER_AUDIT_MAIL_BOUNCE' , 21 ); // User mail bounce
define ( 'USER_AUDIT_BANNED' , 22 ); // User banned
define ( 'USER_AUDIT_BOUNCE_RESET' , 23 ); // User bounce reset
define ( 'USER_AUDIT_TEMP_ACCOUNT' , 24 ); // User temporary account
}
2019-03-29 19:13:32 -05:00
// Init E_MESSAGE_* constants if not already done
// e107::getMessage(); - just include, message handler is creating session in construct
// it breaks stuff (see class2 - language detection and comments)
require_once ( e_HANDLER . 'message_handler.php' );
$this -> _messages = array ();
$this -> _allMessages = array ();
2020-03-06 13:57:33 -08:00
2020-12-18 09:39:02 -08:00
$pref = e107 :: getPref ();
$this -> _roll_log_active = ( bool ) varset ( $pref [ 'roll_log_active' ]);
$this -> _roll_log_days = ( int ) varset ( $pref [ 'roll_log_days' ]);
2019-03-29 19:13:32 -05:00
}
/**
2020-12-18 09:39:02 -08:00
* @ deprecated
2019-03-29 19:13:32 -05:00
* BC Alias of add ();
*/
public function log_event ( $event_title , $event_detail , $event_type = E_LOG_INFORMATIVE , $event_code = '' )
{
return $this -> add ( $event_title , $event_detail , $event_type , $event_code );
}
/**
* Save all logs in the queue to the database and render any unhidden messages with the message handler .
* @ see alias flushMessages () method below .
* @ param string $logTitle - title for log entry eg . 'PREF_01'
* @ param int $logImportance [ optional ] default E_LOG_INFORMATIVE - passed directly to admin log
* @ param string $logEventCode [ optional ] - passed directly to admin log
* @ param string $mstack [ optional ] message stack passed to message handler
* @ param int LOG_TO_ADMIN | LOG_TO_ROLLING | LOG_TO_AUDIT
* @ return \e_admin_log
*/
public function save ( $logTitle , $logImportance = E_LOG_INFORMATIVE , $logEventCode = '' , $mstack = false , $target = LOG_TO_ADMIN )
{
return $this -> flushMessages ( $logTitle , $logImportance , $logEventCode , $mstack , $target );
}
/**
* Add and Save an event into the admin , rolling or user log .
* @ param string $event_title
* @ param mixed $event_details
* @ param integer $event_type [ optional ] Log level eg . E_LOG_INFORMATIVE , E_LOG_NOTICE , E_LOG_WARNING , E_LOG_FATAL
* @ param string $event_code [ optional ] - eg . 'BOUNCE'
* @ param integer $target [ optional ] LOG_TO_ADMIN , LOG_TO_AUDIT , LOG_TO_ROLLING
* @ param array $user - user to attribute the log to . array ( 'user_id' => 2 , 'user_name' => 'whoever' );
* @ return e_admin_log
*
* Alternative admin log entry point - compatible with legacy calls , and a bit simpler to use than the generic entry point .
* ( $eventcode has been added - give it a reference to identify the source module , such as 'NEWS_12' or 'ECAL_03' )
* We also log everything ( unlike 0.7 , where admin log and debug stuff were all mixed up together )
*
* For multi - lingual logging ( where the event title is shown in the language of the current user ), LAN defines may be used in the title
*
* For generic calls , leave $event_code as empty , and specify a constant string STRING_nn of less than 10 characters for the event title
* Typically the 'STRING' part of the name defines the area originating the log event , and the 'nn' is a numeric code
* This is stored as 'LAN_AL_STRING_NN' , and must be defined in a language file which is loaded during log display .
*
*/
public function add ( $event_title , $event_detail , $event_type = E_LOG_INFORMATIVE , $event_code = '' , $target = LOG_TO_ADMIN , $userData = null )
{
2020-12-18 09:39:02 -08:00
if ( empty ( $event_code ))
2019-03-29 19:13:32 -05:00
{
if ( strlen ( $event_title ) <= 12 )
{ // Assume the title is actually a reference to the event
$event_code = $event_title ;
$event_title = 'LAN_AL_' . $event_title ;
}
else
{
$event_code = 'ADMIN' ;
}
}
2020-03-06 13:57:33 -08:00
if ( ! is_array ( $event_detail ))
2019-03-29 19:13:32 -05:00
{
2020-12-18 09:39:02 -08:00
// auto-format long details -
$event_detail = str_replace ( " \n " , '[!br!]' , $event_detail );
2019-03-29 19:13:32 -05:00
}
if ( $this -> _options [ 'backtrace' ] == true )
{
$event_detail .= " \n \n " . debug_backtrace ( false );
}
2020-12-18 09:39:02 -08:00
$this -> addEvent ( $event_type , - 1 , $event_code , $event_title , $event_detail , FALSE , $target , $userData );
2019-03-29 19:13:32 -05:00
return $this ;
}
2019-06-08 10:56:14 -07:00
/**
2020-12-18 09:39:02 -08:00
* Enable / Disable the Rolling Log .
* @ param $bool
2019-06-08 10:56:14 -07:00
*/
2020-12-18 09:39:02 -08:00
public function rollingLog ( $bool )
2019-06-08 10:56:14 -07:00
{
2020-12-18 09:39:02 -08:00
$this -> _roll_log_active = ( bool ) $bool ;
2019-06-08 10:56:14 -07:00
}
2019-03-29 19:13:32 -05:00
/**
2020-12-18 09:39:02 -08:00
* Alias for deprecated e_log_event
* @ param int $importance - importance of event - 0. . 4 or so
* @ param mixed $source_call - either : string identifying calling file / routine
* or : a number 0. . 9 identifying info to log from debug_backtrace ()
2019-03-29 19:13:32 -05:00
* or : empty string , in which case first entry from debug_backtrace () logged
* or : an array , assumed to be from passing debug_backtrace () as a parameter , in which case relevant
* information is extracted and the argument list from the first entry logged
* or : - 1 , in which case no information logged
2020-12-18 09:39:02 -08:00
* @ param string $eventcode - abbreviation listing event type
* @ param string $event_title - title of event - pass standard 'LAN_ERROR_nn' defines to allow language translation
* @ param string $explain - detail of event
* @ param bool $finished - if TRUE , aborts execution
* @ param int $target_logs - table to save to : LOG_TO_ADMIN , LOG_TO_AUDIT , LOG_TO_ROLLING
* @ param null $userData - attribute user to log entry . array ( 'user_id' => 2 , 'user_name' => 'whatever' );
*
* @ return null
2019-03-29 19:13:32 -05:00
*/
2020-12-18 09:39:02 -08:00
public function addEvent ( $importance , $source_call , $eventcode = 'GEN' , $event_title = 'Untitled' , $explain = '' , $finished = FALSE , $target_logs = LOG_TO_AUDIT , $userData = null )
2019-03-29 19:13:32 -05:00
{
$e107 = e107 :: getInstance ();
$tp = e107 :: getParser ();
2020-12-18 09:39:02 -08:00
list ( $time_usec , $time_sec ) = explode ( ' ' , microtime ( FALSE )); // Log event time immediately to minimise uncertainty
2019-03-29 19:13:32 -05:00
$time_usec = $time_usec * 1000000 ;
2020-12-18 09:39:02 -08:00
if ( $this -> rldb === null ) // Better use our own db - don't know what else is going on
{
$this -> rldb = e107 :: getDb ( 'adminlog' );
}
2019-03-29 19:13:32 -05:00
if ( is_bool ( $target_logs ))
{ // Handle the legacy stuff for now - some old code used a boolean to select admin or rolling logs
$target_logs = $target_logs ? LOG_TO_ADMIN : LOG_TO_ROLLING ;
}
//---------------------------------------
// Calculations common to all logs
//---------------------------------------
$userid = deftrue ( 'USER' ) ? USERID : 0 ;
$userstring = deftrue ( 'USER' ) ? USERNAME : 'LAN_ANONYMOUS' ;
$userIP = e107 :: getIPHandler () -> getIP ( FALSE );
if ( ! empty ( $userData [ 'user_id' ]))
{
$userid = $userData [ 'user_id' ];
}
if ( ! empty ( $userData [ 'user_name' ]))
{
$userstring = $userData [ 'user_name' ];
}
if ( ! empty ( $userData [ 'user_ip' ]))
{
$userIP = $userData [ 'user_ip' ];
}
$importance = $tp -> toDB ( $importance , true , false , 'no_html' );
$eventcode = $tp -> toDB ( $eventcode , true , false , 'no_html' );
if ( is_array ( $explain ))
{
/*
$line = '' ;
$spacer = '' ;
foreach ( $explain as $k => $v )
{
$line .= $spacer . $k . '=>' . $v ;
$spacer = '[!br!]' ;
}
$explain = $line ;
unset ( $line );
*/
$explain = str_replace ( " \n " , '[!br!]' , print_r ( $explain , true ));
2020-12-18 09:39:02 -08:00
2019-03-29 19:13:32 -05:00
}
2020-12-18 09:39:02 -08:00
2019-03-29 19:13:32 -05:00
$explain = e107 :: getDb () -> escape ( $tp -> toDB ( $explain , true , false , 'no_html' ));
$event_title = $tp -> toDB ( $event_title , true , false , 'no_html' );
//---------------------------------------
// Admin Log
//---------------------------------------
if ( $target_logs & LOG_TO_ADMIN ) // Admin log - assume all fields valid
2020-12-18 09:39:02 -08:00
{
2019-03-29 19:13:32 -05:00
// $qry = " null, ".intval($time_sec).','.intval($time_usec).", '{$importance}', '{$eventcode}', {$userid}, '{$userIP}', '{$event_title}', '{$explain}' ";
2020-12-18 09:39:02 -08:00
2019-03-29 19:13:32 -05:00
$adminLogInsert = array (
'dblog_id' => null ,
'dblog_type' => $importance ,
'dblog_eventcode' => $eventcode ,
'dblog_datestamp' => time (),
2020-12-18 09:39:02 -08:00
'dblog_microtime' => ( int ) $time_usec ,
2019-03-29 19:13:32 -05:00
'dblog_user_id' => $userid ,
'dblog_ip' => $userIP ,
'dblog_title' => $event_title ,
'dblog_remarks' => $explain
);
2020-12-18 09:39:02 -08:00
$this -> rldb -> insert ( 'admin_log' , $adminLogInsert );
2019-03-29 19:13:32 -05:00
}
//---------------------------------------
// Audit Log
//---------------------------------------
// Add in audit log here
//---------------------------------------
// Rolling Log
//---------------------------------------
2020-12-18 09:39:02 -08:00
if (( $target_logs & LOG_TO_ROLLING ) && $this -> _roll_log_active )
2019-03-29 19:13:32 -05:00
{ // Rolling log
// Process source_call info
//---------------------------------------
if ( is_numeric ( $source_call ) && ( $source_call >= 0 ))
{
$back_count = 1 ;
$i = 0 ;
2020-12-18 09:39:02 -08:00
if (( $source_call == '' ))
2019-03-29 19:13:32 -05:00
{
$back_count = $source_call + 1 ;
$source_call = debug_backtrace ();
$i = 1 ; // Don't want to print the entry parameters to this function - we know all that!
}
}
if ( is_array ( $source_call ))
{ // Print the debug_backtrace() array
while ( $i < $back_count )
{
$source_call [ $i ][ 'file' ] = $e107 -> fix_windows_paths ( $source_call [ $i ][ 'file' ]); // Needed for Windoze hosts.
2020-12-18 09:39:02 -08:00
$source_call [ $i ][ 'file' ] = str_replace ( $e107 -> file_path , '' , $source_call [ $i ][ 'file' ]); // We really just want a e107 root-relative path. Strip out the root bit
$tmp = $source_call [ $i ][ 'file' ] . '|' . $source_call [ $i ][ 'class' ] . $source_call [ $i ][ 'type' ] . $source_call [ $i ][ 'function' ] . '@' . $source_call [ $i ][ 'line' ];
2019-03-29 19:13:32 -05:00
foreach ( $source_call [ $i ][ 'args' ] as $k => $v )
{ // Add in the arguments
2020-12-18 09:39:02 -08:00
$explain .= '[!br!]' . $k . '=' . $v ;
2019-03-29 19:13:32 -05:00
}
$i ++ ;
if ( $i < $back_count )
2020-12-18 09:39:02 -08:00
{
2019-03-29 19:13:32 -05:00
$explain .= " [!br!]------------------- " ;
2020-12-18 09:39:02 -08:00
}
2019-03-29 19:13:32 -05:00
if ( ! isset ( $tmp1 ))
2020-12-18 09:39:02 -08:00
{
$tmp1 = $tmp ;
} // Pick off the immediate caller as the source
}
if ( isset ( $tmp1 ))
{
$source_call = $tmp1 ;
}
else
{
$source_call = 'Root level' ;
2019-03-29 19:13:32 -05:00
}
}
else
{
$source_call = $e107 -> fix_windows_paths ( $source_call ); // Needed for Windoze hosts.
2020-12-18 09:39:02 -08:00
$source_call = str_replace ( $e107 -> file_path , '' , $source_call ); // We really just want a e107 root-relative path. Strip out the root bit
2019-03-29 19:13:32 -05:00
$source_call = $tp -> toDB ( $source_call , true , false , 'no_html' );
}
// else $source_call is a string
// Save new rolling log record
2020-12-18 09:39:02 -08:00
$insertArr = array (
'dblog_id' => 0 ,
'dblog_datestamp' => 0 ,
'dblog_microtime' => 0 ,
'dblog_type' => '' ,
'dblog_eventcode' => '' ,
'dblog_user_id' => '' ,
'dblog_user_name' => '' ,
'dblog_ip' => '' ,
'dblog_caller' => '' ,
'dblog_title' => '' ,
'dblog_remarks' => ''
);
$this -> rldb -> insert ( 'dblog' , '0, ' . intval ( $time_sec ) . ', ' . intval ( $time_usec ) . " , ' { $importance } ', ' { $eventcode } ', { $userid } , ' { $userstring } ', ' { $userIP } ', ' { $source_call } ', ' { $event_title } ', ' { $explain } ' " );
2019-03-29 19:13:32 -05:00
// Now delete any old stuff
2020-12-18 09:39:02 -08:00
if ( ! empty ( $this -> _roll_log_days ))
2019-03-29 19:13:32 -05:00
{
2020-12-18 09:39:02 -08:00
$this -> rldb -> delete ( 'dblog' , " dblog_datestamp < ' " . intval ( time () - ( $this -> _roll_log_days * 86400 )) . " ' " );
2019-03-29 19:13:32 -05:00
}
}
if ( $finished )
2020-12-18 09:39:02 -08:00
{
exit ;
} // Optional abort for all logs
2020-03-06 13:57:33 -08:00
return null ;
2020-12-18 09:39:02 -08:00
2019-03-29 19:13:32 -05:00
}
2020-12-18 09:39:02 -08:00
/**
* @ deprecated - use add () method instead or addEvent () as a direct replacement .
*/
public function e_log_event ( $importance , $source_call , $eventcode = 'GEN' , $event_title = 'Untitled' , $explain = '' , $finished = FALSE , $target_logs = LOG_TO_AUDIT , $userData = null )
{
return addEvent ( $importance , $source_call , $eventcode , $event_title , $explain , $finished , $target_logs , $userData );
}
2019-03-29 19:13:32 -05:00
public function setCurrentPlugin ( $plugdir )
{
$this -> _current_plugin = $plugdir ;
return $this ;
}
/**--------------------------------------
* USER AUDIT ENTRY
*--------------------------------------
* Log user - related events
2020-12-18 19:55:12 -08:00
*@ param string $event_type
* @ param int $event_code is a defined constant ( see above ) which specifies the event
* @ param array | string $event_data is an array of data fields whose keys and values are logged ( usually user data , but doesn ' t have to be - can add messages here )
2019-03-29 19:13:32 -05:00
* @ param int $id
* @ param string $u_name
2020-12-14 16:21:48 -08:00
* both $id and $u_name are left blank except for admin edits and user login , where they specify the id and login name of the 'target' user
2019-03-29 19:13:32 -05:00
*
* @ return bool
*/
function user_audit ( $event_type , $event_data , $id = '' , $u_name = '' )
{
2020-12-18 09:39:02 -08:00
list ( $time_usec , $time_sec ) = explode ( ' ' , microtime ()); // Log event time immediately to minimise uncertainty
2019-03-29 19:13:32 -05:00
$time_usec = $time_usec * 1000000 ;
if ( ! is_numeric ( $event_type ))
{
2020-12-18 09:39:02 -08:00
$title = 'User Audit Event-Type Failure: ' ;
2019-03-29 19:13:32 -05:00
$title .= ( string ) $event_type ;
$debug = debug_backtrace ( DEBUG_BACKTRACE_IGNORE_ARGS , 4 );
$debug [ 0 ] = e_REQUEST_URI ;
2020-12-18 09:39:02 -08:00
$this -> addEvent ( 4 , $debug [ 1 ][ 'file' ] . '|' . $debug [ 1 ][ 'function' ] . '@' . $debug [ 1 ][ 'line' ], 'USERAUDIT' , $title , $debug , FALSE );
2019-03-29 19:13:32 -05:00
return false ;
}
// See whether we should log this
$user_logging_opts = e107 :: getConfig () -> get ( 'user_audit_opts' );
if ( ! isset ( $user_logging_opts [ $event_type ])) // Finished if not set to log this event type
{
return false ;
}
if ( empty ( $event_data ))
{
$backt = debug_backtrace ( DEBUG_BACKTRACE_IGNORE_ARGS , 4 );
$event_data = $backt ;
}
if ( $this -> rldb == null )
{
$this -> rldb = e107 :: getDb ( 'rldb' ); // Better use our own db - don't know what else is going on
}
if ( ! empty ( $id ))
{
$userid = $id ;
}
else
{
$userid = ( USER === true ) ? USERID : 0 ;
}
if ( ! empty ( $u_name ))
{
$userstring = $u_name ;
}
else
{
2020-12-18 09:39:02 -08:00
$userstring = ( USER === true ? USERNAME : 'LAN_ANONYMOUS' );
2019-03-29 19:13:32 -05:00
}
$userIP = e107 :: getIPHandler () -> getIP ( false );
$eventcode = 'USER_' . $event_type ;
$title = 'LAN_AUDIT_LOG_0' . $event_type ; // This creates a string which will be displayed as a constant
$insertQry = array (
'dblog_id' => 0 ,
'dblog_datestamp' => intval ( $time_sec ),
'dblog_microtime' => intval ( $time_usec ),
'dblog_eventcode' => $eventcode ,
'dblog_user_id' => $userid ,
'dblog_user_name' => $userstring ,
'dblog_ip' => $userIP ,
'dblog_title' => $title ,
'dblog_remarks' => print_r ( $event_data , true ),
);
2020-12-18 09:39:02 -08:00
if ( $this -> rldb -> insert ( 'audit_log' , $insertQry ))
2019-03-29 19:13:32 -05:00
{
return true ;
}
return false ;
}
/* Legacy function probably not needed
function get_log_events ( $count = 15 , $offset )
{
global $sql ;
$count = intval ( $count );
return " Not implemented yet " ;
}
*/
/**
* Removes all events older than $days , or truncates the table if $days == false
*
* @ param integer | false $days
* @ return void
*/
public function purge_log_events ( $days )
{
global $sql ;
if ( $days == false )
{ // $days is false, so truncate the log table
2020-12-18 09:39:02 -08:00
$sql -> gen ( 'TRUNCATE TABLE #dblog ' );
2019-03-29 19:13:32 -05:00
}
else
{ // $days is set, so remove all entries older than that.
$days = intval ( $days );
$mintime = $days * 24 * 60 * 60 ;
$time = time () - $mintime ;
2020-12-18 09:39:02 -08:00
$sql -> delete ( 'dblog' , " WHERE `dblog_datestamp` < { $time } " , true );
2019-03-29 19:13:32 -05:00
}
}
//--------------------------------------
// HELPER ROUTINES
//--------------------------------------
/**
* Generic routine to log changes to an array . Only elements in $new are checked
*
* @ param array $new - most recent data being saved
* @ param array $old existing data - array is updated with changes , but not saved anywhere
* @ param string $event - LAN define or string used as title in log
*
* @ return bool true if changes found and logged , false otherwise .
*/
function logArrayDiffs ( $new , $old , $event , $logNow = true )
{
// $changes = array();
$changes = array_diff_recursive ( $new , $old );
if ( count ( $changes ))
{
if ( $logNow )
{
$this -> add ( $event , print_r ( $changes , true ), E_LOG_INFORMATIVE , '' );
}
else
{
$this -> logMessage ( $changes , LOG_MESSAGE_NODISPLAY , E_MESSAGE_INFO );
}
return TRUE ;
}
return FALSE ;
}
/**
* Logs an entry with all the data from an array , one field per line .
2020-12-17 05:52:54 -08:00
* @ deprecated Use e107 :: getLog () -> addArray ( $arrayData ) -> save ( $event );
2019-03-29 19:13:32 -05:00
* @ param string $event - LAN define or string used as title in log
* @ param array $target - data to be logged
* @ param string $extra - if non - empty , it goes on the first line .
* @ param array $niceNames - Normally data is logged in the format keyname => value , one per line .
* If the $niceName array exists and has a definition , the 'nice Name' is displayed instead of the key name
*
2020-03-06 13:57:33 -08:00
* @ return null
2019-03-29 19:13:32 -05:00
*/
public function logArrayAll ( $event , $target , $extra = '' , $niceNames = NULL )
{
if ( $extra == '' && $niceNames == null )
{
return $this -> add ( $event , $target , E_LOG_INFORMATIVE , '' ); // supports arrays
}
$logString = '' ;
if ( $extra )
{
$logString = $extra . '[!br!]' ;
}
$spacer = '' ;
$checkNice = ( $niceNames != NULL ) && is_array ( $niceNames );
foreach ( $target as $k => $v )
{
if ( $checkNice && isset ( $niceNames [ $k ][ 'niceName' ]))
{
$logString .= $spacer . $niceNames [ $k ][ 'niceName' ] . '=>' . $v ;
}
else
{
$logString .= $spacer . $k . '=>' . $v ;
}
$spacer = '[!br!]' ;
}
$this -> add ( $event , $logString , E_LOG_INFORMATIVE , '' );
2020-03-06 13:57:33 -08:00
return null ;
2019-03-29 19:13:32 -05:00
}
/**
* The next two routines accept and buffers messages which are destined for both admin log and message handler
*/
/**
* Add a message to the queue
*
* @ param string | array $text - the message text for logging / display
* @ param int $type - the 'importance' of the message . E_MESSAGE_SUCCESS | E_MESSAGE_ERROR | E_MESSAGE_INFO | E_MESSAGE_DEBUG | E_MESSAGE_NODISPLAY
* ( Values as used in message handler , apart from the last , which causes the message to not be passed to the message handler
* @ param boolean | int $logLevel - TRUE to give same importance as for message display . FALSE to not log .
* one of the values specified for $mesLevel to determine the prefix attached to the log message
* @ param boolean $session add session message
*
* @ return e_admin_log
*/
public function logMessage ( $text , $type = '' , $logLevel = TRUE , $session = FALSE )
{
if ( is_array ( $text ))
{
$text = print_r ( $text , true );
}
elseif ( empty ( $text ))
{
$bt = debug_backtrace ( true );
2020-12-18 09:39:02 -08:00
e107 :: getMessage () -> addDebug ( 'Log Message was empty: ' . print_a ( $bt [ 1 ], true ));
2019-03-29 19:13:32 -05:00
return $this ; // changing to text will break chained methods.
}
2020-12-18 09:39:02 -08:00
if ( ! $type )
{
$type = E_MESSAGE_INFO ;
}
if ( $logLevel === TRUE )
{
$logLevel = $type ;
}
2019-03-29 19:13:32 -05:00
$logArray = array ( 'message' => $text , 'dislevel' => $type , 'loglevel' => $logLevel , 'session' => $session , 'time' => time ());
$this -> _messages [] = $logArray ;
$this -> _allMessages [] = $logArray ;
return $this ;
}
/**
* @ DEPRECATED
* BC Alias for addSuccess ();
*/
public function logSuccess ( $text , $message = true , $session = false )
{
return $this -> addSuccess ( $text , $message , $session );
}
/**
* @ DEPRECATED
* BC Alias for addError ();
*/
public function logError ( $text , $message = true , $session = false )
{
return $this -> addError ( $text , $message , $session );
}
/**
* Add a success message to the log queue
*
* @ param string | array $text
* @ param boolean $message if true - register with eMessage handler
* @ param boolean $session add session message
* @ return e_admin_log
*/
public function addSuccess ( $text , $message = true , $session = false )
{
return $this -> logMessage ( $text , ( $message ? E_MESSAGE_SUCCESS : LOG_MESSAGE_NODISPLAY ), E_MESSAGE_SUCCESS , $session );
}
/**
* Add an error message to the log queue
*
* @ param string $text
* @ param boolean $message if true ( default ) - register with eMessage handler , set to false to hide .
* @ param boolean $session add session message
* @ return e_admin_log
*/
public function addError ( $text , $message = true , $session = false )
{
return $this -> logMessage ( $text , ( $message ? E_MESSAGE_ERROR : LOG_MESSAGE_NODISPLAY ), E_MESSAGE_ERROR , $session );
}
/**
* Add an Debug message to the log queue
*
* @ param string $text
* @ param boolean $message if true ( default ) - register with eMessage handler , set to false to hide .
* @ param boolean $session add session message
* @ return e_admin_log
*/
public function addDebug ( $text , $message = true , $session = false )
{
return $this -> logMessage ( $text , ( $message ? E_MESSAGE_DEBUG : LOG_MESSAGE_NODISPLAY ), E_MESSAGE_DEBUG , $session );
}
/**
* Add an Warning message to the log queue
*
* @ param string $text
* @ param boolean $message if true ( default ) - register with eMessage handler , set to false to hide .
* @ param boolean $session add session message
* @ return e_admin_log
*/
public function addWarning ( $text , $message = true , $session = false )
{
return $this -> logMessage ( $text , ( $message ? E_MESSAGE_WARNING : LOG_MESSAGE_NODISPLAY ), E_MESSAGE_WARNING , $session );
}
/**
* Add an array to the log queue
* @ param $array
* @ param $oldArray ( optional ) - when included , only the changes between the arrays is saved .
* @ param $type ( optional ) default : LOG_MESSAGE_NODISPLAY . or E_MESSAGE_WARNING , E_MESSAGE_DEBUG , E_MESSAGE_SUCCESS
*/
public function addArray ( $array , $oldArray = null , $type = LOG_MESSAGE_NODISPLAY , $session = false )
{
if ( is_array ( $oldArray ))
{
$text = array_diff_recursive ( $array , $oldArray ); // Located in core_functions.php
if ( count ( $text ) < 1 )
{
2020-12-18 09:39:02 -08:00
$text = 'No differences found' ;
2019-03-29 19:13:32 -05:00
}
}
else
{
$text = $array ;
}
return $this -> logMessage ( $text , $type , $type , $session );
}
2020-12-18 09:39:02 -08:00
/**
* Return the last row added to the log table .
* @ param int $type
* @ return array | string
*/
public function getLastLog ( $type = LOG_TO_ADMIN )
{
switch ( $type )
{
case LOG_TO_AUDIT :
$table = 'audit_log' ;
break ;
case LOG_TO_ROLLING :
$table = 'dblog' ;
break ;
case LOG_TO_ADMIN :
default :
$table = 'admin_log' ;
}
$query = 'SELECT * FROM #' . $table . ' ORDER BY dblog_id DESC LIMIT 1' ;
return e107 :: getDb () -> retrieve ( $query );
}
2019-03-29 19:13:32 -05:00
/**
* Empty the messages - pass to both admin log and message handler
*
* @ param string $logTitle - title for log entry
* @ param int $logImportance - passed directly to admin log
* @ param string $logEventCode - passed directly to admin log
* @ param string $mstack [ optional ] message stack passed to message handler
* @ return e_admin_log
*/
public function flushMessages ( $logTitle , $logImportance = E_LOG_INFORMATIVE , $logEventCode = '' , $mstack = false , $target = LOG_TO_ADMIN )
{
$mes = e107 :: getMessage ();
$resultTypes = array ( E_MESSAGE_SUCCESS => 'Success' , E_MESSAGE_ERROR => 'Fail' ); // Add LANS here. Could add other codes
$separator = '' ;
$logString = '' ;
foreach ( $this -> _messages as $m )
{
if ( $m [ 'loglevel' ] !== FALSE )
{
$logString .= $separator ;
if ( $m [ 'loglevel' ] == LOG_MESSAGE_NODISPLAY ) { $logString .= ' ' ; } // Indent supplementary messages
// Not sure about next line - might want to log the <br /> as text, rather than it forcing a newline
$logString .= strip_tags ( str_replace ( array ( '<br>' , '<br/>' , '<br />' ), '[!br!]' , $m [ 'message' ]));
if ( isset ( $resultTypes [ $m [ 'loglevel' ]]))
{
$logString .= ' - ' . $resultTypes [ $m [ 'loglevel' ]];
}
$separator = '[!br!]' ;
}
if ( $m [ 'dislevel' ] != LOG_MESSAGE_NODISPLAY )
{
if ( $mstack )
{
$mes -> addStack ( $m [ 'message' ], $mstack , $m [ 'dislevel' ], $m [ 'session' ]);
// move to main stack OUTSIDE if needed
}
2020-12-18 09:39:02 -08:00
else
{
$mes -> add ( $m [ 'message' ], $m [ 'dislevel' ], $m [ 'session' ]);
}
2019-03-29 19:13:32 -05:00
}
}
$this -> add ( $logTitle , $logString , $logImportance , $logEventCode , $target );
$this -> _messages = array (); // Clear the memory for reuse
return $this ;
}
/**
* Clear all messages in 'memory' .
*/
public function clear ()
{
$this -> _messages = array ();
return $this ;
}
/**
* Save Message stack to File .
*/
private function saveToFile ( $logTitle = '' , $append = false , $opts = array ())
{
if ( $this -> logFile == null )
{
2020-03-06 13:57:33 -08:00
return null ;
2019-03-29 19:13:32 -05:00
}
if ( count ( $this -> _allMessages ))
{
2020-12-18 09:39:02 -08:00
$head = ' e107 CMS Log file : ' . $logTitle . ' ' . date ( 'Y-m-d_H-i-s' ) . " \n " ;
2019-03-29 19:13:32 -05:00
$head .= " ------------------------------------------------------------------------------------------- \n \n " ;
}
else
{
2020-03-06 13:57:33 -08:00
return null ;
2019-03-29 19:13:32 -05:00
}
$text = '' ;
foreach ( $this -> _allMessages as $m )
{
2020-12-18 09:39:02 -08:00
$text .= date ( 'Y-m-d H:i:s' , $m [ 'time' ]) . " \t " . str_pad ( $m [ 'loglevel' ], 10 , ' ' , STR_PAD_RIGHT ) . " \t " . strip_tags ( $m [ 'message' ]) . " \n " ;
2019-03-29 19:13:32 -05:00
}
$date = ( $append == true ) ? date ( 'Y-m-d' ) : date ( 'Y-m-d_H-i-s' ) . '_' . crc32 ( $text );
$dir = e_LOG ;
if ( empty ( $this -> _current_plugin ))
{
$this -> _current_plugin = deftrue ( 'e_CURRENT_PLUGIN' );
}
if ( ! empty ( $this -> _current_plugin )) // If it's a plugin, create a subfolder.
{
2020-12-18 09:39:02 -08:00
$dir = e_LOG . $this -> _current_plugin . '/' ;
2019-03-29 19:13:32 -05:00
if ( ! is_dir ( $dir ))
{
2020-12-18 09:39:02 -08:00
if ( ! mkdir ( $dir , 0755 ) && ! is_dir ( $dir ))
{
$this -> add ( 'Directory creation Failed' , sprintf ( 'Directory "%s" was not created' , $dir ));
}
2019-03-29 19:13:32 -05:00
}
}
2020-12-18 09:39:02 -08:00
$fileName = $dir . $date . '_' . $this -> logFile . '.log' ;
2019-03-29 19:13:32 -05:00
if ( ! empty ( $opts [ 'filename' ]))
{
$fileName = $dir . basename ( $opts [ 'filename' ]);
}
if ( $append == true )
{
$app = FILE_APPEND ;
if ( ! file_exists ( $fileName ))
{
$text = $head . $text ;
}
}
else
{
$app = null ;
$text = $head . $text ;
}
2020-12-18 09:39:02 -08:00
if ( file_put_contents ( $fileName , $text , $app ))
2019-03-29 19:13:32 -05:00
{
$this -> _allMessages = array ();
$this -> _current_plugin = null ;
return $this -> logFile ;
}
2020-12-18 09:39:02 -08:00
if ( E107_DEBUG_LEVEL > 0 && getperms ( '0' ))
2019-03-29 19:13:32 -05:00
{
e107 :: getMessage () -> addDebug ( " Couldn't Save to Log File: " . $fileName );
2020-12-18 09:39:02 -08:00
}
2019-03-29 19:13:32 -05:00
$this -> _current_plugin = null ;
return false ;
}
/**
* Set and save accumulated log to a file .
* Use addDebug (), addError () or addSuccess () prior to executing .
* @ param string name without the extension . ( ie . date prefix and . log suffix will be added automatically )
* @ param string Title for use inside the Log file
* @ param boolean true = append to file , false = new file each save .
*/
public function toFile ( $name , $logTitle = '' , $append = false , $opts = array ())
{
$this -> logFile = $name ;
$file = $this -> saveToFile ( $logTitle , $append , $opts );
$this -> logFile = null ;
return $file ;
}
}