fix: Improve Zoho CRM integration debug and error handling
- Enhanced error messages for Zoho CRM connection test failures - Added detailed error information display in admin UI - Created diagnostics.php script for advanced troubleshooting - Improved logging with file, line, and stack trace information - Added client ID, secret, and refresh token validation checks - Enhanced CSS styling for error messages and debugging info - Added configuration status checks to help identify issues 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
8d44245ec9
commit
005bbf537e
5 changed files with 596 additions and 10 deletions
|
|
@ -2,6 +2,7 @@
|
||||||
* Zoho CRM Admin Styles
|
* Zoho CRM Admin Styles
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Main Sections */
|
||||||
.hvac-zoho-status,
|
.hvac-zoho-status,
|
||||||
.hvac-zoho-sync,
|
.hvac-zoho-sync,
|
||||||
.hvac-zoho-settings {
|
.hvac-zoho-settings {
|
||||||
|
|
@ -54,3 +55,74 @@ code {
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
font-family: 'Courier New', Courier, monospace;
|
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;
|
||||||
|
}
|
||||||
|
|
@ -21,11 +21,65 @@ jQuery(document).ready(function($) {
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
$status.html('<div class="notice notice-success"><p>' + response.data.message + ' (' + response.data.modules + ')</p></div>');
|
$status.html('<div class="notice notice-success"><p>' + response.data.message + ' (' + response.data.modules + ')</p></div>');
|
||||||
} else {
|
} else {
|
||||||
$status.html('<div class="notice notice-error"><p>' + response.data.message + ': ' + response.data.error + '</p></div>');
|
// Create detailed error display
|
||||||
|
var errorHtml = '<div class="notice notice-error">';
|
||||||
|
errorHtml += '<p><strong>' + response.data.message + ':</strong> ' + response.data.error + '</p>';
|
||||||
|
|
||||||
|
// Add error code if available
|
||||||
|
if (response.data.code) {
|
||||||
|
errorHtml += '<p><strong>Error Code:</strong> ' + response.data.code + '</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add details if available
|
||||||
|
if (response.data.details) {
|
||||||
|
errorHtml += '<p><strong>Details:</strong> ' + response.data.details + '</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add debugging info
|
||||||
|
errorHtml += '<div class="hvac-zoho-debug-info">';
|
||||||
|
errorHtml += '<p><strong>Debug Information:</strong></p>';
|
||||||
|
errorHtml += '<p>Check the PHP error log for more details.</p>';
|
||||||
|
errorHtml += '<p>Log location: wp-content/plugins/hvac-community-events/logs/zoho-debug.log</p>';
|
||||||
|
|
||||||
|
// Add raw response data if available
|
||||||
|
if (response.data.raw) {
|
||||||
|
errorHtml += '<details>';
|
||||||
|
errorHtml += '<summary>Raw Response Data (click to expand)</summary>';
|
||||||
|
errorHtml += '<pre style="background: #f0f0f0; padding: 10px; max-height: 300px; overflow: auto;">' +
|
||||||
|
JSON.stringify(JSON.parse(response.data.raw), null, 2) +
|
||||||
|
'</pre>';
|
||||||
|
errorHtml += '</details>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add file/line info if available (for exceptions)
|
||||||
|
if (response.data.file) {
|
||||||
|
errorHtml += '<p><strong>File:</strong> ' + response.data.file + '</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add trace if available
|
||||||
|
if (response.data.trace) {
|
||||||
|
errorHtml += '<details>';
|
||||||
|
errorHtml += '<summary>Stack Trace (click to expand)</summary>';
|
||||||
|
errorHtml += '<pre style="background: #f0f0f0; padding: 10px; max-height: 300px; overflow: auto;">' +
|
||||||
|
response.data.trace +
|
||||||
|
'</pre>';
|
||||||
|
errorHtml += '</details>';
|
||||||
|
}
|
||||||
|
|
||||||
|
errorHtml += '</div>'; // Close debug info
|
||||||
|
errorHtml += '</div>'; // Close notice
|
||||||
|
|
||||||
|
$status.html(errorHtml);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function() {
|
error: function(xhr, status, error) {
|
||||||
$status.html('<div class="notice notice-error"><p>Connection test failed</p></div>');
|
var errorHtml = '<div class="notice notice-error">';
|
||||||
|
errorHtml += '<p><strong>AJAX Error:</strong> Connection test failed</p>';
|
||||||
|
errorHtml += '<p><strong>Status:</strong> ' + status + '</p>';
|
||||||
|
errorHtml += '<p><strong>Error:</strong> ' + error + '</p>';
|
||||||
|
errorHtml += '</div>';
|
||||||
|
|
||||||
|
$status.html(errorHtml);
|
||||||
},
|
},
|
||||||
complete: function() {
|
complete: function() {
|
||||||
$button.prop('disabled', false).text('Test Connection');
|
$button.prop('disabled', false).text('Test Connection');
|
||||||
|
|
|
||||||
|
|
@ -162,26 +162,105 @@ class HVAC_Zoho_Admin {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
require_once HVAC_CE_PLUGIN_DIR . 'includes/zoho/class-zoho-crm-auth.php';
|
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();
|
$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
|
// Test API call
|
||||||
$response = $auth->make_api_request('/settings/modules', 'GET');
|
$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'])) {
|
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(
|
wp_send_json_success(array(
|
||||||
'message' => 'Connection successful!',
|
'message' => 'Connection successful!',
|
||||||
'modules' => count($response['modules']) . ' modules available'
|
'modules' => isset($response['modules']) ? count($response['modules']) . ' modules available' : 'No modules found'
|
||||||
));
|
));
|
||||||
} else {
|
} 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(
|
wp_send_json_error(array(
|
||||||
'message' => 'Connection failed',
|
'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) {
|
} 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(
|
wp_send_json_error(array(
|
||||||
'message' => 'Connection failed',
|
'message' => 'Connection failed due to exception',
|
||||||
'error' => $e->getMessage()
|
'error' => $e->getMessage(),
|
||||||
|
'file' => $e->getFile() . ':' . $e->getLine(),
|
||||||
|
'trace' => $e->getTraceAsString()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ class HVAC_Zoho_CRM_Auth {
|
||||||
private $redirect_uri;
|
private $redirect_uri;
|
||||||
private $access_token;
|
private $access_token;
|
||||||
private $token_expiry;
|
private $token_expiry;
|
||||||
|
private $last_error = null;
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
// Load configuration if available
|
// 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();
|
$access_token = $this->get_access_token();
|
||||||
|
|
||||||
if (!$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';
|
$api_base_url = defined('ZOHO_API_BASE_URL') ? ZOHO_API_BASE_URL : 'https://www.zohoapis.com/crm/v2';
|
||||||
$url = $api_base_url . $endpoint;
|
$url = $api_base_url . $endpoint;
|
||||||
|
|
||||||
|
// Log the request details
|
||||||
|
$this->log_debug('Making ' . $method . ' request to: ' . $url);
|
||||||
|
|
||||||
$args = array(
|
$args = array(
|
||||||
'method' => $method,
|
'method' => $method,
|
||||||
'headers' => array(
|
'headers' => array(
|
||||||
'Authorization' => 'Zoho-oauthtoken ' . $access_token,
|
'Authorization' => 'Zoho-oauthtoken ' . $access_token,
|
||||||
'Content-Type' => 'application/json'
|
'Content-Type' => 'application/json'
|
||||||
)
|
),
|
||||||
|
'timeout' => 30 // Increase timeout to 30 seconds for potentially slow responses
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($data && in_array($method, array('POST', 'PUT', 'PATCH'))) {
|
if ($data && in_array($method, array('POST', 'PUT', 'PATCH'))) {
|
||||||
$args['body'] = json_encode($data);
|
$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);
|
$response = wp_remote_request($url, $args);
|
||||||
|
|
||||||
|
// Handle WordPress errors
|
||||||
if (is_wp_error($response)) {
|
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;
|
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);
|
$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);
|
$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
|
// Log response for debugging
|
||||||
if (defined('ZOHO_DEBUG_MODE') && ZOHO_DEBUG_MODE) {
|
if (defined('ZOHO_DEBUG_MODE') && ZOHO_DEBUG_MODE) {
|
||||||
$this->log_debug('API Response: ' . $body);
|
$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;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -250,9 +343,16 @@ class HVAC_Zoho_CRM_Auth {
|
||||||
* Log error messages
|
* Log error messages
|
||||||
*/
|
*/
|
||||||
private function log_error($message) {
|
private function log_error($message) {
|
||||||
|
$this->last_error = $message;
|
||||||
|
|
||||||
if (defined('ZOHO_LOG_FILE')) {
|
if (defined('ZOHO_LOG_FILE')) {
|
||||||
error_log('[' . date('Y-m-d H:i:s') . '] ERROR: ' . $message . PHP_EOL, 3, 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')) {
|
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);
|
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')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,224 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Zoho CRM Diagnostics Tool
|
||||||
|
*
|
||||||
|
* A standalone script to diagnose Zoho CRM integration issues
|
||||||
|
*
|
||||||
|
* To use: Add the following line to wp-config.php:
|
||||||
|
* define('ZOHO_DIAGNOSTICS_ENABLED', true);
|
||||||
|
*
|
||||||
|
* Then access: /wp-content/plugins/hvac-community-events/includes/zoho/diagnostics.php
|
||||||
|
*
|
||||||
|
* @package HVACCommunityEvents
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Security check to prevent direct access unless diagnostics are enabled
|
||||||
|
if (!defined('ABSPATH')) {
|
||||||
|
// Check if this is a direct access with the diagnostics parameter
|
||||||
|
if (!isset($_GET['run_diagnostics']) || $_GET['run_diagnostics'] !== 'true') {
|
||||||
|
die('Access denied.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bootstrap WordPress
|
||||||
|
$wp_load_path = dirname(dirname(dirname(dirname(dirname(__FILE__))))) . '/wp-load.php';
|
||||||
|
if (file_exists($wp_load_path)) {
|
||||||
|
require_once $wp_load_path;
|
||||||
|
} else {
|
||||||
|
die('WordPress not found. Please run diagnostics from the WordPress installation directory.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if diagnostics are enabled
|
||||||
|
if (!defined('ZOHO_DIAGNOSTICS_ENABLED') || !ZOHO_DIAGNOSTICS_ENABLED) {
|
||||||
|
die('Zoho diagnostics are not enabled. Add define("ZOHO_DIAGNOSTICS_ENABLED", true); to wp-config.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user is logged in and has appropriate capabilities
|
||||||
|
if (!current_user_can('manage_options')) {
|
||||||
|
die('You do not have permission to run diagnostics.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up error reporting and logging
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
|
||||||
|
// Create a log directory if it doesn't exist
|
||||||
|
$log_dir = dirname(dirname(__FILE__)) . '/logs';
|
||||||
|
if (!file_exists($log_dir)) {
|
||||||
|
mkdir($log_dir, 0755, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define log file constants
|
||||||
|
if (!defined('ZOHO_LOG_FILE')) {
|
||||||
|
define('ZOHO_LOG_FILE', $log_dir . '/zoho-diagnostics.log');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!defined('ZOHO_DEBUG_MODE')) {
|
||||||
|
define('ZOHO_DEBUG_MODE', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to log diagnostic messages
|
||||||
|
function diagnostics_log($message, $type = 'INFO') {
|
||||||
|
$log_message = '[' . date('Y-m-d H:i:s') . '] ' . $type . ': ' . $message . PHP_EOL;
|
||||||
|
error_log($log_message, 3, ZOHO_LOG_FILE);
|
||||||
|
|
||||||
|
// Also output to screen if this is a direct access
|
||||||
|
if (!defined('ABSPATH')) {
|
||||||
|
echo $log_message . "<br>\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) . "<br>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($empty_constants)) {
|
||||||
|
diagnostics_log('Diagnostics found empty constants', 'WARNING');
|
||||||
|
echo 'Empty constants: ' . implode(', ', $empty_constants) . "<br>\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 ? '✅' : '❌') . "<br>\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: ✅<br>\n";
|
||||||
|
} else {
|
||||||
|
diagnostics_log('Failed to retrieve access token', 'ERROR');
|
||||||
|
echo "Access token retrieval: ❌<br>\n";
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
diagnostics_log('Exception while retrieving access token: ' . $e->getMessage(), 'ERROR');
|
||||||
|
echo "Access token retrieval exception: " . $e->getMessage() . "<br>\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() . "<br>\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<br>\n";
|
||||||
|
|
||||||
|
// List first few modules
|
||||||
|
echo "<strong>Available Modules:</strong><br>\n";
|
||||||
|
echo "<ul>\n";
|
||||||
|
$count = 0;
|
||||||
|
foreach ($response['modules'] as $module) {
|
||||||
|
if ($count++ < 5) {
|
||||||
|
echo "<li>" . $module['api_name'] . " (" . $module['plural_label'] . ")</li>\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($module_count > 5) {
|
||||||
|
echo "<li>... and " . ($module_count - 5) . " more</li>\n";
|
||||||
|
}
|
||||||
|
echo "</ul>\n";
|
||||||
|
} else {
|
||||||
|
diagnostics_log('API connection failed: ' . json_encode($response), 'ERROR');
|
||||||
|
echo "API connection: ❌ - Error response<br>\n";
|
||||||
|
echo "<pre>" . json_encode($response, JSON_PRETTY_PRINT) . "</pre>\n";
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
diagnostics_log('Exception while testing API connection: ' . $e->getMessage(), 'ERROR');
|
||||||
|
echo "API connection exception: " . $e->getMessage() . "<br>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Environment information
|
||||||
|
echo "<h3>Environment Information</h3>\n";
|
||||||
|
echo "<ul>\n";
|
||||||
|
echo "<li>PHP Version: " . phpversion() . "</li>\n";
|
||||||
|
echo "<li>WordPress Version: " . get_bloginfo('version') . "</li>\n";
|
||||||
|
echo "<li>Site URL: " . get_site_url() . "</li>\n";
|
||||||
|
echo "<li>Staging Mode: " . (strpos(get_site_url(), 'upskillhvac.com') === false ? 'Yes' : 'No') . "</li>\n";
|
||||||
|
echo "<li>Zoho Debug Mode: " . (defined('ZOHO_DEBUG_MODE') && ZOHO_DEBUG_MODE ? 'Enabled' : 'Disabled') . "</li>\n";
|
||||||
|
echo "<li>Diagnostic Log: " . ZOHO_LOG_FILE . "</li>\n";
|
||||||
|
echo "</ul>\n";
|
||||||
|
|
||||||
|
// Final diagnostics message
|
||||||
|
diagnostics_log('Zoho CRM diagnostics completed');
|
||||||
|
echo "<p><strong>Diagnostics completed.</strong> Check the log file for more details: " . ZOHO_LOG_FILE . "</p>\n";
|
||||||
|
|
||||||
|
// Include a simple CSS for better presentation
|
||||||
|
echo "<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; line-height: 1.4; padding: 20px; max-width: 800px; margin: 0 auto; }
|
||||||
|
h1, h2, h3 { color: #23282d; }
|
||||||
|
pre { background: #f0f0f0; padding: 15px; border-radius: 3px; overflow: auto; }
|
||||||
|
ul { margin-left: 20px; }
|
||||||
|
</style>\n";
|
||||||
Loading…
Reference in a new issue