From 47e77f9fac1155c536b2b87fec552c7fcce66fa6 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Mon, 01 Jun 2026 18:06:34 +0000
Subject: [PATCH] =Timeline block fixes. Next up: adding article schema classes

---
 inc/managers/ErrorHandler.php |  167 +++++++++++++++++++------------------------------------
 1 files changed, 59 insertions(+), 108 deletions(-)

diff --git a/inc/managers/ErrorHandler.php b/inc/managers/ErrorHandler.php
index 9e6cc9a..a3b1f33 100644
--- a/inc/managers/ErrorHandler.php
+++ b/inc/managers/ErrorHandler.php
@@ -12,8 +12,6 @@
 
 class ErrorHandler
 {
-    protected object $wpdb;
-	protected string $tableName;
     protected int $notification_threshold = 5; // Critical errors within 1 hour
 
     protected array $error_levels = [
@@ -24,11 +22,14 @@
         'critical' => 4
     ];
 
+	protected CustomTable $table;
+
     public function __construct()
     {
-        global $wpdb;
-        $this->wpdb = $wpdb;
-		$this->tableName = $wpdb->prefix . BASE . 'error_log';
+		$this->defineTables();
+//        global $wpdb;
+//        $this->wpdb = $wpdb;
+//		$this->tableName = $wpdb->prefix . BASE . 'error_log';
 
         add_filter(BASE.'handle_bulk_operation', [$this, 'processOperation'], 10, 3);
 
@@ -39,6 +40,35 @@
 //        add_filter(BASE.'admin_action_filter', [$this, 'adminActionFilter'], 10, 3);
     }
 
+	public function defineTables():void
+	{
+		$table = CustomTable::for('error_log');
+		$table->setColumns([
+			'id'			=> 'bigint(20) unsigned NOT NULL AUTO_INCREMENT',
+			'error_type'	=> 'varchar(50) NOT NULL',
+			'component'		=> 'varchar(100) NOT NULL',
+			'method'		=> 'varchar(100) DEFAULT NULL',
+			'page_url'		=> 'varchar(255) DEFAULT NULL',
+			'message'		=> 'text NOT NULL',
+			'context'		=> 'JSON',
+			'severity'		=> 'ENUM(\'high\',\'normal\',\'low\') DEFAULT \'normal\'',
+			'user_id'		=> $table->getUserIDType().' DEFAULT NULL',
+			'user_was_logged_in'	=> 'tinyint(1) NOT NULL',
+			'source'		=> 'ENUM(\'frontend\', \'backend\') NOT NULL',
+			'created_at'	=> 'timestamp DEFAULT CURRENT_TIMESTAMP',
+		]);
+
+		$table->setKeys([
+			['key' => 'PRIMARY', 'value' => 'id'],
+			'`created_at` (`created_at`)',
+			'`component_severity_date` (`component`, `severity`, `created_at`)',
+			'`error_type_date` (`error_type`, `created_at`)',
+			'`severity_date` (`severity`, `created_at`)'
+		]);
+
+		$table->defineTable();
+		$this->table = $table;
+	}
     public function registerAdminAction():void
     {
         $admin = JVB()->admin();
@@ -68,7 +98,7 @@
         }
 
         try {
-            $table = $this->tableName;
+
             // Extract error data
             $component = sanitize_text_field($data['component'] ?? '');
             $message = sanitize_textarea_field($data['message'] ?? '');
@@ -94,8 +124,7 @@
             }
 
             // Insert into database
-            $result = $this->wpdb->insert(
-                $table,
+            $result = $this->table->insert(
                 [
                     'error_type' => $error_type,
                     'component' => $component,
@@ -104,24 +133,15 @@
                     'severity' => $severity,
                     'user_id' => get_current_user_id(),
                     'created_at' => current_time('mysql')
-                ],
-                [
-                    '%s', // error_type
-                    '%s', // component
-                    '%s', // message
-                    '%s', // context (JSON)
-                    '%s', // severity
-                    '%d', // user_id
-                    '%s'  // created_at
                 ]
             );
 
-            if ($result === false) {
+            if (!$result) {
                 // If insert fails, log to PHP error log as fallback
-                error_log("[ErrorHandler] Database insert failed: " . $this->wpdb->last_error);
+                error_log("[ErrorHandler] Database insert failed: " . $this->table->getLastError());
                 return [
 					'success'	=> false,
-					'message'	=> "[ErrorHandler] Database insert failed: " . $this->wpdb->last_error
+					'message'	=> "[ErrorHandler] Database insert failed: " . $this->table->getLastError()
 				];
             }
 
@@ -155,19 +175,15 @@
     protected function checkErrorThreshold(string $error_type, string $component)
     {
         // Get count of similar critical errors in the last hour
-        $count = $this->wpdb->get_var($this->wpdb->prepare(
-            "SELECT COUNT(*)
-         FROM {$this->tableName}
-         WHERE error_type = %s
-         AND component = %s
-         AND severity = 'critical'
-         AND created_at > DATE_SUB(NOW(), INTERVAL 1 HOUR)",
-            $error_type,
-            $component
-        ));
+		$count = $this->table->count([
+			'error_type' => $error_type,
+			'component' => $component,
+			'severity' => $this->error_levels[$error_type],
+			'created_at' => ['>','DATE_SUB(NOW(), INTERVAL 1 HOUR)']
+		]);
 
         // If threshold reached, take additional actions (e.g., notify developers)
-        if ((int)$count >= $this->notification_threshold) {
+        if ($count >= $this->notification_threshold) {
             // You could send an urgent notification, Slack message, etc.
             $admin_email = get_option('admin_email');
             $subject = "[URGENT] Error Threshold Exceeded for {$component}";
@@ -189,8 +205,6 @@
 	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';
@@ -207,8 +221,7 @@
 			$source = isset($context['source']) ? $context['source'] :
 				(isset($context['url']) ? 'frontend' : 'backend');
 
-			$result = $this->wpdb->insert(
-				$table,
+			$result = $this->table->insert(
 				[
 					'error_type' => $error_type,
 					'component' => $component,
@@ -221,20 +234,18 @@
 					'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 (!$result) {
+				error_log("[ErrorHandler] Database insert failed: " . $this->table->getLastError());
+				return ['success' => false, 'message' => $this->table->getLastError()];
 			}
 
 			if ($severity === 'critical') {
 				$this->checkErrorThreshold($error_type, $component);
 			}
 
-			return ['success' => true, 'id' => $this->wpdb->insert_id];
+			return ['success' => true, 'id' => $result];
 
 		} catch (Exception $e) {
 			error_log("[ErrorHandler Exception] " . $e->getMessage());
@@ -283,8 +294,6 @@
      */
 	public function gatherErrorSummary(?string $start_date = null, ?string $end_date = null): array
 	{
-		$table = $this->wpdb->prefix . BASE . 'error_log';
-
 		if (!$start_date) {
 			$start_date = gmdate('Y-m-d 00:00:00', strtotime('-1 day'));
 		}
@@ -293,72 +302,14 @@
 		}
 
 		// 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
-		));
-
-		// 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
-		));
+		$frequent = $this->table->getMany([
+			'where' => [
+				'created_at'	=> ['BETWEEN', "{$start_date} AND {$end_date}"]
+			]
+		]);
 
 		return [
-			'frequent' => $frequent,
-			'critical' => $critical,
-			'stats' => $stats,
+			'errors'	=> $frequent,
 			'date_range' => ['start' => $start_date, 'end' => $end_date]
 		];
 	}

--
Gitblit v1.10.0