fix(zoho): Fix user sync search criteria and improve data validation
- Fix sync_users search: pass criteria in URL query string instead of as data parameter (GET requests ignore body data), which caused every user search to fail and fall through to create - Improve validate_api_response to check Zoho-specific error codes before generic HTTP errors, and include field-level detail in messages - Add Last_Name fallback to display_name/username when meta is empty - Sanitize Phone to digits-only, require 10+ digits, omit if invalid - Bump HVAC_PLUGIN_VERSION to 2.2.11 to bust browser cache Result: 65/65 trainers now sync successfully (was 0/65). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
03b9bce52d
commit
4c22b9db8e
1 changed files with 52 additions and 17 deletions
|
|
@ -81,7 +81,30 @@ class HVAC_Zoho_Sync {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for HTTP-level errors
|
// Check for Zoho API error codes FIRST (more specific than generic HTTP errors)
|
||||||
|
if (isset($response['data'][0]['code']) && !in_array($response['data'][0]['code'], array('SUCCESS', 'DUPLICATE_DATA'))) {
|
||||||
|
$error_msg = isset($response['data'][0]['message']) ? $response['data'][0]['message'] : $response['data'][0]['code'];
|
||||||
|
// Include field-level details if available
|
||||||
|
if (isset($response['data'][0]['details'])) {
|
||||||
|
$details = $response['data'][0]['details'];
|
||||||
|
if (isset($details['api_name'])) {
|
||||||
|
$error_msg .= ' (field: ' . $details['api_name'] . ')';
|
||||||
|
}
|
||||||
|
if (isset($details['expected_data_type'])) {
|
||||||
|
$error_msg .= ' (expected: ' . $details['expected_data_type'] . ')';
|
||||||
|
}
|
||||||
|
if (isset($details['info'])) {
|
||||||
|
$error_msg .= ' - ' . $details['info'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array(
|
||||||
|
'success' => false,
|
||||||
|
'id' => null,
|
||||||
|
'error' => $error_msg
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for HTTP-level errors (generic fallback)
|
||||||
if (isset($response['error'])) {
|
if (isset($response['error'])) {
|
||||||
return array(
|
return array(
|
||||||
'success' => false,
|
'success' => false,
|
||||||
|
|
@ -90,16 +113,6 @@ class HVAC_Zoho_Sync {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for Zoho API error codes
|
|
||||||
if (isset($response['data'][0]['code']) && !in_array($response['data'][0]['code'], array('SUCCESS', 'DUPLICATE_DATA'))) {
|
|
||||||
$error_msg = isset($response['data'][0]['message']) ? $response['data'][0]['message'] : $response['data'][0]['code'];
|
|
||||||
return array(
|
|
||||||
'success' => false,
|
|
||||||
'id' => null,
|
|
||||||
'error' => $error_msg
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for successful response with ID
|
// Check for successful response with ID
|
||||||
if (isset($response['data'][0]['details']['id'])) {
|
if (isset($response['data'][0]['details']['id'])) {
|
||||||
return array(
|
return array(
|
||||||
|
|
@ -454,9 +467,10 @@ class HVAC_Zoho_Sync {
|
||||||
$sync_succeeded = false;
|
$sync_succeeded = false;
|
||||||
|
|
||||||
// Check if contact already exists in Zoho
|
// Check if contact already exists in Zoho
|
||||||
$search_response = $this->auth->make_api_request('/Contacts/search', 'GET', array(
|
$search_response = $this->auth->make_api_request(
|
||||||
'criteria' => "(Email:equals:{$contact_data['Email']})"
|
'/Contacts/search?criteria=(Email:equals:' . urlencode($contact_data['Email']) . ')',
|
||||||
));
|
'GET'
|
||||||
|
);
|
||||||
|
|
||||||
if (!empty($search_response['data'])) {
|
if (!empty($search_response['data'])) {
|
||||||
// Update existing contact
|
// Update existing contact
|
||||||
|
|
@ -1334,11 +1348,25 @@ class HVAC_Zoho_Sync {
|
||||||
$role = 'Trainee';
|
$role = 'Trainee';
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
// Last_Name is required by Zoho - fallback to display_name or username
|
||||||
|
$last_name = html_entity_decode(get_user_meta($user->ID, 'last_name', true), ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
||||||
|
if (empty(trim($last_name))) {
|
||||||
|
$last_name = $user->display_name ?: $user->user_login;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanitize phone: strip to digits and leading +, require 10+ digits for validity
|
||||||
|
$raw_phone = get_user_meta($user->ID, 'phone_number', true);
|
||||||
|
$phone_digits = preg_replace('/\D/', '', $raw_phone);
|
||||||
|
$phone = '';
|
||||||
|
if (strlen($phone_digits) >= 10) {
|
||||||
|
// Preserve leading + if present, otherwise just use digits
|
||||||
|
$phone = (strpos(trim($raw_phone), '+') === 0 ? '+' : '') . $phone_digits;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = array(
|
||||||
'First_Name' => html_entity_decode(get_user_meta($user->ID, 'first_name', true), ENT_QUOTES | ENT_HTML5, 'UTF-8'),
|
'First_Name' => html_entity_decode(get_user_meta($user->ID, 'first_name', true), ENT_QUOTES | ENT_HTML5, 'UTF-8'),
|
||||||
'Last_Name' => html_entity_decode(get_user_meta($user->ID, 'last_name', true), ENT_QUOTES | ENT_HTML5, 'UTF-8'),
|
'Last_Name' => $last_name,
|
||||||
'Email' => $user->user_email,
|
'Email' => $user->user_email,
|
||||||
'Phone' => get_user_meta($user->ID, 'phone_number', true),
|
|
||||||
'Title' => html_entity_decode(get_user_meta($user->ID, 'hvac_professional_title', true), ENT_QUOTES | ENT_HTML5, 'UTF-8'),
|
'Title' => html_entity_decode(get_user_meta($user->ID, 'hvac_professional_title', true), ENT_QUOTES | ENT_HTML5, 'UTF-8'),
|
||||||
'Company' => html_entity_decode(get_user_meta($user->ID, 'hvac_company_name', true), ENT_QUOTES | ENT_HTML5, 'UTF-8'),
|
'Company' => html_entity_decode(get_user_meta($user->ID, 'hvac_company_name', true), ENT_QUOTES | ENT_HTML5, 'UTF-8'),
|
||||||
'Lead_Source' => 'HVAC Community Events',
|
'Lead_Source' => 'HVAC Community Events',
|
||||||
|
|
@ -1348,6 +1376,13 @@ class HVAC_Zoho_Sync {
|
||||||
'Years_Experience' => get_user_meta($user->ID, 'hvac_years_experience', true),
|
'Years_Experience' => get_user_meta($user->ID, 'hvac_years_experience', true),
|
||||||
'Certification' => get_user_meta($user->ID, 'hvac_certifications', true)
|
'Certification' => get_user_meta($user->ID, 'hvac_certifications', true)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Only include Phone if we have a valid value (10+ digits)
|
||||||
|
if (!empty($phone)) {
|
||||||
|
$data['Phone'] = $phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue