Changeset 3385425
- Timestamp:
- 10/27/2025 07:23:53 PM (5 months ago)
- Location:
- ai-search
- Files:
-
- 5 added
- 3 edited
-
tags/1.8.0 (added)
-
tags/1.8.0/ai-search.php (added)
-
tags/1.8.0/includes (added)
-
tags/1.8.0/includes/class-ai-search-service.php (added)
-
tags/1.8.0/readme.txt (added)
-
trunk/ai-search.php (modified) (9 diffs)
-
trunk/includes/class-ai-search-service.php (modified) (1 diff)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
ai-search/trunk/ai-search.php
r3384072 r3385425 3 3 * Plugin Name: AI Search 4 4 * Description: Replaces the default search with an intelligent search system. 5 * Version: 1. 7.15 * Version: 1.8.0 6 6 * Author: samuelsilvapt 7 7 * License: GPL2 … … 26 26 * Plugin version. 27 27 */ 28 const VERSION = '1. 7.0';28 const VERSION = '1.8.0'; 29 29 30 30 /** … … 75 75 add_action( 'admin_post_ai_search_generate_embeddings', [ $this, 'generate_selected_embeddings' ] ); 76 76 add_action( 'admin_post_ai_search_clear_cache', [ $this, 'clear_embeddings_cache' ] ); 77 add_action( 'admin_post_ai_search_validate_token', [ $this, 'validate_service_token' ] ); 78 add_action( 'wp_ajax_ai_search_validate_token', [ $this, 'validate_service_token' ] ); 77 79 78 80 } … … 393 395 394 396 /** 397 * Validate the service token via admin action. 398 * @return void 399 */ 400 public function validate_service_token() { 401 if ( ! current_user_can( 'manage_options' ) ) { 402 wp_die( __( 'Unauthorized access', 'ai-search' ) ); 403 } 404 405 check_admin_referer( 'ai_search_validate_token' ); 406 407 // Check if token exists first 408 $service_token = get_option( 'ai_search_service_token', '' ); 409 if ( empty( $service_token ) ) { 410 wp_redirect( admin_url( 'options-general.php?page=ai-search&token_validation=no_token&tab=general' ) ); 411 exit; 412 } 413 414 $validation_result = $this->service_client->validate_token(); 415 416 if ( $validation_result === false ) { 417 wp_redirect( admin_url( 'options-general.php?page=ai-search&token_validation=error&tab=general' ) ); 418 } elseif ( isset( $validation_result['valid'] ) && $validation_result['valid'] === true ) { 419 // Store validation data in transient for display 420 set_transient( 'ai_search_validation_data', $validation_result, 300 ); // 5 minutes 421 wp_redirect( admin_url( 'options-general.php?page=ai-search&token_validation=success&tab=general' ) ); 422 } else { 423 // Invalid token 424 set_transient( 'ai_search_validation_error', $validation_result, 300 ); // 5 minutes 425 wp_redirect( admin_url( 'options-general.php?page=ai-search&token_validation=invalid&tab=general' ) ); 426 } 427 428 exit; 429 } 430 431 /** 395 432 * Clear embedding transients from WordPress cache. 396 433 * @return int Number of transients cleared. … … 472 509 */ 473 510 private function general_settings_page() { 511 // Handle token validation messages 512 if ( isset( $_GET['token_validation'] ) ) { 513 $validation_status = sanitize_text_field( $_GET['token_validation'] ); 514 515 if ( $validation_status === 'success' ) { 516 $validation_data = get_transient( 'ai_search_validation_data' ); 517 if ( $validation_data ) { 518 echo '<div class="updated"><p><strong>Token Validation Successful!</strong></p>'; 519 if ( isset( $validation_data['client'] ) ) { 520 $client = $validation_data['client']; 521 echo '<ul style="margin-left: 20px;">'; 522 echo '<li><strong>Client ID:</strong> ' . esc_html( $client['id'] ?? 'N/A' ) . '</li>'; 523 echo '<li><strong>Origin:</strong> ' . esc_html( $client['origin'] ?? 'N/A' ) . '</li>'; 524 echo '<li><strong>Daily Limit:</strong> ' . esc_html( number_format( $client['daily_limit'] ?? 0 ) ) . '</li>'; 525 echo '<li><strong>Total Limit:</strong> ' . esc_html( number_format( $client['total_limit'] ?? 0 ) ) . '</li>'; 526 echo '<li><strong>Used Daily:</strong> ' . esc_html( number_format( $client['used_daily'] ?? 0 ) ) . '</li>'; 527 echo '<li><strong>Used Total:</strong> ' . esc_html( number_format( $client['used_total'] ?? 0 ) ) . '</li>'; 528 echo '<li><strong>Quotas Exceeded:</strong> ' . ( 529 isset( $client['quotas_exceeded']['daily'] ) && $client['quotas_exceeded']['daily'] ? 'Daily' : '' 530 ) . ( 531 isset( $client['quotas_exceeded']['total'] ) && $client['quotas_exceeded']['total'] ? ' Total' : '' 532 ) . ( 533 !( $client['quotas_exceeded']['daily'] ?? false ) && !( $client['quotas_exceeded']['total'] ?? false ) ? 'None' : '' 534 ) . '</li>'; 535 echo '</ul>'; 536 } 537 echo '</div>'; 538 delete_transient( 'ai_search_validation_data' ); 539 } 540 } elseif ( $validation_status === 'invalid' ) { 541 $error_data = get_transient( 'ai_search_validation_error' ); 542 echo '<div class="error"><p><strong>Token Validation Failed!</strong></p>'; 543 if ( $error_data && isset( $error_data['details'] ) ) { 544 echo '<p>Error: ' . esc_html( $error_data['details'] ) . '</p>'; 545 } 546 echo '</div>'; 547 delete_transient( 'ai_search_validation_error' ); 548 } elseif ( $validation_status === 'error' ) { 549 echo '<div class="error"><p><strong>Token Validation Error!</strong> Unable to connect to AI Search Service.</p></div>'; 550 } elseif ( $validation_status === 'no_token' ) { 551 echo '<div class="error"><p><strong>No Token Found!</strong> Please save your settings first to generate a service token.</p></div>'; 552 } 553 } 554 474 555 if ( isset( $_POST['provider'], $_POST['api_key'], $_POST['similarity_threshold'] ) ) { 475 556 check_admin_referer( 'ai_search_save_settings' ); … … 483 564 update_option( 'ai_search_similarity_threshold', floatval( $_POST['similarity_threshold'] ) ); 484 565 566 // Save service token if provided 567 if ( isset( $_POST['service_token'] ) ) { 568 update_option( 'ai_search_service_token', sanitize_text_field( wp_unslash( $_POST['service_token'] ) ) ); 569 } 570 485 571 // Handle AI service registration 486 572 $registration_result = $this->handle_ai_service_registration( $new_provider ); … … 497 583 $provider = get_option( 'ai_search_provider', $this->api_key ? 'openai' : 'ai_service' ); 498 584 $api_key = get_option( 'ai_search_api_key', '' ); 585 $service_token = get_option( 'ai_search_service_token', '' ); 499 586 $similarity_threshold = get_option( 'ai_search_similarity_threshold', 0.5 ); 500 587 … … 516 603 echo '</div>'; 517 604 605 echo '<div id="service-token-container" style="display: ' . ( $provider === 'ai_service' ? 'block' : 'none' ) . ';">'; 606 echo '<label for="service_token">AI Search Service Token:</label><br>'; 607 echo '<input type="text" id="service_token" name="service_token" value="' . esc_attr( $service_token ) . '" style="width: 100%; max-width: 400px;" />'; 608 echo '<p><em>This token is automatically generated when you select the AI Service. You can manually update it if needed.</em></p>'; 609 610 // Add validation button if token exists 611 if ( ! empty( $service_token ) ) { 612 echo '<div style="margin-top: 10px;">'; 613 echo '<button type="button" id="validate-token-btn" class="button button-secondary">Validate Token</button>'; 614 echo '<span id="validation-spinner" style="display: none; margin-left: 10px;">Validating...</span>'; 615 echo '<p><em>Click to validate your token and check usage statistics.</em></p>'; 616 echo '</div>'; 617 } 618 619 echo '</div>'; 620 518 621 echo '<br/><br/>'; 519 622 … … 531 634 var provider = document.getElementById("provider").value; 532 635 document.getElementById("openai-key-container").style.display = (provider === "openai") ? "block" : "none"; 533 } 636 document.getElementById("service-token-container").style.display = (provider === "ai_service") ? "block" : "none"; 637 } 638 639 document.addEventListener("DOMContentLoaded", function() { 640 var validateBtn = document.getElementById("validate-token-btn"); 641 if (validateBtn) { 642 validateBtn.addEventListener("click", function() { 643 var spinner = document.getElementById("validation-spinner"); 644 validateBtn.disabled = true; 645 spinner.style.display = "inline"; 646 647 // Create a form and submit it 648 var form = document.createElement("form"); 649 form.method = "POST"; 650 form.action = "' . esc_url( admin_url( 'admin-post.php?action=ai_search_validate_token' ) ) . '"; 651 652 var nonceField = document.createElement("input"); 653 nonceField.type = "hidden"; 654 nonceField.name = "_wpnonce"; 655 nonceField.value = "' . wp_create_nonce( 'ai_search_validate_token' ) . '"; 656 657 form.appendChild(nonceField); 658 document.body.appendChild(form); 659 form.submit(); 660 }); 661 } 662 }); 534 663 </script>'; 535 664 } -
ai-search/trunk/includes/class-ai-search-service.php
r3384072 r3385425 81 81 return false; 82 82 } 83 84 /** 85 * Validate the current service token. 86 * 87 * @return array|false Validation result or false on failure 88 */ 89 public function validate_token() { 90 $service_token = get_option( 'ai_search_service_token' ); 91 if ( empty( $service_token ) ) { 92 return false; 93 } 94 95 $response = wp_remote_post( $this->service_url . 'clients/validate', [ 96 'headers' => [ 97 'Origin' => get_site_url(), 98 'Content-Type' => 'application/json', 99 ], 100 'body' => wp_json_encode([ 101 'token' => $service_token, 102 'origin' => get_site_url() 103 ]), 104 'timeout' => 20, 105 ]); 106 107 if ( is_wp_error( $response ) ) { 108 // Log the error for debugging 109 error_log( 'AI Search Token Validation Error: ' . $response->get_error_message() ); 110 return false; 111 } 112 113 $status_code = wp_remote_retrieve_response_code( $response ); 114 $body = json_decode( wp_remote_retrieve_body( $response ), true ); 115 116 // Log the response for debugging 117 error_log( 'AI Search Token Validation Response: ' . wp_remote_retrieve_body( $response ) ); 118 119 return $body; 120 } 83 121 } -
ai-search/trunk/readme.txt
r3384072 r3385425 3 3 Tags: search, AI, OpenAI, WordPress 4 4 Tested up to: 6.8 5 Stable tag: 1. 7.15 Stable tag: 1.8.0 6 6 Requires PHP: 8.0 7 7 License: GPLv2 … … 66 66 == Changelog == 67 67 68 = 1.8.0 = 69 - **Service Token Management**: Added manual service token field in General Settings for better control and transparency 70 - **Token Validation System**: New "Validate Token" button with real-time validation and detailed usage statistics 71 - **Enhanced Admin Interface**: Service token field automatically shows/hides based on provider selection 72 - **Comprehensive Validation Results**: Displays client ID, origin, daily/total limits, current usage, and quota status 73 - **Improved Error Handling**: Better error messages for token validation failures and connection issues 74 - **User Experience Improvements**: Loading spinner, button states, and clearer user guidance 75 - **Debugging Enhancements**: Added error logging for better troubleshooting and API response monitoring 76 68 77 = 1.7.0 = 69 78 - Major Performance & UX Improvements
Note: See TracChangeset
for help on using the changeset viewer.