PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 3.2.2
MxChat – AI Chatbot & Content Generation for WordPress v3.2.2
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 | admin/class-knowledge-manager.php +50 -88 3.2.13.2.2 View file →
@@ -59,11 +59,8 @@
59 59 add_action('wp_ajax_mxchat_paginate_entries', array($this, 'ajax_mxchat_paginate_entries'));
60 60 add_action('wp_ajax_mxchat_get_entry_content', array($this, 'ajax_mxchat_get_entry_content'));
61 61 add_action('wp_ajax_mxchat_save_entry_content', array($this, 'ajax_mxchat_save_entry_content'));
62 62
63 - // Hook for content deletion
64 - add_action('mxchat_delete_content', array($this, 'mxchat_delete_from_pinecone_by_url'), 10, 1);
65 -
66 63 // WordPress post management hooks
67 64 add_action('pre_post_update', array($this, 'mxchat_store_pre_update_status'), 10, 2);
68 65 add_action('post_updated', array($this, 'mxchat_handle_post_update'), 10, 3);
69 66 add_action('before_delete_post', array($this, 'mxchat_handle_post_delete'));
@@ -5184,40 +5181,33 @@
5184 5181 // If the post was previously published but is now not published, remove from knowledge base
5185 5182 if ($previous_status === 'publish' && $post->post_status !== 'publish') {
5186 5183 // Use the stored URL from when it was published, or fall back to current permalink
5187 5184 $source_url = $previous_url ?: get_permalink($post_id);
5188 -
5185 +
5189 5186 if ($source_url) {
5190 - // Check if Pinecone is enabled
5191 - $pinecone_options = get_option('mxchat_pinecone_addon_options', array());
5192 - $use_pinecone = ($pinecone_options['mxchat_use_pinecone'] ?? '0') === '1';
5187 + // Chunk-aware deletion (routes to Pinecone or WP DB and removes base + all chunks)
5188 + MxChat_Utils::delete_chunks_for_url($source_url, 'default');
5189 + }
5193 5190
5194 - if ($use_pinecone && !empty($pinecone_options['mxchat_pinecone_api_key'])) {
5195 - // Delete from Pinecone
5196 - $this->mxchat_delete_from_pinecone_by_url($source_url, $pinecone_options);
5197 - } else {
5198 - // Delete from WordPress DB
5199 - global $wpdb;
5200 - $table_name = $wpdb->prefix . 'mxchat_system_prompt_content';
5201 -
5202 - $result = $wpdb->delete(
5203 - $table_name,
5204 - array('source_url' => $source_url),
5205 - array('%s')
5206 - );
5207 - }
5208 - }
5209 -
5210 5191 // Clean up the transients and exit early
5211 5192 delete_transient($previous_status_key);
5212 5193 delete_transient($previous_url_key);
5213 5194 return;
5214 5195 }
5215 -
5196 +
5197 + // Slug/permalink rename while still published: delete the old vectors before upserting new ones.
5198 + // Without this, md5(old_url) vectors (base + chunks) would be orphaned under the stale URL.
5199 + if ($post->post_status === 'publish' && !empty($previous_url)) {
5200 + $current_url = get_permalink($post_id);
5201 + if ($current_url && $current_url !== $previous_url) {
5202 + MxChat_Utils::delete_chunks_for_url($previous_url, 'default');
5203 + }
5204 + }
5205 +
5216 5206 // Store the current status for next time (if this is an update)
5217 5207 if ($update) {
5218 5208 set_transient($previous_status_key, $post->post_status, DAY_IN_SECONDS);
5219 -
5209 +
5220 5210 // If the post is currently published, also store its URL
5221 5211 if ($post->post_status === 'publish') {
5222 5212 $current_url = get_permalink($post_id);
5223 5213 set_transient($previous_url_key, $current_url, DAY_IN_SECONDS);
@@ -5447,12 +5437,14 @@
5447 5437 if (!$should_sync) {
5448 5438 return;
5449 5439 }
5450 5440
5451 - // Get the URL before post is deleted
5452 - $source_url = get_permalink($post_id);
5441 + // Resolve the pre-trash URL. wp_trash_post renames the slug with "__trashed" before firing
5442 + // this hook, so get_permalink() here would return the trashed URL and md5() would miss the
5443 + // real vector IDs stored under the original URL.
5444 + $source_url = $this->mxchat_resolve_pre_trash_url($post_id);
5453 5445 if (!$source_url) {
5454 - //error_log('MXChat: Failed to get permalink for post ' . $post_id);
5446 + //error_log('MXChat: Failed to resolve source URL for post ' . $post_id);
5455 5447 return;
5456 5448 }
5457 5449
5458 5450 // Use chunk-aware deletion (handles both chunked and non-chunked content)
@@ -5460,56 +5452,36 @@
5460 5452
5461 5453 if (is_wp_error($delete_result)) {
5462 5454 //error_log('MXChat: Chunk-aware deletion failed for URL: ' . $source_url . ' - ' . $delete_result->get_error_message());
5463 5455 }
5456 +
5457 + delete_transient('mxchat_prev_url_' . $post_id);
5458 + delete_transient('mxchat_prev_status_' . $post_id);
5464 5459 }
5465 5460
5461 +/**
5462 + * Resolve the source URL for a post being trashed/deleted.
5463 + *
5464 + * Why: wp_trash_post appends "__trashed" to the slug before the wp_trash_post action fires, so
5465 + * get_permalink() returns a URL whose md5() won't match the vector IDs stored in Pinecone or
5466 + * the source_url rows in the WP DB. Prefer the URL captured by mxchat_store_pre_update_status
5467 + * (runs on pre_post_update, before the rename); fall back to stripping the __trashed suffix.
5468 + */
5469 +private function mxchat_resolve_pre_trash_url($post_id) {
5470 + $previous_url = get_transient('mxchat_prev_url_' . $post_id);
5471 + if (!empty($previous_url)) {
5472 + return $previous_url;
5473 + }
5466 5474
5467 - /**
5468 - * Deletes data from Pinecone using a source URL
5469 - */
5470 - public function mxchat_delete_from_pinecone_by_url($source_url, $pinecone_options) {
5471 - $host = $pinecone_options['mxchat_pinecone_host'] ?? '';
5472 - $api_key = $pinecone_options['mxchat_pinecone_api_key'] ?? '';
5475 + $current = get_permalink($post_id);
5476 + if (!$current) {
5477 + return '';
5478 + }
5479 + return preg_replace('#__trashed(/?)$#', '$1', $current);
5480 +}
5473 5481
5474 - if (empty($host) || empty($api_key)) {
5475 - //error_log('MXChat: Pinecone deletion failed - missing configuration');
5476 - return false;
5477 - }
5478 5482
5479 - $api_endpoint = "https://{$host}/vectors/delete";
5480 - $vector_id = md5($source_url);
5481 5483
5482 - $request_body = array(
5483 - 'ids' => array($vector_id)
5484 - );
5485 -
5486 - $response = wp_remote_post($api_endpoint, array(
5487 - 'headers' => array(
5488 - 'Api-Key' => $api_key,
5489 - 'accept' => 'application/json',
5490 - 'content-type' => 'application/json'
5491 - ),
5492 - 'body' => wp_json_encode($request_body),
5493 - 'timeout' => 30
5494 - ));
5495 -
5496 - if (is_wp_error($response)) {
5497 - //error_log('MXChat: Pinecone deletion error - ' . $response->get_error_message());
5498 - return false;
5499 - }
5500 -
5501 - $response_code = wp_remote_retrieve_response_code($response);
5502 - if ($response_code !== 200) {
5503 - //error_log('MXChat: Pinecone deletion failed with status ' . $response_code);
5504 - return false;
5505 - }
5506 -
5507 - return true;
5508 - }
5509 -
5510 -
5511 -
5512 5484 public function mxchat_handle_product_change($post_id, $post, $update) {
5513 5485 if ($post->post_type !== 'product') {
5514 5486 return;
5515 5487 }
@@ -5661,28 +5633,18 @@
5661 5633 if (get_post_type($post_id) !== 'product') {
5662 5634 return;
5663 5635 }
5664 5636
5665 - $source_url = get_permalink($post_id);
5637 + $source_url = $this->mxchat_resolve_pre_trash_url($post_id);
5638 + if (!$source_url) {
5639 + return;
5640 + }
5666 5641
5667 - // Check if Pinecone is enabled
5668 - $pinecone_options = get_option('mxchat_pinecone_addon_options', array());
5669 - $use_pinecone = ($pinecone_options['mxchat_use_pinecone'] ?? '0') === '1';
5642 + // Chunk-aware deletion (routes to Pinecone or WP DB and removes base + all chunks)
5643 + MxChat_Utils::delete_chunks_for_url($source_url, 'default');
5670 5644
5671 - if ($use_pinecone && !empty($pinecone_options['mxchat_pinecone_api_key'])) {
5672 - // Delete from Pinecone
5673 - $this->mxchat_delete_from_pinecone_by_url($source_url, $pinecone_options);
5674 - } else {
5675 - // Delete from WordPress DB
5676 - global $wpdb;
5677 - $table_name = $wpdb->prefix . 'mxchat_system_prompt_content';
5678 -
5679 - $wpdb->delete(
5680 - $table_name,
5681 - array('source_url' => $source_url),
5682 - array('%s')
5683 - );
5684 - }
5645 + delete_transient('mxchat_prev_url_' . $post_id);
5646 + delete_transient('mxchat_prev_status_' . $post_id);
5685 5647 }
5686 5648
5687 5649 /**
5688 5650 * Handle individual Pinecone content deletion