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 Access Granted
Debug Access Enabled!
You now have access to the Debug page.
Next Steps
- Access Debug Page: The " Debug" menu should now be visible in the MetaSync plugin menu
- Use Diagnostics: Click on " Debug" to access comprehensive diagnostic tools
- Troubleshoot Issues: Use the debug tools to identify why changes may not be applied
Security Notes
- Persistent Access: This access is stored in your user profile and persists across sessions
- Magic Word: Keep the magic word
abracadabra@2020 confidential
- Developer Only: This debug page is intended for plugin developers only
- To Revoke Access: Use
Metasync_Otto_Debug::disable_developer_access(ID; ?>)
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:
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):
?>
:
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());
}
}
}