PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 3.1.8
MxChat – AI Chatbot & Content Generation for WordPress v3.1.8
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 +89 -52 3.2.33.1.8 View file →
@@ -59,8 +59,11 @@
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 +
63 66 // WordPress post management hooks
64 67 add_action('pre_post_update', array($this, 'mxchat_store_pre_update_status'), 10, 2);
65 68 add_action('post_updated', array($this, 'mxchat_handle_post_update'), 10, 3);
66 69 add_action('before_delete_post', array($this, 'mxchat_handle_post_delete'));
@@ -602,12 +605,11 @@
602 605 array(
603 606 'article_content' => $article_content,
604 607 'embedding_vector' => $embedding_vector_serialized,
605 608 'source_url' => $article_url,
606 - 'embedding_model' => MxChat_Utils::get_active_embedding_model(),
607 609 ),
608 610 array('id' => $prompt_id),
609 - array('%s', '%s', '%s', '%s'),
611 + array('%s', '%s', '%s'),
610 612 array('%d')
611 613 );
612 614 if ($updated !== false) {
613 615 wp_send_json_success();
@@ -5182,33 +5184,40 @@
5182 5184 // If the post was previously published but is now not published, remove from knowledge base
5183 5185 if ($previous_status === 'publish' && $post->post_status !== 'publish') {
5184 5186 // Use the stored URL from when it was published, or fall back to current permalink
5185 5187 $source_url = $previous_url ?: get_permalink($post_id);
5188 +
5189 + 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';
5186 5193
5187 - if ($source_url) {
5188 - // Chunk-aware deletion (routes to Pinecone or WP DB and removes base + all chunks)
5189 - MxChat_Utils::delete_chunks_for_url($source_url, 'default');
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 + }
5190 5208 }
5191 -
5209 +
5192 5210 // Clean up the transients and exit early
5193 5211 delete_transient($previous_status_key);
5194 5212 delete_transient($previous_url_key);
5195 5213 return;
5196 5214 }
5197 -
5198 - // Slug/permalink rename while still published: delete the old vectors before upserting new ones.
5199 - // Without this, md5(old_url) vectors (base + chunks) would be orphaned under the stale URL.
5200 - if ($post->post_status === 'publish' && !empty($previous_url)) {
5201 - $current_url = get_permalink($post_id);
5202 - if ($current_url && $current_url !== $previous_url) {
5203 - MxChat_Utils::delete_chunks_for_url($previous_url, 'default');
5204 - }
5205 - }
5206 -
5215 +
5207 5216 // Store the current status for next time (if this is an update)
5208 5217 if ($update) {
5209 5218 set_transient($previous_status_key, $post->post_status, DAY_IN_SECONDS);
5210 -
5219 +
5211 5220 // If the post is currently published, also store its URL
5212 5221 if ($post->post_status === 'publish') {
5213 5222 $current_url = get_permalink($post_id);
5214 5223 set_transient($previous_url_key, $current_url, DAY_IN_SECONDS);
@@ -5438,14 +5447,12 @@
5438 5447 if (!$should_sync) {
5439 5448 return;
5440 5449 }
5441 5450
5442 - // Resolve the pre-trash URL. wp_trash_post renames the slug with "__trashed" before firing
5443 - // this hook, so get_permalink() here would return the trashed URL and md5() would miss the
5444 - // real vector IDs stored under the original URL.
5445 - $source_url = $this->mxchat_resolve_pre_trash_url($post_id);
5451 + // Get the URL before post is deleted
5452 + $source_url = get_permalink($post_id);
5446 5453 if (!$source_url) {
5447 - //error_log('MXChat: Failed to resolve source URL for post ' . $post_id);
5454 + //error_log('MXChat: Failed to get permalink for post ' . $post_id);
5448 5455 return;
5449 5456 }
5450 5457
5451 5458 // Use chunk-aware deletion (handles both chunked and non-chunked content)
@@ -5453,36 +5460,56 @@
5453 5460
5454 5461 if (is_wp_error($delete_result)) {
5455 5462 //error_log('MXChat: Chunk-aware deletion failed for URL: ' . $source_url . ' - ' . $delete_result->get_error_message());
5456 5463 }
5464 +}
5457 5465
5458 - delete_transient('mxchat_prev_url_' . $post_id);
5459 - delete_transient('mxchat_prev_status_' . $post_id);
5460 -}
5461 5466
5462 -/**
5463 - * Resolve the source URL for a post being trashed/deleted.
5464 - *
5465 - * Why: wp_trash_post appends "__trashed" to the slug before the wp_trash_post action fires, so
5466 - * get_permalink() returns a URL whose md5() won't match the vector IDs stored in Pinecone or
5467 - * the source_url rows in the WP DB. Prefer the URL captured by mxchat_store_pre_update_status
5468 - * (runs on pre_post_update, before the rename); fall back to stripping the __trashed suffix.
5469 - */
5470 -private function mxchat_resolve_pre_trash_url($post_id) {
5471 - $previous_url = get_transient('mxchat_prev_url_' . $post_id);
5472 - if (!empty($previous_url)) {
5473 - return $previous_url;
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 5473
5476 - $current = get_permalink($post_id);
5477 - if (!$current) {
5478 - return '';
5479 - }
5480 - return preg_replace('#__trashed(/?)$#', '$1', $current);
5481 -}
5474 + if (empty($host) || empty($api_key)) {
5475 + //error_log('MXChat: Pinecone deletion failed - missing configuration');
5476 + return false;
5477 + }
5482 5478
5479 + $api_endpoint = "https://{$host}/vectors/delete";
5480 + $vector_id = md5($source_url);
5483 5481
5482 + $request_body = array(
5483 + 'ids' => array($vector_id)
5484 + );
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 +
5485 5512 public function mxchat_handle_product_change($post_id, $post, $update) {
5486 5513 if ($post->post_type !== 'product') {
5487 5514 return;
5488 5515 }
@@ -5634,18 +5661,28 @@
5634 5661 if (get_post_type($post_id) !== 'product') {
5635 5662 return;
5636 5663 }
5637 5664
5638 - $source_url = $this->mxchat_resolve_pre_trash_url($post_id);
5639 - if (!$source_url) {
5640 - return;
5641 - }
5665 + $source_url = get_permalink($post_id);
5642 5666
5643 - // Chunk-aware deletion (routes to Pinecone or WP DB and removes base + all chunks)
5644 - MxChat_Utils::delete_chunks_for_url($source_url, 'default');
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';
5645 5670
5646 - delete_transient('mxchat_prev_url_' . $post_id);
5647 - delete_transient('mxchat_prev_status_' . $post_id);
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 + }
5648 5685 }
5649 5686
5650 5687 /**
5651 5688 * Handle individual Pinecone content deletion