diff --git a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/assets/css/zoho-admin.css b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/assets/css/zoho-admin.css index f429fce3..bddcee3d 100644 --- a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/assets/css/zoho-admin.css +++ b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/assets/css/zoho-admin.css @@ -2,6 +2,7 @@ * Zoho CRM Admin Styles */ +/* Main Sections */ .hvac-zoho-status, .hvac-zoho-sync, .hvac-zoho-settings { @@ -53,4 +54,75 @@ code { padding: 2px 6px; border-radius: 3px; font-family: 'Courier New', Courier, monospace; +} + +/* Debug Information Styling */ +.hvac-zoho-debug-info { + margin-top: 15px; + padding: 15px; + background: #f9f9f9; + border: 1px solid #ddd; + border-left: 4px solid #dc3232; +} + +.hvac-zoho-debug-info p { + margin: 5px 0; +} + +.hvac-zoho-debug-info strong { + color: #23282d; +} + +.hvac-zoho-debug-info details { + margin-top: 10px; +} + +.hvac-zoho-debug-info details summary { + cursor: pointer; + font-weight: bold; + color: #0073aa; + padding: 5px; + background: #f0f0f0; + border: 1px solid #ddd; + border-radius: 3px; + margin-bottom: 5px; +} + +.hvac-zoho-debug-info details summary:hover { + background: #e9e9e9; +} + +.hvac-zoho-debug-info pre { + white-space: pre-wrap; + word-wrap: break-word; + font-family: monospace; + background: #f0f0f0; + padding: 15px; + max-height: 300px; + overflow: auto; + border: 1px solid #ddd; + border-radius: 3px; + font-size: 12px; + line-height: 1.4; + color: #333; +} + +/* Error Notice Improvements */ +.notice-error { + padding: 15px; +} + +.notice-error p { + margin: 0.5em 0; +} + +.notice-error p:first-child { + font-weight: 500; +} + +/* Staging Mode Banner */ +.notice-info h3 { + margin-top: 0.5em; + margin-bottom: 0.5em; + color: #0073aa; } \ No newline at end of file diff --git a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/assets/js/zoho-admin.js b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/assets/js/zoho-admin.js index 7d7a53c2..b6f08ee2 100644 --- a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/assets/js/zoho-admin.js +++ b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/assets/js/zoho-admin.js @@ -21,11 +21,65 @@ jQuery(document).ready(function($) { if (response.success) { $status.html('

' + response.data.message + ' (' + response.data.modules + ')

'); } else { - $status.html('

' + response.data.message + ': ' + response.data.error + '

'); + // Create detailed error display + var errorHtml = '
'; + errorHtml += '

' + response.data.message + ': ' + response.data.error + '

'; + + // Add error code if available + if (response.data.code) { + errorHtml += '

Error Code: ' + response.data.code + '

'; + } + + // Add details if available + if (response.data.details) { + errorHtml += '

Details: ' + response.data.details + '

'; + } + + // Add debugging info + errorHtml += '
'; + errorHtml += '

Debug Information:

'; + errorHtml += '

Check the PHP error log for more details.

'; + errorHtml += '

Log location: wp-content/plugins/hvac-community-events/logs/zoho-debug.log

'; + + // Add raw response data if available + if (response.data.raw) { + errorHtml += '
'; + errorHtml += 'Raw Response Data (click to expand)'; + errorHtml += '
' + 
+                                     JSON.stringify(JSON.parse(response.data.raw), null, 2) + 
+                                     '
'; + errorHtml += '
'; + } + + // Add file/line info if available (for exceptions) + if (response.data.file) { + errorHtml += '

File: ' + response.data.file + '

'; + } + + // Add trace if available + if (response.data.trace) { + errorHtml += '
'; + errorHtml += 'Stack Trace (click to expand)'; + errorHtml += '
' + 
+                                     response.data.trace + 
+                                     '
'; + errorHtml += '
'; + } + + errorHtml += '
'; // Close debug info + errorHtml += '
'; // Close notice + + $status.html(errorHtml); } }, - error: function() { - $status.html('

Connection test failed

'); + error: function(xhr, status, error) { + var errorHtml = '
'; + errorHtml += '

AJAX Error: Connection test failed

'; + errorHtml += '

Status: ' + status + '

'; + errorHtml += '

Error: ' + error + '

'; + errorHtml += '
'; + + $status.html(errorHtml); }, complete: function() { $button.prop('disabled', false).text('Test Connection'); diff --git a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/admin/class-zoho-admin.php b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/admin/class-zoho-admin.php index c898bc40..be6b3417 100644 --- a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/admin/class-zoho-admin.php +++ b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/admin/class-zoho-admin.php @@ -162,26 +162,105 @@ class HVAC_Zoho_Admin { try { require_once HVAC_CE_PLUGIN_DIR . 'includes/zoho/class-zoho-crm-auth.php'; + + // Enable debug logging + if (!defined('ZOHO_DEBUG_MODE')) { + define('ZOHO_DEBUG_MODE', true); + } + + // Create a temporary log file if needed + if (!defined('ZOHO_LOG_FILE')) { + $log_dir = HVAC_CE_PLUGIN_DIR . 'logs'; + if (!file_exists($log_dir)) { + mkdir($log_dir, 0755, true); + } + define('ZOHO_LOG_FILE', $log_dir . '/zoho-debug.log'); + } + + // Load the general logger for additional context + require_once HVAC_CE_PLUGIN_DIR . 'includes/class-hvac-logger.php'; + HVAC_Logger::set_enabled(true); + HVAC_Logger::info('Starting Zoho connection test', 'ZOHO_TEST'); + $auth = new HVAC_Zoho_CRM_Auth(); + // Debug connection parameters + HVAC_Logger::info('Checking Zoho configuration', 'ZOHO_TEST', array( + 'client_id_exists' => !empty($auth->get_client_id()), + 'client_secret_exists' => !empty($auth->get_client_secret()), + 'refresh_token_exists' => !empty($auth->get_refresh_token()) + )); + // Test API call $response = $auth->make_api_request('/settings/modules', 'GET'); + // Detailed logging of the response + if (is_wp_error($response)) { + HVAC_Logger::error('WP Error in API request', 'ZOHO_TEST', array( + 'error_message' => $response->get_error_message(), + 'error_code' => $response->get_error_code() + )); + + wp_send_json_error(array( + 'message' => 'Connection failed - WordPress Error', + 'error' => $response->get_error_message(), + 'details' => 'Error Code: ' . $response->get_error_code() + )); + return; + } + if ($response && !isset($response['error'])) { + HVAC_Logger::info('Connection successful', 'ZOHO_TEST', array( + 'modules_count' => isset($response['modules']) ? count($response['modules']) : 0 + )); + wp_send_json_success(array( 'message' => 'Connection successful!', - 'modules' => count($response['modules']) . ' modules available' + 'modules' => isset($response['modules']) ? count($response['modules']) . ' modules available' : 'No modules found' )); } else { + $error_message = isset($response['error']) ? $response['error'] : 'Unknown error'; + $error_code = isset($response['code']) ? $response['code'] : ''; + $error_details = isset($response['details']) ? $response['details'] : ''; + + // Extract more detailed error information if available + if (isset($response['data']) && is_array($response['data']) && !empty($response['data'])) { + $first_error = $response['data'][0]; + $error_code = isset($first_error['code']) ? $first_error['code'] : $error_code; + $error_message = isset($first_error['message']) ? $first_error['message'] : $error_message; + if (isset($first_error['details']) && is_array($first_error['details'])) { + $error_details = json_encode($first_error['details']); + } + } + + HVAC_Logger::error('Connection failed', 'ZOHO_TEST', array( + 'error' => $error_message, + 'code' => $error_code, + 'details' => $error_details, + 'full_response' => $response + )); + wp_send_json_error(array( 'message' => 'Connection failed', - 'error' => isset($response['error']) ? $response['error'] : 'Unknown error' + 'error' => $error_message, + 'code' => $error_code, + 'details' => $error_details, + 'raw' => json_encode($response) )); } } catch (Exception $e) { + HVAC_Logger::error('Exception in Zoho connection test', 'ZOHO_TEST', array( + 'exception' => $e->getMessage(), + 'file' => $e->getFile(), + 'line' => $e->getLine(), + 'trace' => $e->getTraceAsString() + )); + wp_send_json_error(array( - 'message' => 'Connection failed', - 'error' => $e->getMessage() + 'message' => 'Connection failed due to exception', + 'error' => $e->getMessage(), + 'file' => $e->getFile() . ':' . $e->getLine(), + 'trace' => $e->getTraceAsString() )); } } diff --git a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/zoho/class-zoho-crm-auth.php b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/zoho/class-zoho-crm-auth.php index 3ca6c86a..88e6a4c8 100644 --- a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/zoho/class-zoho-crm-auth.php +++ b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/zoho/class-zoho-crm-auth.php @@ -20,6 +20,7 @@ class HVAC_Zoho_CRM_Auth { private $redirect_uri; private $access_token; private $token_expiry; + private $last_error = null; public function __construct() { // Load configuration if available @@ -178,42 +179,134 @@ class HVAC_Zoho_CRM_Auth { ); } + // Debug logging of config status + if (defined('ZOHO_DEBUG_MODE') && ZOHO_DEBUG_MODE) { + $config_status = $this->get_configuration_status(); + $this->log_debug('Configuration status: ' . json_encode($config_status)); + + if (!$config_status['client_id_exists']) { + $this->log_error('Client ID is missing or empty'); + } + + if (!$config_status['client_secret_exists']) { + $this->log_error('Client Secret is missing or empty'); + } + + if (!$config_status['refresh_token_exists']) { + $this->log_error('Refresh Token is missing or empty'); + } + + if ($config_status['token_expired']) { + $this->log_debug('Access token is expired, will attempt to refresh'); + } + } + $access_token = $this->get_access_token(); if (!$access_token) { - return new WP_Error('no_token', 'No valid access token available'); + $error_message = 'No valid access token available'; + $this->log_error($error_message); + return new WP_Error('no_token', $error_message); } $api_base_url = defined('ZOHO_API_BASE_URL') ? ZOHO_API_BASE_URL : 'https://www.zohoapis.com/crm/v2'; $url = $api_base_url . $endpoint; + // Log the request details + $this->log_debug('Making ' . $method . ' request to: ' . $url); + $args = array( 'method' => $method, 'headers' => array( 'Authorization' => 'Zoho-oauthtoken ' . $access_token, 'Content-Type' => 'application/json' - ) + ), + 'timeout' => 30 // Increase timeout to 30 seconds for potentially slow responses ); if ($data && in_array($method, array('POST', 'PUT', 'PATCH'))) { $args['body'] = json_encode($data); + $this->log_debug('Request payload: ' . json_encode($data)); } + // Execute the request + $this->log_debug('Executing request to Zoho API'); $response = wp_remote_request($url, $args); + // Handle WordPress errors if (is_wp_error($response)) { - $this->log_error('API request failed: ' . $response->get_error_message()); + $error_message = 'API request failed: ' . $response->get_error_message(); + $error_data = $response->get_error_data(); + + $this->log_error($error_message); + $this->log_debug('Error details: ' . json_encode($error_data)); + return $response; } + // Get response code and body + $status_code = wp_remote_retrieve_response_code($response); + $headers = wp_remote_retrieve_headers($response); $body = wp_remote_retrieve_body($response); + + $this->log_debug('Response code: ' . $status_code); + + // Log headers for debugging + if (defined('ZOHO_DEBUG_MODE') && ZOHO_DEBUG_MODE) { + $this->log_debug('Response headers: ' . json_encode($headers->getAll())); + } + + // Handle empty responses + if (empty($body)) { + $error_message = 'Empty response received from Zoho API'; + $this->log_error($error_message); + return array( + 'error' => $error_message, + 'code' => $status_code, + 'details' => 'No response body received' + ); + } + + // Parse the JSON response $data = json_decode($body, true); + // Check for JSON parsing errors + if ($data === null && json_last_error() !== JSON_ERROR_NONE) { + $error_message = 'Invalid JSON response: ' . json_last_error_msg(); + $this->log_error($error_message); + $this->log_debug('Raw response: ' . $body); + + return array( + 'error' => $error_message, + 'code' => 'JSON_PARSE_ERROR', + 'details' => 'Raw response: ' . substr($body, 0, 255) . (strlen($body) > 255 ? '...' : '') + ); + } + // Log response for debugging if (defined('ZOHO_DEBUG_MODE') && ZOHO_DEBUG_MODE) { $this->log_debug('API Response: ' . $body); } + // Check for API errors + if ($status_code >= 400) { + $error_message = isset($data['message']) ? $data['message'] : 'API error with status code ' . $status_code; + $this->log_error($error_message); + + // Add HTTP error information to the response + $data['http_status'] = $status_code; + $data['error'] = $error_message; + + // Extract more detailed error information if available + if (isset($data['code'])) { + $this->log_debug('Error code: ' . $data['code']); + } + + if (isset($data['details'])) { + $this->log_debug('Error details: ' . json_encode($data['details'])); + } + } + return $data; } @@ -250,9 +343,16 @@ class HVAC_Zoho_CRM_Auth { * Log error messages */ private function log_error($message) { + $this->last_error = $message; + if (defined('ZOHO_LOG_FILE')) { error_log('[' . date('Y-m-d H:i:s') . '] ERROR: ' . $message . PHP_EOL, 3, ZOHO_LOG_FILE); } + + // Also log to WordPress debug log if available + if (defined('WP_DEBUG') && WP_DEBUG && defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) { + error_log('[ZOHO CRM] ' . $message); + } } /** @@ -262,5 +362,62 @@ class HVAC_Zoho_CRM_Auth { if (defined('ZOHO_DEBUG_MODE') && ZOHO_DEBUG_MODE && defined('ZOHO_LOG_FILE')) { error_log('[' . date('Y-m-d H:i:s') . '] DEBUG: ' . $message . PHP_EOL, 3, ZOHO_LOG_FILE); } + + // Also log to WordPress debug log if available + if (defined('ZOHO_DEBUG_MODE') && ZOHO_DEBUG_MODE && defined('WP_DEBUG') && WP_DEBUG && defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) { + error_log('[ZOHO CRM DEBUG] ' . $message); + } + } + + /** + * Get the last error message + * + * @return string|null + */ + public function get_last_error() { + return $this->last_error; + } + + /** + * Get client ID (for debugging only) + * + * @return string + */ + public function get_client_id() { + return $this->client_id; + } + + /** + * Check if client secret exists (for debugging only) + * + * @return bool + */ + public function get_client_secret() { + return !empty($this->client_secret); + } + + /** + * Check if refresh token exists (for debugging only) + * + * @return bool + */ + public function get_refresh_token() { + return !empty($this->refresh_token); + } + + /** + * Get configuration status (for debugging) + * + * @return array + */ + public function get_configuration_status() { + return array( + 'client_id_exists' => !empty($this->client_id), + 'client_secret_exists' => !empty($this->client_secret), + 'refresh_token_exists' => !empty($this->refresh_token), + 'access_token_exists' => !empty($this->access_token), + 'token_expired' => $this->token_expiry < time(), + 'config_loaded' => file_exists(plugin_dir_path(__FILE__) . 'zoho-config.php') + ); } } \ No newline at end of file diff --git a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/zoho/diagnostics.php b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/zoho/diagnostics.php new file mode 100644 index 00000000..cb5e2c52 --- /dev/null +++ b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/zoho/diagnostics.php @@ -0,0 +1,224 @@ +\n"; + } +} + +// Start diagnostics +diagnostics_log('Starting Zoho CRM diagnostics'); + +// Check for required files +$required_files = array( + 'class-zoho-crm-auth.php' => dirname(__FILE__) . '/class-zoho-crm-auth.php', + 'zoho-config.php' => dirname(__FILE__) . '/zoho-config.php', +); + +$missing_files = array(); +foreach ($required_files as $name => $path) { + if (!file_exists($path)) { + $missing_files[] = $name; + diagnostics_log("Missing required file: $name", 'ERROR'); + } else { + diagnostics_log("Found required file: $name"); + } +} + +if (!empty($missing_files)) { + diagnostics_log('Diagnostics failed due to missing files', 'ERROR'); + die('Missing required files: ' . implode(', ', $missing_files)); +} + +// Check for config constants +require_once $required_files['zoho-config.php']; +$required_constants = array( + 'ZOHO_CLIENT_ID', + 'ZOHO_CLIENT_SECRET', + 'ZOHO_REFRESH_TOKEN', + 'ZOHO_ACCOUNTS_URL', + 'ZOHO_API_BASE_URL', +); + +$missing_constants = array(); +$empty_constants = array(); +foreach ($required_constants as $constant) { + if (!defined($constant)) { + $missing_constants[] = $constant; + diagnostics_log("Missing required constant: $constant", 'ERROR'); + } else { + $value = constant($constant); + if (empty($value)) { + $empty_constants[] = $constant; + diagnostics_log("Constant is empty: $constant", 'WARNING'); + } else { + // Mask the actual value for security + $masked_value = $constant === 'ZOHO_CLIENT_ID' ? substr($value, 0, 4) . '...' : '[MASKED]'; + diagnostics_log("Found constant: $constant = $masked_value"); + } + } +} + +if (!empty($missing_constants)) { + diagnostics_log('Diagnostics found missing constants', 'ERROR'); + echo 'Missing required constants: ' . implode(', ', $missing_constants) . "
\n"; +} + +if (!empty($empty_constants)) { + diagnostics_log('Diagnostics found empty constants', 'WARNING'); + echo 'Empty constants: ' . implode(', ', $empty_constants) . "
\n"; +} + +// Initialize Zoho CRM Auth +require_once $required_files['class-zoho-crm-auth.php']; +$auth = new HVAC_Zoho_CRM_Auth(); + +// Check the configuration status +$config_status = $auth->get_configuration_status(); +diagnostics_log('Configuration status: ' . json_encode($config_status)); + +foreach ($config_status as $key => $value) { + $status = $value ? 'OK' : 'FAIL'; + $type = $value ? 'INFO' : 'ERROR'; + diagnostics_log("$key: $status", $type); + + echo "$key: " . ($value ? '✅' : '❌') . "
\n"; +} + +// Test getting an access token +try { + diagnostics_log('Testing access token retrieval'); + $access_token = $auth->get_access_token(); + + if ($access_token) { + diagnostics_log('Successfully retrieved access token'); + echo "Access token retrieval: ✅
\n"; + } else { + diagnostics_log('Failed to retrieve access token', 'ERROR'); + echo "Access token retrieval: ❌
\n"; + } +} catch (Exception $e) { + diagnostics_log('Exception while retrieving access token: ' . $e->getMessage(), 'ERROR'); + echo "Access token retrieval exception: " . $e->getMessage() . "
\n"; +} + +// Test API connection +try { + diagnostics_log('Testing API connection'); + $response = $auth->make_api_request('/settings/modules', 'GET'); + + if (is_wp_error($response)) { + diagnostics_log('API connection failed: ' . $response->get_error_message(), 'ERROR'); + echo "API connection: ❌ - " . $response->get_error_message() . "
\n"; + } else if (isset($response['modules'])) { + $module_count = count($response['modules']); + diagnostics_log("API connection successful. Found $module_count modules."); + echo "API connection: ✅ - Found $module_count modules
\n"; + + // List first few modules + echo "Available Modules:
\n"; + echo "\n"; + } else { + diagnostics_log('API connection failed: ' . json_encode($response), 'ERROR'); + echo "API connection: ❌ - Error response
\n"; + echo "
" . json_encode($response, JSON_PRETTY_PRINT) . "
\n"; + } +} catch (Exception $e) { + diagnostics_log('Exception while testing API connection: ' . $e->getMessage(), 'ERROR'); + echo "API connection exception: " . $e->getMessage() . "
\n"; +} + +// Environment information +echo "

Environment Information

\n"; +echo "\n"; + +// Final diagnostics message +diagnostics_log('Zoho CRM diagnostics completed'); +echo "

Diagnostics completed. Check the log file for more details: " . ZOHO_LOG_FILE . "

\n"; + +// Include a simple CSS for better presentation +echo "\n"; \ No newline at end of file