<?php
if (!defined('WP_WIZIAPP_BASE'))
exit();
/**
* Basic log class for the wordpress plugin
*
* This log class can help us trace runtime information,
* from debugging to errors this class supports erros, debug, info, and all
* usually all logging will be disabled, but in case the problem comes knocking
* on our doors we can enable the Log and see whats up in every step of the way.
*
* @package WiziappWordpressPlugin
* @subpackage Utils
* @author comobix.com plugins@comobix.com
*
* @todo Add log files rotation managment
*/
class WiziappLog {
/**
* The desired logging level
*
* @var integer
*/
var $threshold = 4;
/**
* Is the log enabled?
*
* @var boolean
*/
var $enabled = WP_WIZIAPP_DEBUG;
/**
* The log levels
*
* @var array
*/
var $levels = array('ERROR' => '1', 'WARNING' => 2, 'DEBUG' => '2', 'INFO' => '3', 'ALL' => '4');
/**
* The file maximum size in bytes
*
* @var integer
*
*/
var $max_size = 1048576; // 1MB
/**
* @var integer
*
*/
var $max_days = 10;
var $path = '';
public function __construct(){
$this->path = dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR;
if ( !$this->checkPath() ){
$this->enabled = FALSE;
}
}
public function checkPath(){
return is_writable($this->path);
}
/**
* Checks the file size, if file to big starts new one .
*/
private function toLarge($filepath){
if (!file_exists($filepath)){
return false;
}
if(filesize($filepath) > $this->max_size){
return true;
}else{
return false;
}
}
/**
* @todo Change this method to put the old file as .X and not the new, save the scanning of all the log files
* when adding a new message
*
*/
private function getFilePath(){
$filepath = $this->path . 'wiziapplog-' . date('Y-m-d') . '.log.php';
if(filesize($filepath) > $this->max_size){
$file_indx = 1;
$new_filepath = $this->path.'wiziapplog-' . date('Y-m-d') . '.log' . $file_indx . '.php';
while ($this->toLarge($new_filepath)){
$file_indx++;
$new_filepath = $this->path . 'wiziapplog-' . date('Y-m-d') . '.log' . $file_indx . '.php';
}
return $new_filepath;
}else{
return $filepath;
}
}
private function deleteOldFiles() {
$oldest_date = mktime(0, 0, 0, date('m'), date('d') - $this->max_days, date('Y'));
$dirHandle = opendir($this->path);
while($file = readdir($dirHandle)){
$fileinfo = pathinfo($file);
$basename = $fileinfo['basename'];
if(preg_match("/^wiziapplog-/", $basename)){
$date = strtotime(substr($basename, 11, 10));
if($date <= $oldest_date){
@unlink($this->path . $fileinfo['basename'] );
}
}
}
}
/**
* writes a log message to the log file
*
* The messages sent to this method will be filtered according to their level
* if the level meets the trashold and the logging is enabled the message
* will be written to a log file. The method also receives the component
* related to this log message to ease the reading of the log file itself
* If you want to keep your sanity make sure to send this "optional" parameter
*
* @param string $level The log message level
* @param string $msg The log message
* @param string $component The component related to this message
*/
function write($level = 'error', $msg, $component='') {
ob_start();
clearstatcache(); // We need to clear the cache of the filesize function so that the size checks will work
if ($this->enabled === FALSE){
ob_end_clean();
return FALSE;
}
$this->deleteOldFiles();
// Don't trust the user to use the right case, switch to upper
$level = strtoupper($level);
// If the wanted level is above the trashold nothing to do
if (!isset($this->levels[$level]) || ($this->levels[$level] > $this->threshold)){
ob_end_clean();
return FALSE;
}
// $filepath = dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'logs'.DIRECTORY_SEPARATOR.'wiziapplog-'.date('Y-m-d').'.log.php';
$filepath = $this->getFilePath();
$message = '';
// Prevent direct access to the log, to avoid security issues
if (!file_exists($filepath)){
$message .= "<?php if (!defined('WP_WIZIAPP_BASE')) exit(); ?" . ">\n\n";
$message .= print_r($this->writeServerConfiguration(), TRUE);
$message .= '==================================================================\n\n\n\n\n';
}
// If we can't open the file for appending there isn't much we can do
if (!$fp = @fopen($filepath, 'ab')){
ob_end_clean();
return FALSE;
}
$date = date('Y-m-d H:i:s');
$message .= "[$level][{$date}][$component]$msg\n";
flock($fp, LOCK_EX);
fwrite($fp, $message);
flock($fp, LOCK_UN);
fclose($fp);
@chmod($filepath, 0666);
ob_end_clean();
return TRUE;
}
function writeServerConfiguration(){
global $wpdb;
// mysql version
$sqlversion = $wpdb->get_var("SELECT VERSION() AS version");
// sql mode
$mysqlinfo = $wpdb->get_results("SHOW VARIABLES LIKE 'sql_mode'");
if (is_array($mysqlinfo)){
$sql_mode = $mysqlinfo[0]->Value;
}
if (empty($sql_mode)) {
$sql_mode = 'Not Set';
}
$config = array(
'php_os' => PHP_OS,
'sql version' => $sqlversion,
'sql mode' => $sql_mode,
'safe_mode' => ini_get('safe_mode'),
'output buffer size' => ini_get('pcre.backtrack_limit') ? ini_get('pcre.backtrack_limit') : 'NA',
'post_max_size' => ini_get('post_max_size') ? ini_get('post_max_size') : 'NA',
'max_execution_time' => ini_get('max_execution_time') ? ini_get('max_execution_time') : 'NA',
'memory_limit' => ini_get('memory_limit') ? ini_get('memory_limit') : 'NA',
'memory_get_usage' => function_exists('memory_get_usage') ? round(memory_get_usage() / 1024 / 1024, 2).'MByte' : 'NA',
'server config' => $_SERVER,
'display_errors' => ini_get('display_error'),
'error_reporting' => ini_get('error_reporting'),
);
return $config;
}
}
/**
* One logger to rule them all...
* @global WiziappLogm $GLOBALS['WiziappLog']
*/
if (!isset($GLOBALS['WiziappLog'])) {
// Initate the Wiziapp Loggin Object
$GLOBALS['WiziappLog'] = new WiziappLog() ;
}