Changeset 3461963
- Timestamp:
- 02/15/2026 05:27:48 PM (6 weeks ago)
- Location:
- technodrome-ai-content-assistant/trunk
- Files:
-
- 5 edited
-
changelog.txt (modified) (1 diff)
-
dashboard/modules/history-tab/history.php (modified) (1 diff)
-
includes/class-ajax-handler.php (modified) (5 diffs)
-
readme.txt (modified) (2 diffs)
-
technodrome-ai-content-assistant.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
technodrome-ai-content-assistant/trunk/changelog.txt
r3446048 r3461963 1 1 # Changelog - Technodrome AI Content Assistant 2 3 ## Version 4.0.5 - 2026-02-15 4 5 ### CODE QUALITY IMPROVEMENTS 6 - **AJAX Handler Refactoring (DRY Principle):** Created centralized `sanitize_profile_data()` method to eliminate code duplication 7 - Replaced 3 duplicate code blocks with single method call 8 - Reduced ~100 lines of redundant code 9 - Improved maintainability and consistency 10 11 - **Removed Fake View Data:** Replaced simulated random view counts with "N/A" 12 - WordPress doesn't have built-in view counter (unlike Joomla) 13 - Fake data was misleading to users 14 - Now shows "N/A" when no analytics plugin tracks views 15 - Files affected: class-ajax-handler.php, history.php 16 17 --- 2 18 3 19 ## Version 4.0.3 - 2026-01-21 -
technodrome-ai-content-assistant/trunk/dashboard/modules/history-tab/history.php
r3401081 r3461963 68 68 $taics_word_count = str_word_count(wp_strip_all_tags($taics_content)); 69 69 70 // Get or simulateviews70 // Get views - show N/A if no analytics plugin tracks views 71 71 $taics_views = get_post_meta($taics_post_id, 'taics_views', true); 72 72 if (!$taics_views) { 73 $taics_views = wp_rand(50, 500); // Simulate views for demo 74 update_post_meta($taics_post_id, 'taics_views', $taics_views); 73 $taics_views = 'N/A'; 75 74 } 76 75 $taics_total_views += intval($taics_views); -
technodrome-ai-content-assistant/trunk/includes/class-ajax-handler.php
r3446048 r3461963 58 58 } 59 59 return self::$instance; 60 } 61 62 /** 63 * Sanitize profile data - handles API keys specially 64 * DRY principle: Centralized sanitization to avoid code duplication 65 * 66 * @since 4.0.5 67 * @param array $profile_data_raw Raw profile data from input 68 * @return array Sanitized profile data 69 */ 70 private static function sanitize_profile_data(array $profile_data_raw): array { 71 $profile_data = []; 72 73 foreach ($profile_data_raw as $key => $value) { 74 if ($key === 'ai_settings' && is_array($value)) { 75 // Handle ai_settings with special care for api_key 76 $ai_settings = []; 77 foreach ($value as $ai_key => $ai_value) { 78 if ($ai_key === 'api_key') { 79 // CRITICAL: Preserve API key exactly - do NOT sanitize 80 $ai_settings[$ai_key] = is_string($ai_value) ? $ai_value : ''; 81 } elseif (is_string($ai_value)) { 82 $ai_settings[$ai_key] = sanitize_text_field($ai_value); 83 } else { 84 $ai_settings[$ai_key] = $ai_value; 85 } 86 } 87 $profile_data[$key] = $ai_settings; 88 } elseif (is_string($value)) { 89 $profile_data[$key] = sanitize_text_field($value); 90 } elseif (is_array($value)) { 91 // Handle layout_template photos/videos specially to preserve URLs 92 if ($key === 'layout_template' && is_array($value)) { 93 $profile_data[$key] = []; 94 foreach ($value as $layout_key => $layout_value) { 95 if (($layout_key === 'photos' || $layout_key === 'videos') && is_array($layout_value)) { 96 // Preserve URLs and special characters in photos/videos 97 $profile_data[$key][$layout_key] = $layout_value; 98 } else { 99 $profile_data[$key][$layout_key] = is_string($layout_value) ? sanitize_text_field($layout_value) : $layout_value; 100 } 101 } 102 } else { 103 $profile_data[$key] = map_deep($value, 'sanitize_text_field'); 104 } 105 } else { 106 $profile_data[$key] = $value; 107 } 108 } 109 110 return $profile_data; 60 111 } 61 112 … … 342 393 $profile_data_raw = wp_unslash($_POST['profile_data']); 343 394 344 // CRITICAL FIX v3.3.1: Do NOT sanitize API keys with sanitize_text_field 345 // API keys contain special characters that are essential and get corrupted by sanitize_text_field 346 $profile_data = array(); 347 foreach ($profile_data_raw as $key => $value) { 348 if ($key === 'ai_settings' && is_array($value)) { 349 // Handle ai_settings array with special care for api_key 350 $ai_settings = array(); 351 foreach ($value as $ai_key => $ai_value) { 352 if ($ai_key === 'api_key') { 353 // CRITICAL: Do NOT sanitize API key - preserve it exactly as provided 354 $ai_settings[$ai_key] = is_string($ai_value) ? $ai_value : ''; 355 } elseif (is_string($ai_value)) { 356 $ai_settings[$ai_key] = sanitize_text_field($ai_value); 357 } else { 358 $ai_settings[$ai_key] = $ai_value; 359 } 360 } 361 $profile_data[$key] = $ai_settings; 362 } elseif (is_string($value)) { 363 $profile_data[$key] = sanitize_text_field($value); 364 } elseif (is_array($value)) { 365 $profile_data[$key] = map_deep($value, 'sanitize_text_field'); 366 } else { 367 $profile_data[$key] = $value; 368 } 369 } 395 // Use centralized sanitization method (v4.0.5 - DRY principle) 396 $profile_data = self::sanitize_profile_data($profile_data_raw); 370 397 371 398 $profile_name = isset($_POST['profile_name']) ? sanitize_text_field(wp_unslash($_POST['profile_name'])) : ''; … … 449 476 // CRITICAL FIX v3.3.1: Do NOT sanitize API keys 450 477 $profile_data = array(); 451 foreach ($profile_data_raw as $key => $value) { 452 if ($key === 'ai_settings' && is_array($value)) { 453 // Handle ai_settings with care for api_key 454 $ai_settings = array(); 455 foreach ($value as $ai_key => $ai_value) { 456 if ($ai_key === 'api_key') { 457 // CRITICAL: Preserve API key exactly 458 $ai_settings[$ai_key] = is_string($ai_value) ? $ai_value : ''; 459 } elseif (is_string($ai_value)) { 460 $ai_settings[$ai_key] = sanitize_text_field($ai_value); 461 } else { 462 $ai_settings[$ai_key] = $ai_value; 463 } 464 } 465 $profile_data[$key] = $ai_settings; 466 } elseif (is_string($value)) { 467 $profile_data[$key] = sanitize_text_field($value); 468 } elseif (is_array($value)) { 469 // Handle layout_template photos/videos specially to preserve URLs 470 if ($key === 'layout_template' && is_array($value)) { 471 $profile_data[$key] = array(); 472 foreach ($value as $layout_key => $layout_value) { 473 if (($layout_key === 'photos' || $layout_key === 'videos') && is_array($layout_value)) { 474 // Preserve URLs and special characters in photos/videos 475 $profile_data[$key][$layout_key] = $layout_value; 476 } else { 477 $profile_data[$key][$layout_key] = is_string($layout_value) ? sanitize_text_field($layout_value) : $layout_value; 478 } 479 } 480 } else { 481 $profile_data[$key] = map_deep($value, 'sanitize_text_field'); 482 } 483 } else { 484 $profile_data[$key] = $value; 485 } 486 } 478 // Use centralized sanitization method (v4.0.5 - DRY principle) 479 $profile_data = self::sanitize_profile_data($profile_data_raw); 487 480 488 481 // LICENSE CHECK: Temporarily disabled - methods not implemented yet … … 540 533 } 541 534 542 // CRITICAL FIX v3.3.1: Handle API keys specially - do NOT use map_deep with sanitize_text_field543 // API keys contain special characters that get corrupted544 $raw_profile_data = isset($_POST['profile_data']) ? map_deep(wp_unslash($_POST['profile_data']), 'sanitize_text_field') : array();545 if (!is_array($ raw_profile_data)) {535 // Use centralized sanitization method (v4.0.5 - DRY principle) 536 $profile_data_raw = wp_unslash($_POST['profile_data']); 537 538 if (!is_array($profile_data_raw)) { 546 539 wp_send_json_error(esc_html__('Invalid profile data format', 'technodrome-ai-content-assistant')); 547 540 exit; 548 541 } 549 542 550 $sanitized_profile_data = []; 551 foreach ($raw_profile_data as $key => $value) { 552 if ($key === 'ai_settings' && is_array($value)) { 553 // Handle ai_settings array with special care for api_key 554 $ai_settings = array(); 555 foreach ($value as $ai_key => $ai_value) { 556 if ($ai_key === 'api_key') { 557 // CRITICAL: Do NOT sanitize API key - preserve it exactly as provided 558 $ai_settings[$ai_key] = is_string($ai_value) ? $ai_value : ''; 559 } elseif (is_string($ai_value)) { 560 $ai_settings[$ai_key] = sanitize_text_field($ai_value); 561 } else { 562 $ai_settings[$ai_key] = $ai_value; 563 } 564 } 565 $sanitized_profile_data[$key] = $ai_settings; 566 } elseif (is_array($value)) { 567 $sanitized_profile_data[$key] = map_deep($value, 'sanitize_text_field'); 568 } elseif (is_string($value)) { 569 $sanitized_profile_data[$key] = sanitize_text_field($value); 570 } else { 571 $sanitized_profile_data[$key] = $value; 572 } 573 } 543 $sanitized_profile_data = self::sanitize_profile_data($profile_data_raw); 574 544 575 545 $user_id = get_current_user_id(); … … 1004 974 'date' => esc_html(get_the_date('M j, Y')), 1005 975 'word_count' => str_word_count(wp_strip_all_tags(get_the_content())), 1006 'views' => intval(get_post_meta($post_id, 'taics_views', true)) ?: wp_rand(100, 2000),976 'views' => intval(get_post_meta($post_id, 'taics_views', true)) ?: 'N/A', 1007 977 'status' => esc_html($status), 1008 978 'edit_link' => esc_url(get_edit_post_link($post_id)), -
technodrome-ai-content-assistant/trunk/readme.txt
r3446048 r3461963 5 5 Tested up to: 6.9 6 6 Requires PHP: 8.0 7 Stable tag: 4.0. 47 Stable tag: 4.0.5 8 8 License: GPL v2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 41 41 == Changelog == 42 42 43 = 4.0.5 (2026-01-21) = 43 = 4.0.5 (2026-02-15) = 44 * **CODE QUALITY**: AJAX Handler refactoring - Created centralized sanitize_profile_data() method (DRY principle) 45 * **CODE QUALITY**: Removed ~100 lines of duplicate code by reusing centralized method 46 * **IMPROVED**: Replaced fake random view counts with "N/A" (WordPress has no built-in view counter) 44 47 * **FIX**: Structure Name no longer resets to "PROFILE" when switching profiles 45 48 * **FIX**: Custom profile names persist correctly without being overwritten -
technodrome-ai-content-assistant/trunk/technodrome-ai-content-assistant.php
r3446048 r3461963 4 4 * Plugin URI: https://technodrome.org/ai-content-assistant 5 5 * Description: Advanced AI content generation plugin with multiple AI providers, profile system, layout templates, and content rules for WordPress. 6 * Version: 4.0. 46 * Version: 4.0.5 7 7 * Author: Technodrome Team 8 8 * Author URI: https://technodrome.org … … 30 30 31 31 // Plugin constants 32 define('TAICS_VERSION', '4.0. 4');32 define('TAICS_VERSION', '4.0.5'); 33 33 define('TAICS_PLUGIN_FILE', __FILE__); 34 34 define('TAICS_PLUGIN_DIR', plugin_dir_path(__FILE__));
Note: See TracChangeset
for help on using the changeset viewer.