From 3aada9949d51024a92a8b5c6cb70d12f9c3cac16 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sun, 21 Dec 2025 19:59:48 +0000
Subject: [PATCH] =auth refactored via rest, referral system set up for Jane, some javascript consolidation
---
inc/managers/ErrorHandler.php | 190 ++++++++++++++++++++++++++++++++++-------------
1 files changed, 137 insertions(+), 53 deletions(-)
diff --git a/inc/managers/ErrorHandler.php b/inc/managers/ErrorHandler.php
index add4eda..166229e 100644
--- a/inc/managers/ErrorHandler.php
+++ b/inc/managers/ErrorHandler.php
@@ -186,33 +186,61 @@
*
* @return bool Whether it gets logged successfully
*/
- public function log(string $component, string $message, array $context = [], string $severity = 'error'):bool
- {
- try {
- // Normal queue-based logging
- JVB()->queue()->queueOperation(
- 'error_log',
- get_current_user_id(),
- [
- 'component' => $component,
- 'message' => $message,
- 'context' => $context,
- 'severity' => $severity
- ],
- ['priority' => 'high']
- );
+ public function log(string $component, string $message, array $context = [], string $severity = 'error'): array
+ {
+ try {
+ $table = $this->wpdb->prefix . BASE . 'error_log';
+ // Validate severity
+ if (!array_key_exists($severity, $this->error_levels)) {
+ $severity = 'error';
+ }
- // Immediate notification for critical errors
- if ($severity === 'critical') {
- $this->notifyAdmin($component, $message, $context);
- }
- return true;
- } catch (Exception $e) {
- error_log("[edmonton.ink Error] Failed to log error: " . $e->getMessage());
- return false;
- }
- }
+ // Extract info
+ $error_type = sanitize_text_field($context['error_type'] ?? $component);
+ $method = isset($context['method']) ? sanitize_text_field($context['method']) : null;
+ $page_url = isset($context['url']) ? esc_url_raw($context['url']) : null;
+ $user_id = get_current_user_id();
+ $user_was_logged_in = $user_id > 0 || (!empty($context['isLoggedIn']));
+
+ // Determine source from context
+ $source = isset($context['source']) ? $context['source'] :
+ (isset($context['url']) ? 'frontend' : 'backend');
+
+ $result = $this->wpdb->insert(
+ $table,
+ [
+ 'error_type' => $error_type,
+ 'component' => $component,
+ 'method' => $method,
+ 'page_url' => $page_url,
+ 'message' => sanitize_textarea_field($message),
+ 'context' => json_encode($context),
+ 'severity' => $severity,
+ 'user_id' => $user_id ?: null,
+ 'user_was_logged_in' => $user_was_logged_in ? 1 : 0,
+ 'source' => $source,
+ 'created_at' => current_time('mysql')
+ ],
+ ['%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%d', '%s', '%s']
+ );
+
+ if ($result === false) {
+ error_log("[ErrorHandler] Database insert failed: " . $this->wpdb->last_error);
+ return ['success' => false, 'message' => $this->wpdb->last_error];
+ }
+
+ if ($severity === 'critical') {
+ $this->checkErrorThreshold($error_type, $component);
+ }
+
+ return ['success' => true, 'id' => $this->wpdb->insert_id];
+
+ } catch (Exception $e) {
+ error_log("[ErrorHandler Exception] " . $e->getMessage());
+ return ['success' => false, 'message' => $e->getMessage()];
+ }
+ }
/**
* @param string $component What class or function logs the error
@@ -227,42 +255,96 @@
$subject = "[edmonton.ink Critical Error] {$component}";
$body = "Error: {$message}\n\nContext: " . print_r($context, true);
- return jvbMail($admin_email, $subject, $body);
+ return JVB()->email()->sendEmail($admin_email, $subject, $body);
}
/**
* Gather summary of the most important errors
+ * @param ?string $start_date Defaults to today
+ * @param ?string $end_date Defaults to today
* @return array
*/
- protected function gatherErrorSummary():array
- {
- $yesterday = date('Y-m-d H:i:s', strtotime('-24 hours'));
+ public function gatherErrorSummary(?string $start_date = null, ?string $end_date = null): array
+ {
+ $table = $this->wpdb->prefix . BASE . 'error_log';
- // Get most frequent errors
- $frequent_errors = $this->wpdb->get_results($this->wpdb->prepare(
- "SELECT error_type, component, message, COUNT(*) as count
- FROM {$this->tableName}
- WHERE created_at > %s
- GROUP BY error_type, component, message
- ORDER BY count DESC
- LIMIT 20",
- $yesterday
- ));
+ if (!$start_date) {
+ $start_date = gmdate('Y-m-d 00:00:00', strtotime('-1 day'));
+ }
+ if (!$end_date) {
+ $end_date = gmdate('Y-m-d 23:59:59');
+ }
- // Get most recent critical errors
- $critical_errors = $this->wpdb->get_results($this->wpdb->prepare(
- "SELECT * FROM {$this->tableName}
- WHERE severity = 'critical' AND created_at > %s
- ORDER BY created_at DESC
- LIMIT 5",
- $yesterday
- ));
+ // Most frequent error patterns (deduplicated by component/method/message)
+ $frequent = $this->wpdb->get_results($this->wpdb->prepare(
+ "SELECT
+ component,
+ method,
+ error_type,
+ message,
+ severity,
+ source,
+ COUNT(*) as count,
+ SUM(CASE WHEN user_was_logged_in = 1 THEN 1 ELSE 0 END) as logged_in_count,
+ SUM(CASE WHEN user_was_logged_in = 0 THEN 1 ELSE 0 END) as logged_out_count,
+ MIN(created_at) as first_seen,
+ MAX(created_at) as last_seen
+ FROM {$table}
+ WHERE created_at BETWEEN %s AND %s
+ GROUP BY component, method, error_type, message, severity, source
+ ORDER BY count DESC, severity DESC
+ LIMIT 10",
+ $start_date,
+ $end_date
+ ));
- return [
- 'frequent' => $frequent_errors,
- 'critical' => $critical_errors
- ];
- }
+ // Critical errors
+ $critical = $this->wpdb->get_results($this->wpdb->prepare(
+ "SELECT
+ component,
+ method,
+ error_type,
+ message,
+ source,
+ COUNT(*) as count,
+ SUM(CASE WHEN user_was_logged_in = 1 THEN 1 ELSE 0 END) as logged_in_count,
+ SUM(CASE WHEN user_was_logged_in = 0 THEN 1 ELSE 0 END) as logged_out_count,
+ MIN(created_at) as first_seen,
+ MAX(created_at) as last_seen
+ FROM {$table}
+ WHERE created_at BETWEEN %s AND %s AND severity = 'critical'
+ GROUP BY component, method, error_type, message, source
+ ORDER BY count DESC
+ LIMIT 5",
+ $start_date,
+ $end_date
+ ));
+
+ // Overall stats
+ $stats = $this->wpdb->get_row($this->wpdb->prepare(
+ "SELECT
+ COUNT(*) as total_errors,
+ COUNT(DISTINCT CONCAT(component, '-', COALESCE(method, ''), '-', error_type)) as unique_error_types,
+ SUM(CASE WHEN user_was_logged_in = 1 THEN 1 ELSE 0 END) as logged_in_errors,
+ SUM(CASE WHEN user_was_logged_in = 0 THEN 1 ELSE 0 END) as logged_out_errors,
+ SUM(CASE WHEN source = 'frontend' THEN 1 ELSE 0 END) as frontend_errors,
+ SUM(CASE WHEN source = 'backend' THEN 1 ELSE 0 END) as backend_errors,
+ SUM(CASE WHEN severity = 'critical' THEN 1 ELSE 0 END) as critical_count,
+ SUM(CASE WHEN severity = 'error' THEN 1 ELSE 0 END) as error_count,
+ SUM(CASE WHEN severity = 'warning' THEN 1 ELSE 0 END) as warning_count
+ FROM {$table}
+ WHERE created_at BETWEEN %s AND %s",
+ $start_date,
+ $end_date
+ ));
+
+ return [
+ 'frequent' => $frequent,
+ 'critical' => $critical,
+ 'stats' => $stats,
+ 'date_range' => ['start' => $start_date, 'end' => $end_date]
+ ];
+ }
/**
* Send daily error summary email to administrator
@@ -330,7 +412,7 @@
$body .= "View detailed error logs in the dashboard: {$admin_url}\n\n";
// Send the email
- $sent = jvbMail($admin_email, $subject, $body, 'ERROR SUMMARY');
+ $sent = JVB()->email()->sendEmail($admin_email, $subject, $body, 'ERROR SUMMARY');
// Log that summary was sent
if ($sent) {
@@ -426,6 +508,8 @@
}
+
+
protected function buildParams(WP_REST_Request $request):array {
$allowedSeverity = [
'all',
--
Gitblit v1.10.0