['internal_function_track_order'], 'aizl_track_ticket' => ['internal_function_track_ticket'], 'aizl_get_bestsellers' => ['internal_function_get_bestsellers'], ]; protected static array $handlers = []; public static function register_handler(string $class_name): string { if (!class_exists($class_name)) { return "Error: Handler class $class_name does not exist"; } if (!is_subclass_of($class_name, self::class)) { return "Error: $class_name must extend " . self::class; } self::$handlers[$class_name] = $class_name; return "Handler $class_name registered successfully"; } public static function internal_call(string $function_name, array $args = []) { $map = array_merge(self::$function_map, apply_filters('aizl_function_map', [])); if (!isset($map[$function_name])) { return "Function $function_name not available"; } $method = $map[$function_name][0]; // Check main class first if (method_exists(self::class, $method)) { return self::$method($args); } // Check registered handlers foreach (self::$handlers as $handler_class) { if (method_exists($handler_class, $method)) { return $handler_class::$method($args); } } return "No handler available for $function_name (method: $method)"; } // Accepts an associative array of arguments public static function internal_function_track_order($args) { $order_id = $args['order_id'] ?? null; if (!$order_id) { $result = json_encode([ 'order_status' => 'No Order ID' ]); return $result; } global $wpdb; $table = esc_sql($wpdb->prefix . 'wc_order_stats'); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Querying WooCommerce custom table, table name is escaped $status = $wpdb->get_var($wpdb->prepare("SELECT status FROM `{$table}` WHERE order_id = %s", $order_id)); if (!$status) { $result = json_encode([ 'order_status' => 'Order not found' ]); return $result; } else { $result = json_encode([ 'order_status' => $status ]); return $result; } } public static function internal_function_track_ticket($args) { $ticket_number = $args['ticket_number'] ?? null; $email = $args['email'] ?? null; if (!$ticket_number || !$email) { $result = json_encode([ 'error' => 'Ticket number and email are required' ]); return $result; } global $wpdb; // Check if SupportCandy tables exist $tickets_table = esc_sql($wpdb->prefix . 'psmsc_tickets'); $customers_table = esc_sql($wpdb->prefix . 'psmsc_customers'); $threads_table = esc_sql($wpdb->prefix . 'psmsc_threads'); $statuses_table = esc_sql($wpdb->prefix . 'psmsc_statuses'); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Checking for SupportCandy plugin tables if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $tickets_table)) != $tickets_table) { $result = json_encode([ 'error' => 'SupportCandy plugin not found or not active' ]); return $result; } // Get ticket information with status and customer details // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Querying SupportCandy custom tables, table names are escaped $ticket = $wpdb->get_row($wpdb->prepare("SELECT t.id, t.id as ticket_number, s.name as status_name, s.color, c.name as customer_name, c.email as customer_email, t.date_created, t.date_updated FROM `{$tickets_table}` t JOIN `{$customers_table}` c ON t.customer = c.id LEFT JOIN `{$statuses_table}` s ON t.status = s.id WHERE t.id = %s AND c.email = %s", $ticket_number, $email)); if (!$ticket) { $result = json_encode([ 'error' => 'Ticket not found or email does not match' ]); return $result; } // Get latest thread/message // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Querying SupportCandy custom tables, table name is escaped $latest_thread = $wpdb->get_row($wpdb->prepare("SELECT body, type, date_created FROM `{$threads_table}` WHERE ticket = %d AND is_active = 1 AND type != 'log' ORDER BY date_created DESC LIMIT 1", $ticket->id)); $result = json_encode([ 'ticket_number' => $ticket->ticket_number, 'status' => $ticket->status_name ?: 'Unknown', 'status_color' => $ticket->color ?: '#999999', 'customer_name' => $ticket->customer_name, 'date_created' => $ticket->date_created, 'last_updated' => $ticket->date_updated, 'latest_message' => [ 'content' => $latest_thread ? wp_strip_all_tags($latest_thread->body) : 'No messages found', 'type' => $latest_thread ? $latest_thread->type : 'system', 'date' => $latest_thread ? $latest_thread->date_created : $ticket->date_created ] ]); return $result; } public static function internal_function_get_bestsellers($args) { // Check if WooCommerce is active if (!class_exists('WooCommerce')) { return json_encode([ 'error' => 'WooCommerce plugin is not active' ]); } global $wpdb; $lookup_table = esc_sql($wpdb->prefix . 'wc_order_product_lookup'); // Check if the analytics table exists // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Checking for WooCommerce Analytics table if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $lookup_table)) != $lookup_table) { return json_encode([ 'error' => 'WooCommerce analytics table not found' ]); } // Get top 5 bestselling products // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Querying WooCommerce Analytics custom tables, table name is escaped $bestsellers = $wpdb->get_results("SELECT p.ID as product_id, p.post_title as product_name, SUM(ol.product_qty) as total_sold, pm.meta_value as price FROM `{$lookup_table}` ol JOIN {$wpdb->posts} p ON ol.product_id = p.ID LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = '_price' WHERE p.post_status = 'publish' AND p.post_type = 'product' GROUP BY ol.product_id ORDER BY total_sold DESC LIMIT 5"); if (empty($bestsellers)) { return json_encode([ 'message' => 'No sales data available yet' ]); } $result = []; foreach ($bestsellers as $product) { $result[] = [ 'product_id' => $product->product_id, 'name' => $product->product_name, 'total_sold' => (int)$product->total_sold, 'price' => $product->price ? '$' . number_format((float)$product->price, 2) : 'Price not available', 'url' => get_permalink($product->product_id) ]; } return json_encode([ 'bestsellers' => $result, 'count' => count($result) ]); } }