PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 1.1.7
MxChat – AI Chatbot & Content Generation for WordPress v1.1.7
3.2.21 3.2.20 3.2.19 3.2.18 3.2.17 3.2.16 3.2.15 3.2.14 3.2.12 3.2.13 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 3.2.6 3.2.5 3.2.4 3.2.3 3.2.2 3.2.1 2.0.3 2.0.4 2.0.5 2.0.6 All 152 releases
← All changes | includes/class-mxchat-woocommerce.php +205 -230 3.2.211.1.7 View file →
@@ -1,230 +1,205 @@
1 -<?php
2 -
3 -if (!defined('ABSPATH')) {
4 - exit;
5 -}
6 -
7 -class MxChat_WooCommerce {
8 -
9 - public static function init() {
10 - add_action('wp_ajax_mxchat_fetch_user_orders', array(__CLASS__, 'mxchat_fetch_user_orders'));
11 - add_action('wp_ajax_nopriv_mxchat_fetch_user_orders', array(__CLASS__, 'mxchat_fetch_user_orders'));
12 -
13 - add_action('wp_ajax_mxchat_add_to_cart', array(__CLASS__, 'mxchat_add_to_cart'));
14 -add_action('wp_ajax_nopriv_mxchat_add_to_cart', array(__CLASS__, 'mxchat_add_to_cart'));
15 -
16 - }
17 -
18 - // New function to handle add to cart requests
19 -public static function mxchat_add_to_cart() {
20 - // Validate nonce
21 - if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'mxchat_nonce')) {
22 - wp_send_json_error('Invalid nonce.');
23 - wp_die();
24 - }
25 -
26 - $product_id = isset($_POST['product_id']) ? intval($_POST['product_id']) : 0;
27 - if (!$product_id) {
28 - wp_send_json_error('Invalid product ID.');
29 - wp_die();
30 - }
31 -
32 - // Add to WooCommerce cart
33 - $added = WC()->cart->add_to_cart($product_id);
34 - if ($added) {
35 - $product = wc_get_product($product_id);
36 - wp_send_json_success(['message' => "The product '{$product->get_name()}' has been added to your cart."]);
37 - } else {
38 - wp_send_json_error('Error adding product to cart.');
39 - }
40 - wp_die();
41 -}
42 -
43 -
44 -public static function mxchat_fetch_user_orders_details($type = 'all') {
45 - $user_id = get_current_user_id();
46 - if (!$user_id && isset(WC()->session)) {
47 - $user_id = WC()->session->get_customer_id();
48 - }
49 -
50 - if (!$user_id) {
51 - return [];
52 - }
53 -
54 - $args = array(
55 - 'customer_id' => $user_id,
56 - 'limit' => ($type === 'last') ? 1 : 5, // Limit to last 5 orders for 'all'
57 - 'orderby' => 'date',
58 - 'order' => 'DESC',
59 - );
60 -
61 - $orders = wc_get_orders($args);
62 -
63 - if (empty($orders)) {
64 - return [];
65 - }
66 -
67 - $order_details = [];
68 - foreach ($orders as $order) {
69 - $items = [];
70 - foreach ($order->get_items() as $item) {
71 - $items[] = [
72 - 'name' => $item->get_name(),
73 - 'total' => $order->get_formatted_line_subtotal($item),
74 - 'license_key' => $item->get_meta('_license_key'), // Get specific meta if needed
75 - 'quantity' => $item->get_quantity()
76 - ];
77 - }
78 -
79 - $order_details[] = [
80 - 'order_id' => $order->get_id(),
81 - 'date' => $order->get_date_created()->date('F j, Y'),
82 - 'status' => wc_get_order_status_name($order->get_status()),
83 - 'total' => $order->get_total(),
84 - 'formatted_total' => $order->get_formatted_order_total(),
85 - 'items' => $items
86 - ];
87 -
88 - if ($type === 'last') {
89 - break;
90 - }
91 - }
92 -
93 - return $order_details;
94 -}
95 -
96 -
97 - // Check if there are items in the cart
98 - public static function cart_has_items() {
99 - return WC()->cart && WC()->cart->get_cart_contents_count() > 0;
100 - }
101 -
102 -/**
103 - * Extract product ID from message with advanced matching.
104 - *
105 - * @param string $message The search message
106 - * @return int|null Product ID if found, null if no match
107 - */
108 -public static function mxchat_extract_product_id_from_message($message) {
109 - if (!function_exists('wc_get_products')) {
110 - //error_log("WooCommerce is not active or not available.");
111 - return null;
112 - }
113 -
114 - // Clean and normalize input
115 - $message = sanitize_text_field(strtolower($message));
116 - //error_log("Product extraction message: " . $message);
117 -
118 - // Get all published products
119 - $products = wc_get_products([
120 - 'status' => 'publish',
121 - 'limit' => -1,
122 - 'return' => 'objects'
123 - ]);
124 -
125 - //error_log("Total products to search: " . count($products));
126 -
127 - // Store all matches with their scores
128 - $matches = [];
129 -
130 - // Search terms (original message and name-only version)
131 - $search_terms = explode(' ', $message);
132 - //error_log("Search terms: " . implode(', ', $search_terms));
133 -
134 - foreach ($products as $product) {
135 - $score = 0;
136 - $product_name = strtolower($product->get_name());
137 - $product_slug = strtolower($product->get_slug());
138 - $product_sku = strtolower($product->get_sku());
139 -
140 - // Score calculation
141 - $matched_terms = 0;
142 - $consecutive_matches = 0;
143 - $max_consecutive = 0;
144 -
145 - // Check for consecutive term matches
146 - for ($i = 0; $i < count($search_terms); $i++) {
147 - $term = $search_terms[$i];
148 -
149 - // Skip common words
150 - if (strlen($term) <= 2 || in_array($term, ['the', 'and', 'or', 'for', 'to', 'in', 'on', 'at', 'of'])) {
151 - continue;
152 - }
153 -
154 - // Check name, slug, and SKU
155 - if (strpos($product_name, $term) !== false ||
156 - strpos($product_slug, $term) !== false ||
157 - strpos($product_sku, $term) !== false) {
158 -
159 - $matched_terms++;
160 - $consecutive_matches++;
161 - $max_consecutive = max($max_consecutive, $consecutive_matches);
162 - } else {
163 - $consecutive_matches = 0;
164 - }
165 - }
166 -
167 - // Calculate final score
168 - if ($matched_terms > 0) {
169 - // Base score from matched terms
170 - $score = $matched_terms / count(array_filter($search_terms, function($term) {
171 - return strlen($term) > 2;
172 - }));
173 -
174 - // Bonus for consecutive matches
175 - $score += ($max_consecutive > 1) ? 0.3 : 0;
176 -
177 - // Bonus for exact matches
178 - if (strpos($product_name, implode(' ', $search_terms)) !== false) {
179 - $score += 0.5;
180 - }
181 -
182 - // Store match if score is above zero
183 - if ($score > 0) {
184 - $matches[] = [
185 - 'product_id' => $product->get_id(),
186 - 'score' => $score,
187 - 'name' => $product_name,
188 - 'consecutive_matches' => $max_consecutive
189 - ];
190 -
191 - // error_log(sprintf("Product '%s' scored %f with %d consecutive matches", $product_name, $score, $max_consecutive));
192 - }
193 - }
194 - }
195 -
196 - // Sort matches by score
197 - usort($matches, function($a, $b) {
198 - if ($b['score'] === $a['score']) {
199 - // If scores are equal, prefer the one with more consecutive matches
200 - return $b['consecutive_matches'] - $a['consecutive_matches'];
201 - }
202 - return $b['score'] <=> $a['score'];
203 - });
204 -
205 - // Return the best match if we found any
206 - if (!empty($matches)) {
207 - $best_match = $matches[0];
208 - // error_log(sprintf("Selected best match: '%s' (ID: %d) with score %f and %d consecutive matches", $best_match['name'], $best_match['product_id'], $best_match['score'], $best_match['consecutive_matches']));
209 - return $best_match['product_id'];
210 - }
211 -
212 - //error_log("No product matches found");
213 - return null;
214 -}
215 -
216 -
217 -
218 - // Store the product ID in session when discussed
219 - public static function store_last_discussed_product($product_id) {
220 - set_transient('mxchat_last_product', $product_id, 12 * HOUR_IN_SECONDS);
221 - }
222 -
223 - // Retrieve the last discussed product ID
224 - public static function get_last_discussed_product() {
225 - return get_transient('mxchat_last_product');
226 - }
227 -
228 -}
229 -
230 -MxChat_WooCommerce::init();
1 +<?php
2 +
3 +if (!defined('ABSPATH')) {
4 + exit;
5 +}
6 +
7 +class MxChat_WooCommerce {
8 +
9 + public static function init() {
10 + add_action('wp_ajax_mxchat_fetch_user_orders', array(__CLASS__, 'mxchat_fetch_user_orders'));
11 + add_action('wp_ajax_nopriv_mxchat_fetch_user_orders', array(__CLASS__, 'mxchat_fetch_user_orders'));
12 + }
13 +
14 + // Fetch user orders via AJAX
15 + public static function mxchat_fetch_user_orders() {
16 + // Check if WooCommerce order access is enabled in the settings
17 + if (!self::is_order_access_enabled()) {
18 + wp_send_json_error(__('Order tracking is disabled. Please contact support for more information.', 'mxchat'));
19 + wp_die();
20 + }
21 +
22 + // Validate the AJAX request with a nonce
23 + if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'mxchat_nonce')) {
24 + wp_send_json_error(__('Invalid request.', 'mxchat'));
25 + wp_die();
26 + }
27 +
28 + // Check if the user is logged in
29 + if (!is_user_logged_in()) {
30 + wp_send_json_error(__('You need to be logged in to view your orders.', 'mxchat'));
31 + wp_die();
32 + }
33 +
34 + // Fetch the logged-in user ID
35 + $user_id = get_current_user_id();
36 +
37 + // Fetch orders associated with the user
38 + $orders = wc_get_orders(array(
39 + 'customer_id' => $user_id,
40 + 'limit' => -1,
41 + 'orderby' => 'date',
42 + 'order' => 'DESC',
43 + ));
44 +
45 + if (empty($orders)) {
46 + wp_send_json_error(__('No orders found.', 'mxchat'));
47 + wp_die();
48 + }
49 +
50 + $order_data = array();
51 + foreach ($orders as $order) {
52 + $order_id = $order->get_id();
53 + $order_date = $order->get_date_created()->date('F j, Y');
54 + $order_total = wc_price($order->get_total());
55 + $order_status = wc_get_order_status_name($order->get_status());
56 + $order_items = array_map(function ($item) {
57 + return $item->get_name();
58 + }, $order->get_items());
59 +
60 + $order_data[] = array(
61 + 'order_id' => $order_id,
62 + 'order_date' => $order_date,
63 + 'order_total' => $order_total,
64 + 'order_status' => $order_status,
65 + 'order_items' => $order_items,
66 + );
67 + }
68 +
69 + // Send the order data as a success response
70 + wp_send_json_success($order_data);
71 + wp_die();
72 + }
73 +
74 + // Helper function to determine if the query is related to orders
75 + public static function mxchat_is_order_related_query($message) {
76 + $keywords = array('my orders', 'order status', 'previous orders', 'order history');
77 + foreach ($keywords as $keyword) {
78 + if (stripos($message, $keyword) !== false) {
79 + return true;
80 + }
81 + }
82 + return false;
83 + }
84 +
85 + // Function to fetch the user's order details as a string
86 + public static function mxchat_fetch_user_orders_details() {
87 + // Ensure the session is active
88 + if (!session_id()) {
89 + session_start();
90 + }
91 +
92 + // Check if WooCommerce order access is enabled
93 + if (!self::is_order_access_enabled()) {
94 + return "Order tracking is disabled. Please contact support for more information.";
95 + }
96 +
97 + // Check if the user is logged in
98 + if (!is_user_logged_in()) {
99 + return 'User is not logged in.';
100 + }
101 +
102 + // Fetch the logged-in user ID
103 + $user_id = get_current_user_id();
104 +
105 + // Fetch all orders associated with the user, regardless of status
106 + $orders = wc_get_orders(array(
107 + 'customer_id' => $user_id,
108 + 'limit' => -1,
109 + 'orderby' => 'date',
110 + 'order' => 'DESC',
111 + ));
112 +
113 + if (empty($orders)) {
114 + return 'No orders found for the user.';
115 + }
116 +
117 + $order_details = "Your recent orders:\n";
118 + foreach ($orders as $order) {
119 + $items = implode(', ', array_map(function ($item) {
120 + return $item->get_name();
121 + }, $order->get_items()));
122 +
123 + $order_details .= "Order #{$order->get_id()} on {$order->get_date_created()->date('F j, Y')} - Status: {$order->get_status()} - Total: {$order->get_total()} - Items: {$items}\n";
124 + }
125 +
126 + return $order_details;
127 + }
128 +
129 + // Function to check if order access is enabled in the admin settings
130 + public static function is_order_access_enabled() {
131 + $options = get_option('mxchat_options', array());
132 + return isset($options['enable_woocommerce_order_access']) && $options['enable_woocommerce_order_access'] === '1';
133 + }
134 +
135 + // Check if there are items in the cart
136 + public static function cart_has_items() {
137 + return WC()->cart && WC()->cart->get_cart_contents_count() > 0;
138 + }
139 +
140 +public static function mxchat_extract_product_id_from_message($message) {
141 + // Ensure WooCommerce functions are available
142 + if (!function_exists('wc_get_products')) {
143 + error_log("WooCommerce is not active or not available.");
144 + return null; // Exit if WooCommerce is not active
145 + }
146 +
147 + // Normalize the message
148 + $message = sanitize_text_field(strtolower($message));
149 +
150 + // Add debug log for the incoming message
151 + error_log("Product extraction message: " . $message);
152 +
153 + // Split the message into individual words to search more effectively
154 + $search_terms = explode(' ', $message);
155 +
156 + // Log the search terms
157 + error_log("Search terms: " . implode(', ', $search_terms));
158 +
159 + // Search for the product in WooCommerce catalog by title, slug, and SKU
160 + $args = array(
161 + 'status' => 'publish',
162 + 'limit' => 5, // Retrieve multiple products to better match
163 + 'return' => 'objects',
164 + );
165 +
166 + $products = wc_get_products($args);
167 +
168 + // Log how many products were fetched
169 + error_log("Total products found: " . count($products));
170 +
171 + foreach ($products as $product) {
172 + // Check if the product title, slug, or SKU matches any of the search terms
173 + $product_name = strtolower($product->get_name());
174 + $product_slug = strtolower($product->get_slug());
175 + $product_sku = strtolower($product->get_sku());
176 +
177 + foreach ($search_terms as $term) {
178 + if (stripos($product_name, $term) !== false || stripos($product_slug, $term) !== false || stripos($product_sku, $term) !== false) {
179 + // Log which product was matched
180 + error_log("Matched product: " . $product_name . " (ID: " . $product->get_id() . ")");
181 + return $product->get_id(); // Return the first matching product ID
182 + }
183 + }
184 + }
185 +
186 + // If no product matches, log the failure
187 + error_log("No product matched for message: " . $message);
188 +
189 + return null;
190 +}
191 +
192 +
193 + // Store the product ID in session when discussed
194 + public static function store_last_discussed_product($product_id) {
195 + set_transient('mxchat_last_product', $product_id, 12 * HOUR_IN_SECONDS);
196 + }
197 +
198 + // Retrieve the last discussed product ID
199 + public static function get_last_discussed_product() {
200 + return get_transient('mxchat_last_product');
201 + }
202 +
203 +}
204 +
205 +MxChat_WooCommerce::init();