plugin_name = $plugin_name; $this->version = $version; // Add admin menu add_action('admin_menu', array($this, 'add_debug_menu')); // Add magic word handler add_action('admin_init', array($this, 'handle_magic_word_access')); // Add AJAX handlers add_action('wp_ajax_metasync_otto_debug_test_api', array($this, 'ajax_test_otto_api')); add_action('wp_ajax_metasync_otto_debug_test_notification', array($this, 'ajax_test_notification_endpoint')); add_action('wp_ajax_metasync_otto_debug_clear_cache', array($this, 'ajax_clear_otto_cache')); add_action('wp_ajax_metasync_otto_debug_simulate_crawl', array($this, 'ajax_simulate_crawl_notification')); add_action('wp_ajax_metasync_otto_debug_test_url', array($this, 'ajax_test_specific_url')); add_action('wp_ajax_metasync_otto_debug_emulate_changes', array($this, 'ajax_emulate_otto_changes')); add_action('wp_ajax_metasync_otto_debug_simple_test', array($this, 'ajax_simple_test')); add_action('wp_ajax_metasync_otto_debug_test_db_permissions', array($this, 'ajax_test_db_permissions')); } /** * Add debug menu (developer only - hidden by default) */ public function add_debug_menu() { // Check if user has developer capabilities if (!Metasync::current_user_has_plugin_access()) { return; } // Check if debug access is enabled via magic word if (!$this->is_debug_access_enabled()) { return; } $menu_slug = Metasync_Admin::$page_slug; add_submenu_page( $menu_slug, Metasync::get_whitelabel_otto_name() . ' Debug', Metasync::get_whitelabel_otto_name() . ' Debug', 'manage_options', $menu_slug . '-otto-debug', array($this, 'create_debug_page') ); } /** * Add magic word handler for direct access */ public function handle_magic_word_access() { // Check if magic word is provided if (isset($_GET['metasync_debug']) && $_GET['metasync_debug'] === 'abracadabra@2020') { // Enable debug access via user meta (persistent, no sessions needed) $current_user = wp_get_current_user(); if ($current_user && $current_user->ID) { update_user_meta($current_user->ID, 'metasync_debug_enabled', 'true'); } // Redirect to admin with debug access enabled $redirect_url = admin_url('admin.php?page=' . Metasync_Admin::$page_slug . '-otto-debug'); wp_redirect($redirect_url); exit; } } /** * Check if debug access is enabled via magic word system * Hidden from regular users, only accessible with secret key */ private function is_debug_access_enabled() { // Magic word for developer access $magic_word = 'abracadabra@2020'; // Check if magic word is provided in URL parameter if (isset($_GET['metasync_debug']) && $_GET['metasync_debug'] === $magic_word) { // Enable debug access via user meta (persistent, no sessions needed) $current_user = wp_get_current_user(); if ($current_user && $current_user->ID) { update_user_meta($current_user->ID, 'metasync_debug_enabled', 'true'); } return true; } // Check if debug access is enabled via user meta (for persistent access) $current_user = wp_get_current_user(); if ($current_user && $current_user->ID) { $debug_enabled = get_user_meta($current_user->ID, 'metasync_debug_enabled', true); if ($debug_enabled === 'true') { return true; } } return false; } /** * Check if current user is a developer * Multiple methods to identify developers without requiring WP_DEBUG */ private function is_developer_user($user) { // Method 1: Check for specific user meta $is_developer = get_user_meta($user->ID, 'metasync_developer', true); if ($is_developer === 'true') { return true; } // Method 2: Check for specific user roles $developer_roles = array('administrator', 'developer', 'super_admin'); $user_roles = $user->roles; foreach ($developer_roles as $role) { if (in_array($role, $user_roles)) { return true; } } // Method 3: Check for specific capabilities if ($user->has_cap('manage_options') && $user->has_cap('edit_plugins')) { return true; } // Method 4: Check for specific email domains (optional) $email_domain = substr(strrchr($user->user_email, "@"), 1); $developer_domains = array('searchatlas.com', 'yourcompany.com'); // Add your company domains if (in_array($email_domain, $developer_domains)) { return true; } // Method 5: Check for specific username patterns $username_patterns = array('/^dev_/', '/^admin_/', '/^support_/'); foreach ($username_patterns as $pattern) { if (preg_match($pattern, $user->user_login)) { return true; } } return false; } /** * Helper function to enable developer access for a specific user * Call this function to grant debug access to a user * * Usage: Metasync_Otto_Debug::enable_developer_access($user_id); */ public static function enable_developer_access($user_id) { update_user_meta($user_id, 'metasync_debug_enabled', 'true'); } /** * Helper function to disable developer access for a specific user * * Usage: Metasync_Otto_Debug::disable_developer_access($user_id); */ public static function disable_developer_access($user_id) { delete_user_meta($user_id, 'metasync_debug_enabled'); } /** * Get the magic word for debug access * * Usage: Metasync_Otto_Debug::get_magic_word(); */ public static function get_magic_word() { return 'abracadabra@2020'; } /** * Generate debug access URL * * Usage: Metasync_Otto_Debug::get_debug_access_url(); */ public static function get_debug_access_url() { $admin_url = admin_url('admin.php'); $magic_word = self::get_magic_word(); return add_query_arg('metasync_debug', $magic_word, $admin_url); } /** * Quick enable debug access for current user * * Usage: Metasync_Otto_Debug::quick_enable_debug(); */ public static function quick_enable_debug() { $current_user = wp_get_current_user(); if ($current_user && $current_user->ID) { update_user_meta($current_user->ID, 'metasync_debug_enabled', 'true'); return true; } return false; } /** * Create the debug page */ public function create_debug_page() { // Check if this is a magic word access request if (isset($_GET['metasync_debug']) && $_GET['metasync_debug'] === 'abracadabra@2020') { // Enable debug access via user meta (persistent, no sessions needed) $current_user = wp_get_current_user(); if ($current_user && $current_user->ID) { update_user_meta($current_user->ID, 'metasync_debug_enabled', 'true'); } // Show access granted message $this->show_access_granted_page(); return; } $whitelabel_otto_name = Metasync::get_whitelabel_otto_name(); ?>

Debug & Diagnostics

Comprehensive diagnostics for functionality. This page helps identify why changes may not be applied.

render_developer_access_status(); ?> render_url_testing_section(); ?> render_configuration_status(); ?> render_notification_endpoint_status(); ?> render_api_connectivity_status(); ?> render_crawl_data_status(); ?> render_processing_status(); ?> render_debug_tools(); ?>

Debug Access Granted

Debug Access Enabled!

You now have access to the Debug page.

Next Steps

  1. Access Debug Page: The " Debug" menu should now be visible in the MetaSync plugin menu
  2. Use Diagnostics: Click on " Debug" to access comprehensive diagnostic tools
  3. Troubleshoot Issues: Use the debug tools to identify why changes may not be applied

Access Information

Magic Word abracadabra@2020
Current User user_login); ?> (ID: ID; ?>)
Access Type User Meta (persistent)
Debug Page URL

Security Notes

Quick Access

To access the debug page directly, use this URL:

Open Debug Page

Or add the magic word to any WordPress admin URL:

?metasync_debug=abracadabra@2020

is_debug_access_enabled(); $debug_meta = get_user_meta($current_user->ID, 'metasync_debug_enabled', true); ?>

Developer Access Status

Debug Access:
Current User: user_login); ?> (ID: ID; ?>)
User Roles: roles); ?>
Email Domain: user_email, "@"), 1)); ?>
Debug Meta:
Enable Debug Access:

Method 1 - Magic Word (Recommended):

Add this parameter to any WordPress admin URL:

?metasync_debug=abracadabra@2020

Example:

Method 2 - User Meta:

Run this code in WordPress:

Metasync_Otto_Debug::enable_developer_access(ID; ?>);

Method 3 - WordPress CLI:

wp user meta update ID; ?> metasync_debug_enabled true
Debug Access Active

You have access to all debug tools and diagnostics.

Magic Word: abracadabra@2020

Access URL:

URL Testing & Emulation

Test Specific URL:

Enter any URL from your site to test functionality and check all diagnostic points.



What This Tests:
Database Permissions Check:

Testing if Action Scheduler can schedule jobs...

Configuration Status

SSR Enabled: Yes (Always Active)
UUID:
Disable for Logged-in Users:
Current User Logged In:
Plugin Version:

Notification Endpoint Status

REST API Base URL:
Notification Endpoint:
REST API Available:
Endpoint Registered: is_rest_endpoint_registered() ? 'Yes' : 'No'; ?>
Expected Method: POST
Expected JSON Fields: domain, urls
get_site_url(), 'uuid' => $otto_uuid ), $api_url); ?>

API Connectivity Status

API Endpoint:
Test URL:
API Reachable: can_reach_otto_api() ? 'Yes' : 'No'; ?>
SSL Verification: Enabled
Timeout: 30 seconds
User Agent: MetaSync-WordPress-Plugin/1.0

Crawl Data Status

Crawl Data Available:
Domain:
Total URLs Crawled:
Last Updated: get_option_last_updated('metasync_otto_crawldata'); ?>
Sample URLs:
'; } if (count($crawl_data['urls'] ?? []) > 5) { echo '... and ' . (count($crawl_data['urls']) - 5) . ' more'; } ?>
get_current_url(); $otto_pixel = new Metasync_otto_pixel(Metasync::get_option('general')['otto_pixel_uuid'] ?? ''); $is_crawled = $otto_pixel->is_url_crawled($current_url); $render_diagnostics = $this->get_render_strategy_diagnostics(); ?>

Processing Status

Current URL:
URL Crawled by :
Excluded: is_otto_excluded() ? 'Yes' : 'No'; ?>
Page Type: get_page_type(); ?>
Cache Status: get_cache_status(); ?>
Processing Method: get_processing_method(); ?>
Render Strategy:
  • PHP:
  • WP:
  • Memory: (used: )
  • Buffer Level:
  • Headers Sent:
Detected Plugins:
$active): ?> :
Detected Hosts:
$detected): ?> :

Debug Tools

Note: These tools help diagnose issues. Use with caution in production environments.
get_routes(); return isset($routes['/metasync/v1/otto_crawl_notify']); } /** * Check if OTTO API is reachable */ private function can_reach_otto_api() { $general_options = Metasync::get_option('general'); $otto_uuid = $general_options['otto_pixel_uuid'] ?? ''; if (empty($otto_uuid)) { return false; } # Use endpoint manager to get the correct API URL $api_endpoint = class_exists('Metasync_Endpoint_Manager') ? Metasync_Endpoint_Manager::get_endpoint('OTTO_URL_DETAILS') : 'https://sa.searchatlas.com/api/v2/otto-url-details'; $api_url = add_query_arg(array( 'url' => get_site_url(), 'uuid' => $otto_uuid ), $api_endpoint); $response = wp_remote_get($api_url, array( 'timeout' => 10, 'sslverify' => true )); return !is_wp_error($response) && wp_remote_retrieve_response_code($response) === 200; } /** * Get option last updated time */ private function get_option_last_updated($option_name) { global $wpdb; $result = $wpdb->get_var($wpdb->prepare( "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s", $option_name )); if ($result) { $data = maybe_unserialize($result); if (isset($data['last_updated'])) { return date('Y-m-d H:i:s', $data['last_updated']); } } return 'Unknown'; } /** * Get current URL */ private function get_current_url() { $scheme = is_ssl() ? 'https' : 'http'; $host = $_SERVER['HTTP_HOST'] ?? ''; $uri = $_SERVER['REQUEST_URI'] ?? ''; return $scheme . '://' . $host . $uri; } /** * Check if OTTO is excluded for current request */ private function is_otto_excluded() { // Check AJAX requests if (wp_doing_ajax() || defined('DOING_AJAX') && DOING_AJAX) { return true; } // Check WooCommerce pages if (function_exists('is_woocommerce') && is_woocommerce()) { return true; } // Check logged-in user exclusion $general_options = Metasync::get_option('general'); if (!empty($general_options['otto_disable_on_loggedin']) && $general_options['otto_disable_on_loggedin'] === 'true' && is_user_logged_in()) { return true; } return false; } /** * Get page type */ private function get_page_type() { if (is_home()) return 'Home'; if (is_front_page()) return 'Front Page'; if (is_single()) return 'Single Post'; if (is_page()) return 'Page'; if (is_category()) return 'Category'; if (is_tag()) return 'Tag'; if (is_archive()) return 'Archive'; if (is_search()) return 'Search'; if (is_404()) return '404'; return 'Other'; } /** * Get cache status */ private function get_cache_status() { // Cache is disabled in current implementation return 'Disabled (SSR Mode)'; } /** * Get processing method */ private function get_processing_method() { // OTTO SSR is always enabled by default $otto_enabled = true; if ($otto_enabled) { // Check which render strategy would be used if (class_exists('Metasync_Otto_Render_Strategy')) { $method = Metasync_Otto_Render_Strategy::determine_method(); if ($method === Metasync_Otto_Render_Strategy::METHOD_BUFFER) { return 'Server-Side Rendering (SSR) - Output Buffer (Fast)'; } elseif ($method === Metasync_Otto_Render_Strategy::METHOD_HTTP) { return 'Server-Side Rendering (SSR) - HTTP Request (Fallback)'; } } return 'Server-Side Rendering (SSR)'; } else { return 'Client-Side JavaScript'; } } /** * Get render strategy diagnostics */ public function get_render_strategy_diagnostics() { if (!class_exists('Metasync_Otto_Render_Strategy')) { return array( 'available' => false, 'message' => 'Render Strategy class not loaded' ); } return Metasync_Otto_Render_Strategy::get_diagnostics(); } /** * AJAX handler for testing OTTO API */ public function ajax_test_otto_api() { check_ajax_referer('metasync_otto_debug', 'nonce'); if (!Metasync::current_user_has_plugin_access()) { wp_die('Unauthorized'); } $general_options = Metasync::get_option('general'); $otto_uuid = $general_options['otto_pixel_uuid'] ?? ''; if (empty($otto_uuid)) { wp_send_json_error(Metasync::get_whitelabel_otto_name() . ' UUID not configured'); } $test_url = get_site_url(); # Use endpoint manager to get the correct API URL $api_endpoint = class_exists('Metasync_Endpoint_Manager') ? Metasync_Endpoint_Manager::get_endpoint('OTTO_URL_DETAILS') : 'https://sa.searchatlas.com/api/v2/otto-url-details'; $api_url = add_query_arg(array( 'url' => $test_url, 'uuid' => $otto_uuid ), $api_endpoint); $response = wp_remote_get($api_url, array( 'timeout' => 30, 'sslverify' => true, 'headers' => array( 'User-Agent' => 'MetaSync-WordPress-Plugin/1.0' ) )); if (is_wp_error($response)) { wp_send_json_error(array( 'error' => $response->get_error_message(), 'url' => $api_url )); } $response_code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); wp_send_json_success(array( 'response_code' => $response_code, 'url' => $api_url, 'body' => $body, 'has_data' => !empty($body), 'data_valid' => json_decode($body, true) !== null )); } /** * AJAX handler for testing notification endpoint */ public function ajax_test_notification_endpoint() { check_ajax_referer('metasync_otto_debug', 'nonce'); if (!Metasync::current_user_has_plugin_access()) { wp_die('Unauthorized'); } $endpoint_url = rest_url('metasync/v1/otto_crawl_notify'); $test_data = array( 'domain' => get_site_url(), 'urls' => array('/', '/about/', '/contact/') ); $response = wp_remote_post($endpoint_url, array( 'headers' => array( 'Content-Type' => 'application/json' ), 'body' => json_encode($test_data), 'timeout' => 30 )); if (is_wp_error($response)) { wp_send_json_error(array( 'error' => $response->get_error_message(), 'url' => $endpoint_url )); } $response_code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); wp_send_json_success(array( 'response_code' => $response_code, 'url' => $endpoint_url, 'body' => $body, 'test_data' => $test_data )); } /** * AJAX handler for clearing OTTO cache */ public function ajax_clear_otto_cache() { check_ajax_referer('metasync_otto_debug', 'nonce'); if (!Metasync::current_user_has_plugin_access()) { wp_die('Unauthorized'); } // Clear crawl data delete_option('metasync_otto_crawldata'); // Clear any cached API responses $general_options = Metasync::get_option('general'); $otto_uuid = $general_options['otto_pixel_uuid'] ?? ''; if (!empty($otto_uuid)) { delete_transient(Metasync_Heartbeat_Manager::public_hash_cache_key($otto_uuid)); } delete_transient('metasync_otto_js_detected'); wp_send_json_success(array( 'message' => Metasync::get_whitelabel_otto_name() . ' cache cleared successfully', 'cleared_items' => array( 'crawl_data' => true, 'api_cache' => true ) )); } /** * AJAX handler for simulating crawl notification */ public function ajax_simulate_crawl_notification() { check_ajax_referer('metasync_otto_debug', 'nonce'); if (!Metasync::current_user_has_plugin_access()) { wp_die('Unauthorized'); } $general_options = Metasync::get_option('general'); $otto_uuid = $general_options['otto_pixel_uuid'] ?? ''; if (empty($otto_uuid)) { wp_send_json_error(Metasync::get_whitelabel_otto_name() . ' UUID not configured'); } // Simulate crawl notification $test_data = array( 'domain' => get_site_url(), 'urls' => array('/', '/about/', '/contact/', '/blog/') ); // Create a mock request object $request = new WP_REST_Request('POST', '/metasync/v1/otto_crawl_notify'); $request->set_body(json_encode($test_data)); // Call the notification handler $response = metasync_otto_crawl_notify($request); wp_send_json_success(array( 'message' => 'Crawl notification simulated', 'test_data' => $test_data, 'response' => $response->get_data(), 'response_code' => $response->get_status() )); } /** * AJAX handler for testing specific URL */ public function ajax_test_specific_url() { try { check_ajax_referer('metasync_otto_debug', 'nonce'); if (!Metasync::current_user_has_plugin_access()) { wp_die('Unauthorized'); } $test_url = sanitize_url($_POST['test_url'] ?? ''); if (empty($test_url)) { wp_send_json_error('No URL provided'); } $results = array( 'test_url' => $test_url, 'timestamp' => current_time('mysql'), 'tests' => array() ); // Test 1: URL Accessibility $results['tests']['url_accessibility'] = $this->test_url_accessibility($test_url); // Test 2: OTTO API Data $results['tests']['otto_api_data'] = $this->test_otto_api_for_url($test_url); // Test 3: Crawl Status $results['tests']['crawl_status'] = $this->test_crawl_status($test_url); // Test 4: Page Type Detection $results['tests']['page_type_detection'] = $this->test_page_type_detection($test_url); // Test 5: Processing Eligibility $results['tests']['processing_eligibility'] = $this->test_processing_eligibility($test_url); wp_send_json_success($results); } catch (Exception $e) { error_log('MetaSync OTTO Debug: Exception in ajax_test_specific_url: ' . $e->getMessage()); wp_send_json_error('Exception: ' . $e->getMessage()); } } /** * AJAX handler for emulating OTTO changes */ public function ajax_emulate_otto_changes() { check_ajax_referer('metasync_otto_debug', 'nonce'); if (!Metasync::current_user_has_plugin_access()) { wp_die('Unauthorized'); } $test_url = sanitize_url($_POST['test_url'] ?? ''); if (empty($test_url)) { wp_send_json_error('No URL provided'); } $results = array( 'test_url' => $test_url, 'timestamp' => current_time('mysql'), 'emulation' => array() ); // Emulate OTTO processing $results['emulation'] = $this->emulate_otto_processing($test_url); wp_send_json_success($results); } /** * Test URL accessibility */ private function test_url_accessibility($url) { $response = wp_remote_get($url, array( 'timeout' => 10, 'user-agent' => 'MetaSync Debug Tool' )); if (is_wp_error($response)) { return array( 'status' => 'error', 'message' => $response->get_error_message(), 'accessible' => false ); } $status_code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); return array( 'status' => 'success', 'status_code' => $status_code, 'accessible' => $status_code === 200, 'content_length' => strlen($body), 'headers' => wp_remote_retrieve_headers($response)->getAll() ); } /** * Test OTTO API data for specific URL */ private function test_otto_api_for_url($url) { $general_options = Metasync::get_option('general'); $otto_uuid = $general_options['otto_pixel_uuid'] ?? ''; if (empty($otto_uuid)) { return array( 'status' => 'error', 'message' => Metasync::get_whitelabel_otto_name() . ' UUID not configured' ); } // Use the existing OTTO API function if (function_exists('metasync_fetch_otto_seo_data')) { $data = metasync_fetch_otto_seo_data($url, $otto_uuid); if (is_wp_error($data)) { return array( 'status' => 'error', 'message' => $data->get_error_message(), 'has_data' => false ); } return array( 'status' => 'success', 'has_data' => !empty($data), 'data_keys' => array_keys($data ?? array()), 'recommendations_count' => count($data['recommendations'] ?? array()), 'sample_data' => array_slice($data ?? array(), 0, 3) // First 3 items for preview ); } return array( 'status' => 'error', 'message' => Metasync::get_whitelabel_otto_name() . ' API function not available' ); } /** * Test crawl status for URL */ private function test_crawl_status($url) { if (class_exists('Metasync_otto_pixel')) { $otto_pixel = new Metasync_otto_pixel(false); $is_crawled = $otto_pixel->is_url_crawled($url); // Get crawl data from options $crawl_data = get_option('metasync_otto_crawldata'); return array( 'status' => 'success', 'is_crawled' => $is_crawled, 'crawl_data' => $crawl_data, 'total_crawled_urls' => count($crawl_data['urls'] ?? array()), 'domain' => $crawl_data['domain'] ?? 'Not set' ); } return array( 'status' => 'error', 'message' => Metasync::get_whitelabel_otto_name() . ' pixel class not available' ); } /** * Test page type detection */ private function test_page_type_detection($url) { $parsed_url = parse_url($url); $path = $parsed_url['path'] ?? '/'; $detection = array( 'url' => $url, 'path' => $path, 'is_ajax' => strpos($path, 'wp-admin/admin-ajax.php') !== false, 'is_woocommerce' => function_exists('is_woocommerce') ? false : 'WooCommerce not available', 'is_admin' => strpos($path, '/wp-admin/') !== false, 'is_login' => strpos($path, '/wp-login.php') !== false, 'is_cron' => strpos($path, '/wp-cron.php') !== false, 'is_xmlrpc' => strpos($path, '/xmlrpc.php') !== false ); // Check if it's a WooCommerce page if (function_exists('is_woocommerce')) { // This would need to be tested with actual page context $detection['is_woocommerce'] = 'Requires page context to determine'; } return $detection; } /** * Test processing eligibility */ private function test_processing_eligibility($url) { $general_options = Metasync::get_option('general'); // OTTO SSR is always enabled by default $otto_enabled = true; $disable_logged_in = $general_options['otto_disable_on_loggedin'] ?? false; $eligibility = array( 'otto_enabled' => $otto_enabled, 'disable_logged_in' => $disable_logged_in, 'user_logged_in' => is_user_logged_in(), 'eligible_for_processing' => false, 'exclusion_reasons' => array() ); // OTTO SSR is always enabled, so this check is no longer needed if ($disable_logged_in && is_user_logged_in()) { $eligibility['exclusion_reasons'][] = 'User is logged in and ' . Metasync::get_whitelabel_otto_name() . ' disabled for logged-in users'; } $eligibility['eligible_for_processing'] = empty($eligibility['exclusion_reasons']); return $eligibility; } /** * Emulate OTTO processing */ private function emulate_otto_processing($url) { $emulation = array( 'url' => $url, 'steps' => array(), 'errors' => array(), 'changes_applied' => array() ); // Step 1: Check if URL is crawled $emulation['steps']['check_crawled'] = $this->test_crawl_status($url); // Step 2: Fetch OTTO data $emulation['steps']['fetch_otto_data'] = $this->test_otto_api_for_url($url); // Step 3: Simulate HTML processing if (class_exists('Metasync_otto_html')) { try { $otto_html = new Metasync_otto_html(false); $emulation['steps']['html_processing'] = array( 'status' => 'success', 'message' => Metasync::get_whitelabel_otto_name() . ' HTML class available' ); // Simulate processing (without actually modifying files) $emulation['changes_applied'] = array( 'header_changes' => 'Simulated header modifications', 'body_changes' => 'Simulated body modifications', 'footer_changes' => 'Simulated footer modifications' ); } catch (Exception $e) { $emulation['errors'][] = 'HTML processing error: ' . $e->getMessage(); } } else { $emulation['errors'][] = Metasync::get_whitelabel_otto_name() . ' HTML class not available'; } return $emulation; } /** * Simple AJAX test to verify basic functionality */ public function ajax_simple_test() { try { check_ajax_referer('metasync_otto_debug', 'nonce'); if (!Metasync::current_user_has_plugin_access()) { wp_send_json_error('Unauthorized'); } wp_send_json_success(array( 'message' => 'AJAX is working!', 'timestamp' => current_time('mysql'), 'user_id' => get_current_user_id(), 'nonce_verified' => true )); } catch (Exception $e) { error_log('MetaSync OTTO Debug: Exception in ajax_simple_test: ' . $e->getMessage()); wp_send_json_error('Exception: ' . $e->getMessage()); } } /** * AJAX handler for testing database permissions */ public function ajax_test_db_permissions() { try { check_ajax_referer('metasync_otto_debug', 'nonce'); if (!Metasync::current_user_has_plugin_access()) { wp_send_json_error('Unauthorized'); } $results = array( 'timestamp' => current_time('mysql'), 'tests' => array() ); // Test 1: Try to schedule a simple action $test_action = 'metasync_debug_test_action'; $scheduled = wp_schedule_single_event(time() + 60, $test_action, array('test' => 'data')); $results['tests']['action_scheduler'] = array( 'can_schedule' => $scheduled !== false, 'scheduled' => $scheduled, 'message' => $scheduled !== false ? 'Action Scheduler working' : 'Action Scheduler failed - likely database permissions issue' ); // Test 2: Check if we can access Action Scheduler tables global $wpdb; $table_name = $wpdb->prefix . 'actionscheduler_actions'; $table_exists = $wpdb->get_var("SHOW TABLES LIKE '$table_name'") == $table_name; $results['tests']['table_access'] = array( 'table_exists' => $table_exists, 'table_name' => $table_name, 'message' => $table_exists ? 'Action Scheduler table exists' : 'Action Scheduler table not found' ); // Test 3: Try to insert a test record if ($table_exists) { $insert_result = $wpdb->insert( $table_name, array( 'hook' => 'metasync_debug_test', 'status' => 'pending', 'scheduled_date_gmt' => current_time('mysql', 1), 'args' => json_encode(array('test' => true)), 'schedule' => 'once' ), array('%s', '%s', '%s', '%s', '%s') ); $results['tests']['insert_test'] = array( 'can_insert' => $insert_result !== false, 'insert_id' => $wpdb->insert_id, 'last_error' => $wpdb->last_error, 'message' => $insert_result !== false ? 'Can insert records' : 'Cannot insert records - ' . $wpdb->last_error ); // Clean up test record if ($insert_result !== false && $wpdb->insert_id) { $wpdb->delete($table_name, array('ID' => $wpdb->insert_id)); } } // Test 4: Check WordPress cron functionality $cron_disabled = defined('DISABLE_WP_CRON') && DISABLE_WP_CRON; $results['tests']['wp_cron'] = array( 'enabled' => !$cron_disabled, 'message' => $cron_disabled ? 'WordPress cron is disabled' : 'WordPress cron is enabled' ); wp_send_json_success($results); } catch (Exception $e) { error_log('MetaSync OTTO Debug: Exception in ajax_test_db_permissions: ' . $e->getMessage()); wp_send_json_error('Exception: ' . $e->getMessage()); } } }