Files
Instagram-Gallery-Sync-Pro/includes/class-logger.php

332 lines
8.3 KiB
PHP

<?php
/**
* Logger Class
*
* Handles logging of plugin events, errors, and debugging information.
*
* @package Instagram_Gallery_Sync_Pro
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
/**
* Class IGSP_Logger
*/
class IGSP_Logger
{
/**
* Log types
*/
const TYPE_SUCCESS = 'success';
const TYPE_ERROR = 'error';
const TYPE_WARNING = 'warning';
const TYPE_INFO = 'info';
/**
* Maximum log entries to keep
*
* @var int
*/
private $max_entries = 500;
/**
* Constructor
*/
public function __construct()
{
// Schedule log cleanup
add_action('igsp_cleanup_logs', array($this, 'cleanup_old_logs'));
}
/**
* Add a log entry
*
* @param string $type Log type (success, error, warning, info)
* @param string $message Log message
* @param array $details Additional details (optional)
* @return int|false Insert ID or false
*/
public function log($type, $message, $details = array())
{
global $wpdb;
// Validate type
$valid_types = array(self::TYPE_SUCCESS, self::TYPE_ERROR, self::TYPE_WARNING, self::TYPE_INFO);
if (!in_array($type, $valid_types, true)) {
$type = self::TYPE_INFO;
}
// Only log in debug mode unless it's an error
$debug_mode = get_option('igsp_debug_mode', 'no');
if ($debug_mode !== 'yes' && $type !== self::TYPE_ERROR) {
return false;
}
$result = $wpdb->insert(
IGSP_TABLE_LOG,
array(
'log_type' => $type,
'message' => sanitize_text_field($message),
'details' => !empty($details) ? wp_json_encode($details) : null,
'created_at' => current_time('mysql'),
),
array('%s', '%s', '%s', '%s')
);
// Also log to error_log if debug is enabled
if (defined('WP_DEBUG') && WP_DEBUG) {
error_log(sprintf(
'[IGSP %s] %s %s',
strtoupper($type),
$message,
!empty($details) ? wp_json_encode($details) : ''
));
}
return $result ? $wpdb->insert_id : false;
}
/**
* Log success
*
* @param string $message Message
* @param array $details Details
* @return int|false
*/
public function success($message, $details = array())
{
return $this->log(self::TYPE_SUCCESS, $message, $details);
}
/**
* Log error
*
* @param string $message Message
* @param array $details Details
* @return int|false
*/
public function error($message, $details = array())
{
return $this->log(self::TYPE_ERROR, $message, $details);
}
/**
* Log warning
*
* @param string $message Message
* @param array $details Details
* @return int|false
*/
public function warning($message, $details = array())
{
return $this->log(self::TYPE_WARNING, $message, $details);
}
/**
* Log info
*
* @param string $message Message
* @param array $details Details
* @return int|false
*/
public function info($message, $details = array())
{
return $this->log(self::TYPE_INFO, $message, $details);
}
/**
* Get log entries
*
* @param array $args Query arguments
* @return array
*/
public function get_logs($args = array())
{
global $wpdb;
$defaults = array(
'limit' => 50,
'offset' => 0,
'type' => '',
'search' => '',
);
$args = wp_parse_args($args, $defaults);
$where = array('1=1');
$values = array();
if (!empty($args['type'])) {
$where[] = 'log_type = %s';
$values[] = $args['type'];
}
if (!empty($args['search'])) {
$where[] = 'message LIKE %s';
$values[] = '%' . $wpdb->esc_like($args['search']) . '%';
}
$where_clause = implode(' AND ', $where);
$query = "SELECT * FROM " . IGSP_TABLE_LOG . "
WHERE {$where_clause}
ORDER BY created_at DESC
LIMIT %d OFFSET %d";
$values[] = $args['limit'];
$values[] = $args['offset'];
return $wpdb->get_results(
$wpdb->prepare($query, $values)
);
}
/**
* Count log entries
*
* @param string $type Optional log type filter
* @return int
*/
public function count_logs($type = '')
{
global $wpdb;
if (!empty($type)) {
return (int) $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT(*) FROM " . IGSP_TABLE_LOG . " WHERE log_type = %s",
$type
)
);
}
return (int) $wpdb->get_var(
"SELECT COUNT(*) FROM " . IGSP_TABLE_LOG
);
}
/**
* Clear all logs
*
* @return bool
*/
public function clear_logs()
{
global $wpdb;
return $wpdb->query("TRUNCATE TABLE " . IGSP_TABLE_LOG) !== false;
}
/**
* Cleanup old log entries
*
* @return int Number of deleted entries
*/
public function cleanup_old_logs()
{
global $wpdb;
// Keep only the most recent entries
return $wpdb->query(
$wpdb->prepare(
"DELETE FROM " . IGSP_TABLE_LOG . "
WHERE id NOT IN (
SELECT id FROM (
SELECT id FROM " . IGSP_TABLE_LOG . "
ORDER BY created_at DESC
LIMIT %d
) AS t
)",
$this->max_entries
)
);
}
/**
* Delete logs older than X days
*
* @param int $days Days to keep
* @return int
*/
public function delete_logs_older_than($days)
{
global $wpdb;
$date_threshold = date('Y-m-d H:i:s', strtotime("-{$days} days"));
return $wpdb->query(
$wpdb->prepare(
"DELETE FROM " . IGSP_TABLE_LOG . " WHERE created_at < %s",
$date_threshold
)
);
}
/**
* Get logs formatted for display
*
* @param int $limit Number of entries
* @return array
*/
public function get_formatted_logs($limit = 50)
{
$logs = $this->get_logs(array('limit' => $limit));
$formatted = array();
foreach ($logs as $log) {
$formatted[] = array(
'id' => $log->id,
'type' => $log->log_type,
'type_label' => $this->get_type_label($log->log_type),
'type_class' => $this->get_type_class($log->log_type),
'message' => $log->message,
'details' => !empty($log->details) ? json_decode($log->details, true) : array(),
'date' => mysql2date(get_option('date_format') . ' ' . get_option('time_format'), $log->created_at),
'relative' => human_time_diff(strtotime($log->created_at), current_time('timestamp')) . ' ' . __('ago', 'instagram-gallery-sync-pro'),
);
}
return $formatted;
}
/**
* Get type label
*
* @param string $type Log type
* @return string
*/
private function get_type_label($type)
{
$labels = array(
self::TYPE_SUCCESS => __('Success', 'instagram-gallery-sync-pro'),
self::TYPE_ERROR => __('Error', 'instagram-gallery-sync-pro'),
self::TYPE_WARNING => __('Warning', 'instagram-gallery-sync-pro'),
self::TYPE_INFO => __('Info', 'instagram-gallery-sync-pro'),
);
return isset($labels[$type]) ? $labels[$type] : $type;
}
/**
* Get type CSS class
*
* @param string $type Log type
* @return string
*/
private function get_type_class($type)
{
$classes = array(
self::TYPE_SUCCESS => 'igsp-log-success',
self::TYPE_ERROR => 'igsp-log-error',
self::TYPE_WARNING => 'igsp-log-warning',
self::TYPE_INFO => 'igsp-log-info',
);
return isset($classes[$type]) ? $classes[$type] : 'igsp-log-info';
}
}