From d38d825e3484d822ea3c1f0fb1df37ecf386b18a Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sun, 04 Jan 2026 19:54:16 +0000
Subject: [PATCH] =TaxonomyCreator.js debugging

---
 inc/managers/ErrorHandler.php |  350 ++++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 232 insertions(+), 118 deletions(-)

diff --git a/inc/managers/ErrorHandler.php b/inc/managers/ErrorHandler.php
index add4eda..9e6cc9a 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
@@ -221,126 +249,210 @@
      *
      * @return bool Whether the notification is sent successfully
      */
-    protected function notifyAdmin(string $component, string $message, array $context):bool
-    {
-        $admin_email = get_option('admin_email');
-        $subject = "[edmonton.ink Critical Error] {$component}";
-        $body = "Error: {$message}\n\nContext: " . print_r($context, true);
+	protected function notifyAdmin(string $component, string $message, array $context):bool
+	{
+		$admin_email = get_option('admin_email');
+		$subject = "[" . get_bloginfo('name') . " Critical Error] {$component}";
 
-        return jvbMail($admin_email, $subject, $body);
-    }
+		$body = JVB()->email()->alert(
+			'A critical error has occurred and requires immediate attention',
+			'error'
+		);
+
+		$body .= JVB()->email()->h2('Error Details');
+		$body .= JVB()->email()->card(
+			'<p><strong>Component:</strong> ' . esc_html($component) . '</p>' .
+			'<p><strong>Message:</strong></p>' .
+			JVB()->email()->codeBlock($message),
+			'Error Information'
+		);
+
+		if (!empty($context)) {
+			$body .= JVB()->email()->h3('Additional Context');
+			$body .= JVB()->email()->codeBlock(json_encode($context, JSON_PRETTY_PRINT));
+		}
+
+		return JVB()->email()->sendEmail($admin_email, $subject, $body, 'CRITICAL ERROR');
+	}
 
     /**
      * 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
      * @return bool Whether email is sent
      */
-    public function sendErrorSummary():bool
-    {
-        // Get summary data
-        $summary = $this->gatherErrorSummary();
+	public function sendErrorSummary():bool
+	{
+		$summary = $this->gatherErrorSummary();
 
-        // Only send if there are errors
-        if (empty($summary['frequent']) && empty($summary['critical'])) {
-            return false;
-        }
+		if (empty($summary['frequent']) && empty($summary['critical'])) {
+			return false;
+		}
 
-        $admin_email = get_option('admin_email');
-        $site_name = get_bloginfo('name');
-        $today = date('Y-m-d');
-        $yesterday = date('Y-m-d', strtotime('-1 day'));
+		$admin_email = get_option('admin_email');
+		$site_name = get_bloginfo('name');
+		$yesterday = date('Y-m-d', strtotime('-1 day'));
+		$subject = "[{$site_name}] Daily Error Summary - " . date('Y-m-d');
 
-        $subject = "[{$site_name}] Daily Error Summary - {$today}";
+		// Header with alert
+		$body = JVB()->email()->h1('Daily Error Summary');
+		$body .= sprintf('<p>Error summary for <strong>%s</strong></p>', $yesterday);
 
-        // Build email body
-        $body = "= Error Summary for {$yesterday} =\n\n";
+		// Summary stats in a grid
+		if (!empty($summary['stats'])) {
+			$stats = [
+				JVB()->email()->stat($summary['stats']->total_errors, 'Total Errors'),
+				JVB()->email()->stat($summary['stats']->critical_count, 'Critical', 'Requires attention'),
+				JVB()->email()->stat($summary['stats']->error_count, 'Errors'),
+				JVB()->email()->stat($summary['stats']->warning_count, 'Warnings')
+			];
+			$body .= JVB()->email()->grid($stats, 4);
+		}
 
-        // Add frequent errors section
-        if (!empty($summary['frequent'])) {
-            $body .= "== Most Frequent Errors ==\n\n";
+		// Alert if critical errors exist
+		if (!empty($summary['critical'])) {
+			$body .= JVB()->email()->alert(
+				sprintf('Found %d critical errors that need immediate attention', count($summary['critical'])),
+				'error'
+			);
+		}
 
-            foreach ($summary['frequent'] as $index => $error) {
-                $body .= ($index + 1) . ". [{$error->component}] {$error->error_type}\n";
-                $body .= "   Message: " . wp_trim_words($error->message, 20, '...') . "\n";
-                $body .= "   Count: {$error->count}\n\n";
-            }
-        }
+		$body .= JVB()->email()->spacer(20);
 
-        // Add critical errors section
-        if (!empty($summary['critical'])) {
-            $body .= "== Recent Critical Errors ==\n\n";
+		// Frequent errors section
+		if (!empty($summary['frequent'])) {
+			$body .= JVB()->email()->h2('Most Frequent Errors');
 
-            foreach ($summary['critical'] as $index => $error) {
-                $body .= ($index + 1) . ". [{$error->component}] {$error->error_type}\n";
-                $body .= "   Time: {$error->created_at}\n";
-                $body .= "   Message: " . $error->message . "\n\n";
+			foreach ($summary['frequent'] as $error) {
+				$cardContent = JVB()->email()->badge($error->count . 'x', 'warning') . ' ';
+				$cardContent .= '<strong>' . esc_html($error->error_type) . '</strong>';
+				$cardContent .= '<p style="margin:10px 0 5px 0;font-size:13px;">' . esc_html(wp_trim_words($error->message, 15)) . '</p>';
+				$cardContent .= '<p style="margin:0;font-size:12px;color:' . JVB()->email()->colours['dark-200'] . ';">
+                Source: ' . esc_html($error->source) . ' |
+                Logged in: ' . $error->logged_in_count . ' |
+                Logged out: ' . $error->logged_out_count . '
+            </p>';
 
-                // Include context for critical errors if available
-                if (!empty($error->context)) {
-                    $context = json_decode($error->context, true);
-                    if (is_array($context)) {
-                        $body .= "   Context:\n";
-                        foreach ($context as $key => $value) {
-                            if (is_array($value) || is_object($value)) {
-                                $value = json_encode($value);
-                            }
-                            $body .= "     - {$key}: {$value}\n";
-                        }
-                    }
-                    $body .= "\n";
-                }
-            }
-        }
+				$body .= JVB()->email()->card($cardContent, $error->component);
+			}
+		}
 
-        // Add dashboard link if available
-        $admin_url = admin_url('admin.php?page=jvb-error-logs');
-        $body .= "View detailed error logs in the dashboard: {$admin_url}\n\n";
+		// Critical errors section
+		if (!empty($summary['critical'])) {
+			$body .= JVB()->email()->spacer(30);
+			$body .= JVB()->email()->h2('Recent Critical Errors');
 
-        // Send the email
-        $sent = jvbMail($admin_email, $subject, $body, 'ERROR SUMMARY');
+			foreach ($summary['critical'] as $error) {
+				$cardContent = '<p><strong>Time:</strong> ' . esc_html($error->created_at) . '</p>';
+				$cardContent .= '<p><strong>Message:</strong></p>';
+				$cardContent .= JVB()->email()->codeBlock($error->message);
 
-        // Log that summary was sent
-        if ($sent) {
-            error_log("[ErrorHandler] Daily error summary sent to {$admin_email}");
-        } else {
-            error_log("[ErrorHandler] Daily error summary was not sent.");
-        }
+				// Include context if available
+				if (!empty($error->context)) {
+					$context = json_decode($error->context, true);
+					if (is_array($context)) {
+						$cardContent .= '<p><strong>Context:</strong></p>';
+						$cardContent .= JVB()->email()->codeBlock(json_encode($context, JSON_PRETTY_PRINT));
+					}
+				}
 
-        return $sent;
-    }
+				$body .= JVB()->email()->card($cardContent, $error->component . ': ' . $error->error_type);
+			}
+		}
+
+		// Dashboard link
+		$admin_url = admin_url('admin.php?page=jvb-error-logs');
+		$body .= JVB()->email()->spacer(30);
+		$body .= JVB()->email()->button($admin_url, 'View Detailed Logs');
+
+		return JVB()->email()->sendEmail($admin_email, $subject, $body, 'ERROR SUMMARY');
+	}
 
     /**
      * Get HTML version of the error summary for nicer emails
@@ -426,6 +538,8 @@
 
     }
 
+
+
     protected function buildParams(WP_REST_Request $request):array {
         $allowedSeverity = [
             'all',

--
Gitblit v1.10.0