| @@ -63,25 +63,8 @@ | ||
| 63 | 63 | return false; |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | 66 | /** |
| 67 | - * Whether a URL's crawl pipeline has completed, per the bounded | |
| 68 | - * Metasync_Otto_Job_Status store. Replaces the legacy unbounded | |
| 69 | - * metasync_otto_crawldata option lookup: state history is pruned | |
| 70 | - * 48 hours after completion, so a URL finished longer ago reads as | |
| 71 | - * "not crawled" here without implying Otto never touched it. | |
| 72 | - */ | |
| 73 | - private static function is_url_crawled($url) { | |
| 74 | - if (!class_exists('Metasync_Otto_Job_Status')) { | |
| 75 | - return false; | |
| 76 | - } | |
| 77 | - $entry = Metasync_Otto_Job_Status::get($url); | |
| 78 | - return is_array($entry) | |
| 79 | - && isset($entry['state']) | |
| 80 | - && $entry['state'] === Metasync_Otto_Job_Status::STATE_COMPLETED; | |
| 81 | - } | |
| 82 | - | |
| 83 | - /** | |
| 84 | 67 | * Add debug menu (internal only - hidden on customer production sites) |
| 85 | 68 | */ |
| 86 | 69 | public function add_debug_menu() { |
| 87 | 70 | if (!current_user_can('manage_options') || !self::is_debug_tools_enabled()) { |
| @@ -119,8 +102,9 @@ | ||
| 119 | 102 | <?php $this->render_url_testing_section(); ?> |
| 120 | 103 | <?php $this->render_configuration_status(); ?> |
| 121 | 104 | <?php $this->render_notification_endpoint_status(); ?> |
| 122 | 105 | <?php $this->render_api_connectivity_status(); ?> |
| 106 | + <?php $this->render_crawl_data_status(); ?> | |
| 123 | 107 | <?php $this->render_processing_status(); ?> |
| 124 | 108 | <?php $this->render_debug_tools(); ?> |
| 125 | 109 | </div> |
| 126 | 110 | </div> |
| @@ -258,14 +242,14 @@ | ||
| 258 | 242 | </div> |
| 259 | 243 | |
| 260 | 244 | <div class="debug-item info"> |
| 261 | 245 | <strong>Current User:</strong> |
| 262 | - <span class="debug-value"><?php echo esc_html($current_user->user_login); ?> (ID: <?php echo (int) $current_user->ID; ?>)</span> | |
| 246 | + <span class="debug-value"><?php echo esc_html($current_user->user_login); ?> (ID: <?php echo $current_user->ID; ?>)</span> | |
| 263 | 247 | </div> |
| 264 | 248 | |
| 265 | 249 | <div class="debug-item info"> |
| 266 | 250 | <strong>User Roles:</strong> |
| 267 | - <span class="debug-value"><?php echo esc_html(implode(', ', $current_user->roles)); ?></span> | |
| 251 | + <span class="debug-value"><?php echo implode(', ', $current_user->roles); ?></span> | |
| 268 | 252 | </div> |
| 269 | 253 | |
| 270 | 254 | <div class="debug-item success"> |
| 271 | 255 | <strong>Debug Access Active</strong> |
| @@ -361,9 +345,9 @@ | ||
| 361 | 345 | </div> |
| 362 | 346 | |
| 363 | 347 | <div class="debug-item info"> |
| 364 | 348 | <strong>Plugin Version:</strong> |
| 365 | - <span class="debug-value"><?php echo esc_html(defined('METASYNC_VERSION') ? METASYNC_VERSION : 'Unknown'); ?></span> | |
| 349 | + <span class="debug-value"><?php echo defined('METASYNC_VERSION') ? METASYNC_VERSION : 'Unknown'; ?></span> | |
| 366 | 350 | </div> |
| 367 | 351 | </div> |
| 368 | 352 | <?php |
| 369 | 353 | } |
| @@ -465,13 +449,64 @@ | ||
| 465 | 449 | <?php |
| 466 | 450 | } |
| 467 | 451 | |
| 468 | 452 | /** |
| 453 | + * Render crawl data status | |
| 454 | + */ | |
| 455 | + private function render_crawl_data_status() { | |
| 456 | + $crawl_data = get_option('metasync_otto_crawldata'); | |
| 457 | + | |
| 458 | + ?> | |
| 459 | + <div class="debug-section"> | |
| 460 | + <h3><span class="status-indicator <?php echo !empty($crawl_data) ? 'status-success' : 'status-warning'; ?>"></span>Crawl Data Status</h3> | |
| 461 | + | |
| 462 | + <div class="debug-item <?php echo !empty($crawl_data) ? 'success' : 'warning'; ?>"> | |
| 463 | + <strong>Crawl Data Available:</strong> | |
| 464 | + <span class="debug-value"><?php echo !empty($crawl_data) ? 'Yes' : 'No'; ?></span> | |
| 465 | + </div> | |
| 466 | + | |
| 467 | + <?php if (!empty($crawl_data)): ?> | |
| 468 | + <div class="debug-item info"> | |
| 469 | + <strong>Domain:</strong> | |
| 470 | + <span class="debug-value"><?php echo esc_html($crawl_data['domain'] ?? 'Not Set'); ?></span> | |
| 471 | + </div> | |
| 472 | + | |
| 473 | + <div class="debug-item info"> | |
| 474 | + <strong>Total URLs Crawled:</strong> | |
| 475 | + <span class="debug-value"><?php echo count($crawl_data['urls'] ?? []); ?></span> | |
| 476 | + </div> | |
| 477 | + | |
| 478 | + <div class="debug-item info"> | |
| 479 | + <strong>Last Updated:</strong> | |
| 480 | + <span class="debug-value"><?php echo $this->get_option_last_updated('metasync_otto_crawldata'); ?></span> | |
| 481 | + </div> | |
| 482 | + | |
| 483 | + <div class="debug-item info"> | |
| 484 | + <strong>Sample URLs:</strong> | |
| 485 | + <div class="debug-value"> | |
| 486 | + <?php | |
| 487 | + $sample_urls = array_slice($crawl_data['urls'] ?? [], 0, 5); | |
| 488 | + foreach ($sample_urls as $url) { | |
| 489 | + echo esc_html($url) . '<br>'; | |
| 490 | + } | |
| 491 | + if (count($crawl_data['urls'] ?? []) > 5) { | |
| 492 | + echo '... and ' . (count($crawl_data['urls']) - 5) . ' more'; | |
| 493 | + } | |
| 494 | + ?> | |
| 495 | + </div> | |
| 496 | + </div> | |
| 497 | + <?php endif; ?> | |
| 498 | + </div> | |
| 499 | + <?php | |
| 500 | + } | |
| 501 | + | |
| 502 | + /** | |
| 469 | 503 | * Render processing status |
| 470 | 504 | */ |
| 471 | 505 | private function render_processing_status() { |
| 472 | 506 | $current_url = $this->get_current_url(); |
| 473 | - $is_crawled = self::is_url_crawled($current_url); | |
| 507 | + $otto_pixel = new Metasync_otto_pixel(Metasync::get_option('general')['otto_pixel_uuid'] ?? ''); | |
| 508 | + $is_crawled = $otto_pixel->is_url_crawled($current_url); | |
| 474 | 509 | $render_diagnostics = $this->get_render_strategy_diagnostics(); |
| 475 | 510 | |
| 476 | 511 | ?> |
| 477 | 512 | <div class="debug-section"> |
| @@ -493,19 +528,19 @@ | ||
| 493 | 528 | </div> |
| 494 | 529 | |
| 495 | 530 | <div class="debug-item info"> |
| 496 | 531 | <strong>Page Type:</strong> |
| 497 | - <span class="debug-value"><?php echo esc_html($this->get_page_type()); ?></span> | |
| 532 | + <span class="debug-value"><?php echo $this->get_page_type(); ?></span> | |
| 498 | 533 | </div> |
| 499 | 534 | |
| 500 | 535 | <div class="debug-item info"> |
| 501 | 536 | <strong>Cache Status:</strong> |
| 502 | - <span class="debug-value"><?php echo esc_html($this->get_cache_status()); ?></span> | |
| 537 | + <span class="debug-value"><?php echo $this->get_cache_status(); ?></span> | |
| 503 | 538 | </div> |
| 504 | 539 | |
| 505 | 540 | <div class="debug-item info"> |
| 506 | 541 | <strong>Processing Method:</strong> |
| 507 | - <span class="debug-value"><?php echo esc_html($this->get_processing_method()); ?></span> | |
| 542 | + <span class="debug-value"><?php echo $this->get_processing_method(); ?></span> | |
| 508 | 543 | </div> |
| 509 | 544 | |
| 510 | 545 | <?php if (!empty($render_diagnostics) && isset($render_diagnostics['available']) === false): ?> |
| 511 | 546 | <div class="debug-item info"> |
| @@ -617,8 +652,29 @@ | ||
| 617 | 652 | return !is_wp_error($response) && wp_remote_retrieve_response_code($response) === 200; |
| 618 | 653 | } |
| 619 | 654 | |
| 620 | 655 | /** |
| 656 | + * Get option last updated time | |
| 657 | + */ | |
| 658 | + private function get_option_last_updated($option_name) { | |
| 659 | + global $wpdb; | |
| 660 | + | |
| 661 | + $result = $wpdb->get_var($wpdb->prepare( // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- admin debug tool — scratch diagnostics storage outside any WordPress API | |
| 662 | + "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s", | |
| 663 | + $option_name | |
| 664 | + )); | |
| 665 | + | |
| 666 | + if ($result) { | |
| 667 | + $data = maybe_unserialize($result); | |
| 668 | + if (isset($data['last_updated'])) { | |
| 669 | + return gmdate('Y-m-d H:i:s', $data['last_updated']); | |
| 670 | + } | |
| 671 | + } | |
| 672 | + | |
| 673 | + return 'Unknown'; | |
| 674 | + } | |
| 675 | + | |
| 676 | + /** | |
| 621 | 677 | * Get current URL |
| 622 | 678 | */ |
| 623 | 679 | private function get_current_url() { |
| 624 | 680 | $scheme = is_ssl() ? 'https' : 'http'; |
| @@ -816,23 +872,20 @@ | ||
| 816 | 872 | * AJAX handler for clearing OTTO cache |
| 817 | 873 | */ |
| 818 | 874 | public function ajax_clear_otto_cache() { |
| 819 | 875 | check_ajax_referer('metasync_otto_debug', 'nonce'); |
| 820 | - | |
| 876 | + | |
| 821 | 877 | if (!current_user_can('manage_options') || !self::is_debug_tools_enabled()) { |
| 822 | 878 | wp_die('Unauthorized'); |
| 823 | 879 | } |
| 824 | - | |
| 825 | - // Clear the retired crawl-data option if an internal debug tool is | |
| 826 | - // ever re-enabled. This explicit action is harmless and preserves | |
| 827 | - // the old clear-cache contract; production never reaches this | |
| 828 | - // handler because debug tools are hard-disabled. | |
| 880 | + | |
| 881 | + // Clear crawl data | |
| 829 | 882 | delete_option('metasync_otto_crawldata'); |
| 830 | - | |
| 883 | + | |
| 831 | 884 | // Clear any cached API responses |
| 832 | 885 | $general_options = Metasync::get_option('general'); |
| 833 | 886 | $otto_uuid = $general_options['otto_pixel_uuid'] ?? ''; |
| 834 | - | |
| 887 | + | |
| 835 | 888 | if (!empty($otto_uuid)) { |
| 836 | 889 | delete_transient(Metasync_Heartbeat_Manager::public_hash_cache_key($otto_uuid)); |
| 837 | 890 | } |
| 838 | 891 | |
| @@ -1032,27 +1085,27 @@ | ||
| 1032 | 1085 | /** |
| 1033 | 1086 | * Test crawl status for URL |
| 1034 | 1087 | */ |
| 1035 | 1088 | private function test_crawl_status($url) { |
| 1036 | - if (class_exists('Metasync_Otto_Job_Status')) { | |
| 1037 | - $entry = Metasync_Otto_Job_Status::get($url); | |
| 1038 | - $is_crawled = is_array($entry) | |
| 1039 | - && isset($entry['state']) | |
| 1040 | - && $entry['state'] === Metasync_Otto_Job_Status::STATE_COMPLETED; | |
| 1041 | - | |
| 1089 | + if (class_exists('Metasync_otto_pixel')) { | |
| 1090 | + $otto_pixel = new Metasync_otto_pixel(false); | |
| 1091 | + $is_crawled = $otto_pixel->is_url_crawled($url); | |
| 1092 | + | |
| 1093 | + // Get crawl data from options | |
| 1094 | + $crawl_data = get_option('metasync_otto_crawldata'); | |
| 1095 | + | |
| 1042 | 1096 | return array( |
| 1043 | 1097 | 'status' => 'success', |
| 1044 | 1098 | 'is_crawled' => $is_crawled, |
| 1045 | - 'job_state' => is_array($entry) && isset($entry['state']) ? $entry['state'] : 'unknown', | |
| 1046 | - 'job_stage' => is_array($entry) && isset($entry['stage']) ? $entry['stage'] : '', | |
| 1047 | - 'job_attempts' => is_array($entry) && isset($entry['attempts']) ? (int) $entry['attempts'] : 0, | |
| 1048 | - 'job_updated' => is_array($entry) && isset($entry['updated']) ? $entry['updated'] : null | |
| 1099 | + 'crawl_data' => $crawl_data, | |
| 1100 | + 'total_crawled_urls' => count($crawl_data['urls'] ?? array()), | |
| 1101 | + 'domain' => $crawl_data['domain'] ?? 'Not set' | |
| 1049 | 1102 | ); |
| 1050 | 1103 | } |
| 1051 | - | |
| 1104 | + | |
| 1052 | 1105 | return array( |
| 1053 | 1106 | 'status' => 'error', |
| 1054 | - 'message' => Metasync::get_whitelabel_otto_name() . ' job status class not available' | |
| 1107 | + 'message' => Metasync::get_whitelabel_otto_name() . ' pixel class not available' | |
| 1055 | 1108 | ); |
| 1056 | 1109 | } |
| 1057 | 1110 | |
| 1058 | 1111 | /** |