We have developed a plugin that hooks the Elementor Pro form submission to capture the form data and send it to an external API endpoint. However, we are facing some issues with this integration. The API we have integrated with works well with the Contact Form 7 plugin hook, where it returns an error and stores data in the MySQL server. But, in Elementor, the request is sent successfully and a custom response is received from the API. However, there are no validation errors and the data is not saved in the database, which seems weird.
Here’s the Elementor Pro Form Plugin Hook Code
<?php
/*
Plugin Name: Elementor Pro Forms API
Description: Custom hook for Elementor Pro forms submission.
Version: 1.5
Author: Haris Khan
*/
// A send custom WebHook
add_action('elementor_pro/forms/new_record', function ($record, $handler) {
// Make sure it's our form
$form_name = $record->get_form_settings('form_name');
// Replace 'Contact_Form' with the name you gave your form
if ('Contact_Form' !== $form_name) {
return;
}
// Extract form fields
$raw_fields = $record->get('fields');
$fields = [];
foreach ($raw_fields as $id => $field) {
$fields[$id] = $field['value'];
}
// Get user IP address
$user_info = array();
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$user_info['ip'] = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$user_info['ip'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$user_info['ip'] = $_SERVER['REMOTE_ADDR'];
}
// Get user agent
$user_info['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
$fields['ipaddress'] = $user_info['ip'];
// Add source field
$siteName = get_permalink();
$fields['source'] = $siteName;
// Make API request
$response = wp_remote_post('https://myapi.com/elementor-form', [
'body' => $fields,
]);
if (is_wp_error($response)) {
// Handle API request error
$msg = 'There was a problem with the additional webhook.';
$handler->add_error(0, $msg);
$handler->add_error_message($msg);
$handler->is_success = false;
}
// Check for errors in the API response
$api_response = json_decode(wp_remote_retrieve_body($response), true);
if (isset($api_response['status']) && $api_response['status'] === 'error' && isset($api_response['errors'])) {
// Add errors to the form submission
foreach ($api_response['errors'] as $field => $error_message) {
$handler->add_error($field, $error_message);
}
$handler->is_success = false;
}
}, 10, 2);
also provided the API End Point Code in php
public function elementorForm(){
try {
//Rate Limiter
// $key = 'user_'. 123;
// // Set maximum number of requests and time interval (in seconds)
// $maxRequests = 2;
// $interval = 60; // 1 minute
// // Check if the user has exceeded the rate limit
// if (!$this->rateLimiter->limitRequests($key, $maxRequests, $interval)) {
// // Handle the rate limit exceeded error (e.g., show an error message)
// $response = [
// 'status' => 'error',
// 'message' => 'Throttle exceeded. Please try again later.',
// ];
// return $this->response->setStatusCode(200)->setJSON($response);
// }
// Get the input data from the request
$inputData = $this->request->getPost(); // true: convert to associative array
// Define validation rules
$validationRules = [
'name' => 'required|min_length[3]|max_length[25]|regex_match[/^[a-zA-Z]{3,}(?:s[a-zA-Z]*)?$/]',
'phone' => 'required|is_unique[tblLead.appPhone]|regex_match[/^[5-9][0-9]{9}$/]|exact_length[10]',
'channel' => 'required',
'source' => 'required',
// 'ipaddress' => 'required'
];
if (!empty($inputData["email"])) {
$validationRules['email'] = 'required|valid_email|regex_match[/^[^@&%!#$^?*-_.]{3}[^@&%!#$^?]*(?:.[^@&%!#$^?]+)?@[a-zA-Z]{5,10}+.[a-zA-Z]{2,3}$/]';
}
$customErrors = [
'name' => [
'required' => 'The name field is required.',
'min_length' => 'The name must be at least 3 characters long.',
'max_length' => 'The name cannot exceed 25 characters.',
'regex_match' => 'Invalid format for the name field.',
],
'phone' => [
'required' => 'The phone field is required.',
'regex_match' => 'Invalid format for the phone field.',
'exact_length' => 'The phone number must be exactly 10 digits long.',
'is_unique' => 'The phone number is already registered, Please use a different one.',
],
'channel' =>[
'required' => 'The channel field is required.',
],
'source' =>[
'required' => 'The source field is required.',
],
// 'ipaddress' =>[
// 'required' => 'The IP Address field is required.',
// ]
];
if (!empty($inputData["email"])) {
$customErrors["email"] = [
'required' => 'The email field is required.',
'valid_email' => 'Please provide a valid email address.',
'regex_match' => 'Invalid format for the email field.',
];
}
// Run the validation
$validation = ConfigServices::validation();
$validation->setRules($validationRules, $customErrors);
if (!$validation->run($inputData)) {
// Validation failed, return JSON response with custom errors
$errors = $validation->getErrors();
$response = [
'status' => 'error',
'message' => 'Validation failed',
'errors' => $errors,
];
return $this->response->setStatusCode(400)->setJSON($response);
}
$userModel = new UserModel();
// $result = $userModel->insert($inputData);
$result = $userModel->insertUser($inputData);
if($result != null){
$response = [
"message"=>"Data Successfully Inserted",
"result"=>$result
];
return $this->response->setStatusCode(200)->setJSON($response);
}
}catch (Exception $e) {
$response = [
"message"=>"Something went wrong.",
];
return $this->response->setStatusCode(400)->setJSON($response);
}
}
Our pro forms data is not being set in the MYSQL DB despite the API response suggesting otherwise.