Changeset 3367591
- Timestamp:
- 09/25/2025 06:27:46 AM (4 months ago)
- Location:
- integrate-with-zoho-campaigns
- Files:
-
- 79 added
- 9 edited
-
tags/1.0.5 (added)
-
tags/1.0.5/assets (added)
-
tags/1.0.5/assets/css (added)
-
tags/1.0.5/assets/css/ai-settings.css (added)
-
tags/1.0.5/assets/css/auth.css (added)
-
tags/1.0.5/assets/css/banner.css (added)
-
tags/1.0.5/assets/css/error-log.css (added)
-
tags/1.0.5/assets/css/help.css (added)
-
tags/1.0.5/assets/css/home.css (added)
-
tags/1.0.5/assets/css/premium.css (added)
-
tags/1.0.5/assets/css/settings.css (added)
-
tags/1.0.5/assets/css/setup-filter.css (added)
-
tags/1.0.5/assets/css/setup-fm.css (added)
-
tags/1.0.5/assets/img (added)
-
tags/1.0.5/assets/img/close.png (added)
-
tags/1.0.5/assets/img/loading-icon.gif (added)
-
tags/1.0.5/assets/img/loading-icon.png (added)
-
tags/1.0.5/assets/img/loading-icon.svg (added)
-
tags/1.0.5/assets/img/loading.gif (added)
-
tags/1.0.5/assets/img/tick.png (added)
-
tags/1.0.5/assets/img/zoho-logo.png (added)
-
tags/1.0.5/assets/js (added)
-
tags/1.0.5/assets/js/ai-settings.js (added)
-
tags/1.0.5/assets/js/common.js (added)
-
tags/1.0.5/assets/js/error-log.js (added)
-
tags/1.0.5/assets/js/help.js (added)
-
tags/1.0.5/assets/js/home.js (added)
-
tags/1.0.5/assets/js/setup-custom.js (added)
-
tags/1.0.5/assets/js/setup-filter.js (added)
-
tags/1.0.5/assets/js/setup-fm.js (added)
-
tags/1.0.5/includes (added)
-
tags/1.0.5/includes/admin (added)
-
tags/1.0.5/includes/admin/accounts-tab.php (added)
-
tags/1.0.5/includes/admin/admin.php (added)
-
tags/1.0.5/includes/admin/ai-settings-tab.php (added)
-
tags/1.0.5/includes/admin/banner.php (added)
-
tags/1.0.5/includes/admin/errorlog-tab.php (added)
-
tags/1.0.5/includes/admin/premium-tab.php (added)
-
tags/1.0.5/includes/admin/settings-tab.php (added)
-
tags/1.0.5/includes/admin/setup-existing.php (added)
-
tags/1.0.5/includes/admin/setup-new.php (added)
-
tags/1.0.5/includes/admin/setup-tab.php (added)
-
tags/1.0.5/includes/class-includes.php (added)
-
tags/1.0.5/includes/extend (added)
-
tags/1.0.5/includes/extend/auth.php (added)
-
tags/1.0.5/includes/extend/error-log.php (added)
-
tags/1.0.5/includes/extend/extend.php (added)
-
tags/1.0.5/includes/extend/setup.php (added)
-
tags/1.0.5/includes/function (added)
-
tags/1.0.5/includes/function/common-actions.php (added)
-
tags/1.0.5/includes/function/review.php (added)
-
tags/1.0.5/includes/function/session-notice.php (added)
-
tags/1.0.5/includes/includes.php (added)
-
tags/1.0.5/integrate-with-zoho-campaigns.php (added)
-
tags/1.0.5/readme.txt (added)
-
tags/1.0.5/src (added)
-
tags/1.0.5/src/db (added)
-
tags/1.0.5/src/db/account.php (added)
-
tags/1.0.5/src/db/error-log.php (added)
-
tags/1.0.5/src/db/field-mapping.php (added)
-
tags/1.0.5/src/forms (added)
-
tags/1.0.5/src/forms/ai-settings.php (added)
-
tags/1.0.5/src/forms/form-fields.php (added)
-
tags/1.0.5/src/forms/form-group-ids.php (added)
-
tags/1.0.5/src/forms/form-name.php (added)
-
tags/1.0.5/src/forms/forms.php (added)
-
tags/1.0.5/src/forms/id-mapping.php (added)
-
tags/1.0.5/src/forms/smart-form-filter.php (added)
-
tags/1.0.5/src/forms/submit-action.php (added)
-
tags/1.0.5/src/product (added)
-
tags/1.0.5/src/product/account-action.php (added)
-
tags/1.0.5/src/product/action.php (added)
-
tags/1.0.5/src/product/ai-settings-action.php (added)
-
tags/1.0.5/src/product/errorlog-action.php (added)
-
tags/1.0.5/src/product/product.php (added)
-
tags/1.0.5/src/product/settings-action.php (added)
-
tags/1.0.5/src/product/setup-action.php (added)
-
tags/1.0.5/src/product/util.php (added)
-
tags/1.0.5/uninstall.php (added)
-
trunk/includes/admin/admin.php (modified) (1 diff)
-
trunk/includes/extend/auth.php (modified) (2 diffs)
-
trunk/integrate-with-zoho-campaigns.php (modified) (1 diff)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/src/db/account.php (modified) (2 diffs)
-
trunk/src/forms/form-fields.php (modified) (1 diff)
-
trunk/src/forms/form-group-ids.php (modified) (1 diff)
-
trunk/src/forms/form-name.php (modified) (1 diff)
-
trunk/src/forms/submit-action.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
integrate-with-zoho-campaigns/trunk/includes/admin/admin.php
r3261395 r3367591 36 36 wp_enqueue_script('jquery'); 37 37 38 // Define assets for CSS and JS with cache-busting versioning.38 // Define assets for CSS and JS with busting versioning. 39 39 $assets = [ 40 40 'css' => ['home', 'auth', 'setup-fm', 'setup-filter', 'premium', 'settings', 'ai-settings', 'help', 'banner', 'error-log'], -
integrate-with-zoho-campaigns/trunk/includes/extend/auth.php
r3261395 r3367591 19 19 { 20 20 global $blog_id; 21 22 // Dynamically set cache key for multisite compatibility23 $this->cache_key = "iafwzcai_all_account_data_{$blog_id}";24 21 25 22 // Initialize parent class with the required arguments … … 59 56 $this->_column_headers = [$columns, $hidden, $sortable]; 60 57 61 // Retrieve account data from cache 62 $account_items = wp_cache_get($this->cache_key); 63 if ($account_items === false) { 64 // If not cached, fetch all account data 65 $account_items = $iafwzcai_accountDBInstance->get_account_data(); 66 } 58 $account_items = $iafwzcai_accountDBInstance->get_account_data(); 67 59 68 60 // Check if $account_items is an array with data -
integrate-with-zoho-campaigns/trunk/integrate-with-zoho-campaigns.php
r3330797 r3367591 5 5 * Plugin URI: https://integrazo.com/products/integrate-with-zoho-campaigns 6 6 * Description: Automatically send contact form submissions from popular WordPress forms to Zoho Campaigns and grow your business. 7 * Version: 1.0. 47 * Version: 1.0.5 8 8 * Author: Integrazo 9 9 * Author URI: https://integrazo.com/ -
integrate-with-zoho-campaigns/trunk/readme.txt
r3330797 r3367591 5 5 Tested up to: 6.8 6 6 Requires PHP: 7.4 7 Stable tag: 1.0. 47 Stable tag: 1.0.5 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 347 347 == Changelog == 348 348 349 = 1.0.5 = 350 * Changed: Elementor Forms integration flow updated for smoother setup 351 * Improved: Better results and reliability when mapping Elementor form fields 352 349 353 = 1.0.4 = 350 354 * Added: New FAQ about disabling specific integrations -
integrate-with-zoho-campaigns/trunk/src/db/account.php
r3261395 r3367591 118 118 global $wpdb, $blog_id; 119 119 120 // Cache key for all account data with multisite compatibility121 $cache_key = "iafwzcai_all_account_data_{$blog_id}";122 123 // Attempt to get data from cache without specifying a group124 $cached_data = wp_cache_get($cache_key);125 126 if ($cached_data !== false) {127 return $cached_data;128 }129 130 120 // Fetch all account data from the database 131 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery 121 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching 132 122 $data = $wpdb->get_results("SELECT * FROM " . esc_sql($this->table_name), ARRAY_A); 133 123 … … 136 126 return []; 137 127 } 138 139 // Store the fetched data in cache for future requests without a group140 wp_cache_set($cache_key, $data, '', HOUR_IN_SECONDS);141 128 142 129 return $data; -
integrate-with-zoho-campaigns/trunk/src/forms/form-fields.php
r3309840 r3367591 313 313 * @return array Array of form fields, each containing the field ID, label, and type. 314 314 */ 315 public function getElementorFormFields($ form_id)316 { 317 $ form_fields= [];318 319 // ✅ Check if Elementor Pro class exists320 if (! class_exists('\ElementorPro\Modules\Forms\Submissions\Database\Repositories\Form_Snapshot_Repository')) {321 return $ form_fields;315 public function getElementorFormFields($combined_id) 316 { 317 $empty = []; 318 319 // Require Elementor Core + Pro 320 if (! did_action('elementor/loaded') || ! defined('ELEMENTOR_PRO_VERSION')) { 321 return $empty; 322 322 } 323 323 324 324 try { 325 $formsnaps = \ElementorPro\Modules\Forms\Submissions\Database\Repositories\Form_Snapshot_Repository::instance()->all(); 326 327 foreach ($formsnaps as $form) { 328 if ($form->id === $form_id) { 329 // ✅ Found matching form ID → now get fields 330 if (!empty($form->fields) && is_array($form->fields)) { 331 foreach ($form->fields as $field) { 332 $form_fields[] = [ 333 'key' => $field['id'] ?? '', 334 'label' => $field['label'] ?? '', 335 'type' => $field['type'] ?? 'text', 336 'source' => 'form' 337 ]; 325 // Expect "{post_id}_{form_widget_id}" (widget id may contain underscores → limit=2) 326 $parts = explode('_', (string) $combined_id, 2); 327 if (count($parts) < 2) return $empty; 328 329 $post_id = (int) $parts[0]; 330 $form_widget_id = trim((string) $parts[1]); 331 if ($post_id <= 0 || $form_widget_id === '') return $empty; 332 333 // Prefer _elementor_data; fallback to post_content 334 $raw = get_post_meta($post_id, '_elementor_data', true); 335 if (! is_string($raw) || $raw === '') { 336 $raw = (string) get_post_field('post_content', $post_id); 337 if ($raw === '') return $empty; 338 } 339 340 // Tolerant decode (no pre-unslash) 341 $data = $this->decode_elementor_json($raw); 342 if (! is_array($data)) return $empty; 343 344 // Walk the structure to find the exact form widget 345 $fields_out = []; 346 $iterator = new RecursiveIteratorIterator( 347 new RecursiveArrayIterator($data), 348 RecursiveIteratorIterator::SELF_FIRST 349 ); 350 351 foreach ($iterator as $node) { 352 if ( 353 is_array($node) 354 && ($node['elType'] ?? null) === 'widget' 355 && ($node['widgetType'] ?? null) === 'form' 356 && ($node['id'] ?? null) === $form_widget_id 357 ) { 358 $form_fields = $node['settings']['form_fields'] ?? []; 359 if (! is_array($form_fields)) break; 360 361 foreach ($form_fields as $field) { 362 if (! is_array($field)) continue; 363 364 $type = (string) ($field['field_type'] ?? 'text'); 365 366 // Skip internal/non-mappable types 367 if (in_array($type, ['step', 'html', 'recaptcha', 'recaptcha_v3', 'honeypot'], true)) { 368 continue; 338 369 } 370 371 $key = isset($field['_id']) ? (string) $field['_id'] : ''; 372 if ($key === '') continue; 373 374 $label = (string) ($field['field_label'] ?? ''); 375 if ($label === '') $label = ucfirst($type); 376 377 $fields_out[] = [ 378 'key' => $key, 379 'type' => $type, 380 'label' => $label, 381 'source' => 'form', 382 ]; 339 383 } 340 break; // ✅ Form found → no need to check others 341 } 342 } 343 return $form_fields; 384 break; // matched widget found; stop scanning 385 } 386 } 387 388 return $fields_out; 344 389 } catch (Throwable $e) { 345 return $form_fields; 346 } 390 return $empty; // fail safe 391 } 392 } 393 private function decode_elementor_json($raw) 394 { 395 $data = json_decode($raw, true); 396 if (is_array($data)) return $data; 397 398 if (function_exists('wp_unslash')) { 399 $data = json_decode(wp_unslash($raw), true); 400 if (is_array($data)) return $data; 401 } 402 403 if (function_exists('mb_convert_encoding')) { 404 $fixed = mb_convert_encoding($raw, 'UTF-8', 'UTF-8'); 405 $data = json_decode($fixed, true); 406 if (is_array($data)) return $data; 407 } 408 409 return null; 347 410 } 348 411 /** -
integrate-with-zoho-campaigns/trunk/src/forms/form-group-ids.php
r3309840 r3367591 270 270 * @return array Array of forms with their IDs, names, and fields. 271 271 */ 272 /** ========================= 273 * ELEMENTOR FORMS LISTING (clean) 274 * ========================= */ 272 275 public function getElementorForms() 273 276 { 274 277 $form_list = []; 275 278 276 if (! class_exists('\ElementorPro\Modules\Forms\Submissions\Database\Repositories\Form_Snapshot_Repository')) { 277 return $form_list; // Return empty if class not found 278 } 279 280 try { 281 $formsnaps = \ElementorPro\Modules\Forms\Submissions\Database\Repositories\Form_Snapshot_Repository::instance()->all(); 282 283 foreach ($formsnaps as $form) { 284 $page_title = get_the_title($form->post_id); 285 286 $form_list[] = [ 287 'id' => $form->id, 288 'name' => $form->name . ' - ' . $page_title, 289 ]; 290 } 291 279 // Require Elementor Core + Pro 280 if (! did_action('elementor/loaded') || ! defined('ELEMENTOR_PRO_VERSION')) { 292 281 return $form_list; 293 } catch (Throwable $e) { 282 } 283 284 try { 285 $args = [ 286 'post_type' => ['page', 'post', 'elementor_library'], 287 'posts_per_page' => -1, 288 'post_status' => 'any', 289 'fields' => 'ids', 290 // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query 291 'meta_query' => [ 292 [ 293 'key' => '_elementor_data', 294 'compare' => 'EXISTS', 295 ], 296 ], 297 ]; 298 299 $posts = get_posts($args); 300 if (empty($posts) || is_wp_error($posts)) { 301 return $form_list; 302 } 303 304 foreach ($posts as $post_id) { 305 $raw = get_post_meta($post_id, '_elementor_data', true); 306 if ($raw === '' || $raw === null) { 307 continue; 308 } 309 310 // Tolerant decode (no pre-unslash) 311 $data = $this->decode_elementor_json($raw); 312 if (! is_array($data)) { 313 continue; 314 } 315 316 // Find Elementor Form widgets 317 $iterator = new RecursiveIteratorIterator( 318 new RecursiveArrayIterator($data), 319 RecursiveIteratorIterator::SELF_FIRST 320 ); 321 322 foreach ($iterator as $node) { 323 if ( 324 is_array($node) 325 && ($node['elType'] ?? null) === 'widget' 326 && ($node['widgetType'] ?? null) === 'form' 327 && ! empty($node['id']) 328 ) { 329 $form_name = ! empty($node['settings']['form_name']) 330 ? (string) $node['settings']['form_name'] 331 : 'Untitled Form'; 332 333 $form_id = (string) $node['id']; // Elementor widget id 334 $title = get_the_title($post_id); 335 336 $form_list[] = [ 337 'id' => $post_id . '_' . $form_id, // combined id for lookup 338 'name' => sprintf('%s (Page: %s)', $form_name, $title), 339 ]; 340 } 341 } 342 } 343 294 344 return $form_list; 295 } 345 } catch (Throwable $e) { 346 return $form_list; 347 } 348 } 349 350 /** ========================= 351 * Tolerant JSON decoder (no side-effects) 352 * ========================= */ 353 private function decode_elementor_json($raw) 354 { 355 // 1) Try as-is 356 $data = json_decode($raw, true); 357 if (is_array($data)) return $data; 358 359 // 2) Try unslash 360 if (function_exists('wp_unslash')) { 361 $data = json_decode(wp_unslash($raw), true); 362 if (is_array($data)) return $data; 363 } 364 365 // 3) Normalize encoding (rare) 366 if (function_exists('mb_convert_encoding')) { 367 $fixed = mb_convert_encoding($raw, 'UTF-8', 'UTF-8'); 368 $data = json_decode($fixed, true); 369 if (is_array($data)) return $data; 370 } 371 372 return null; 296 373 } 297 374 } -
integrate-with-zoho-campaigns/trunk/src/forms/form-name.php
r3309840 r3367591 115 115 * Retrieves the name of an Elementor Form by form ID. 116 116 */ 117 public function getElementorFormName($form_id) 118 { 119 // Return empty string by default 120 $form_name = ''; 121 122 // ✅ Check if Elementor Pro class exists 123 if (! class_exists('\ElementorPro\Modules\Forms\Submissions\Database\Repositories\Form_Snapshot_Repository')) { 124 return $form_name; 117 public function getElementorFormName($combined_id) 118 { 119 $empty = ''; 120 121 // Elementor core + Pro required 122 if (! did_action('elementor/loaded') || ! defined('ELEMENTOR_PRO_VERSION')) { 123 return $empty; 125 124 } 126 125 127 126 try { 128 $formsnaps = \ElementorPro\Modules\Forms\Submissions\Database\Repositories\Form_Snapshot_Repository::instance()->all(); 129 130 foreach ($formsnaps as $form) { 131 if ($form->id === $form_id) { 132 $page_title = get_the_title($form->post_id); 133 $form_name = $form->name . ' - ' . $page_title; 134 break; // Found → exit loop 127 // Expect "{post_id}_{form_widget_id}" (widget id may contain underscores → limit=2) 128 $parts = explode('_', (string) $combined_id, 2); 129 if (count($parts) < 2) return $empty; 130 131 $post_id = (int) $parts[0]; 132 $form_widget_id = trim((string) $parts[1]); 133 if ($post_id <= 0 || $form_widget_id === '') return $empty; 134 135 // Prefer _elementor_data; fallback to post_content 136 $raw = get_post_meta($post_id, '_elementor_data', true); 137 if (! is_string($raw) || $raw === '') { 138 $raw = (string) get_post_field('post_content', $post_id); 139 if ($raw === '') return $empty; 140 } 141 142 // Tolerant decode (no pre-unslash) 143 $data = $this->decode_elementor_json($raw); 144 if (! is_array($data)) return $empty; 145 146 // Traverse to find the exact form widget 147 $iterator = new RecursiveIteratorIterator( 148 new RecursiveArrayIterator($data), 149 RecursiveIteratorIterator::SELF_FIRST 150 ); 151 152 foreach ($iterator as $node) { 153 if ( 154 is_array($node) 155 && ($node['elType'] ?? null) === 'widget' 156 && ($node['widgetType'] ?? null) === 'form' 157 && ($node['id'] ?? null) === $form_widget_id 158 ) { 159 $name = (string) ($node['settings']['form_name'] ?? ''); 160 $name = trim($name); 161 if ($name === '') $name = 'Untitled Form'; 162 163 // Cap extreme lengths safely (multibyte-aware) 164 if (function_exists('mb_strlen') && mb_strlen($name) > 120) { 165 $name = mb_substr($name, 0, 117) . '...'; 166 } 167 168 return $name; 135 169 } 136 170 } 137 171 138 return $ form_name;172 return $empty; 139 173 } catch (Throwable $e) { 140 return $form_name; // return empty string if error 141 } 174 return $empty; 175 } 176 } 177 /** 178 * Tolerant decoder for Elementor JSON: as-is → unslash → encoding normalize. 179 */ 180 private function decode_elementor_json($raw) 181 { 182 // 1) Try as-is 183 $data = json_decode($raw, true); 184 if (is_array($data)) return $data; 185 186 // 2) Try unslash (if meta stored with added slashes) 187 if (function_exists('wp_unslash')) { 188 $data = json_decode(wp_unslash($raw), true); 189 if (is_array($data)) return $data; 190 } 191 192 // 3) Normalize encoding (rare but safe) 193 if (function_exists('mb_convert_encoding')) { 194 $fixed = mb_convert_encoding($raw, 'UTF-8', 'UTF-8'); 195 $data = json_decode($fixed, true); 196 if (is_array($data)) return $data; 197 } 198 199 return null; 142 200 } 143 201 -
integrate-with-zoho-campaigns/trunk/src/forms/submit-action.php
r3309840 r3367591 363 363 { 364 364 $IAFWZCAI_Field_MappingDBInstance = new IAFWZCAI_Field_Mapping(); 365 try { 366 // Retrieve form ID and group ID 367 $form_details = $handler->get_current_form(); 368 $form_id = $form_details['id']; 369 $form_group_id = 7; // Set form group ID for Elementor Forms 365 366 try { 367 // --- Build combined form ID: {postId}_{widgetId} 368 $form_widget_id = (string) $record->get_form_settings('id'); 369 $form_post_id = (int) $record->get_form_settings('form_post_id'); 370 if ($form_post_id <= 0 || $form_widget_id === '') { 371 return; 372 } 373 $form_id = $form_post_id . '_' . $form_widget_id; 374 $form_group_id = 7; // Elementor Forms group 375 // --- License/session check 370 376 $session = iafwzcai_is_valid_key(); 371 if (!$session) { 377 if (! $session) { 378 // If session invalid, block and stop further processing 372 379 $IAFWZCAI_Field_MappingDBInstance->block_field_mapping(); 373 380 } 374 // Retrieve field mapping details 381 382 // --- Get mapping rows for this form 375 383 $field_mapping_list = $IAFWZCAI_Field_MappingDBInstance->get_mapping_by_id($form_id, $form_group_id); 376 377 // Prepare form data for CRM 378 $raw_fields = $record->get('fields'); 384 if (empty($field_mapping_list)) { 385 return; // nothing to do 386 } 387 388 // --- Read form fields and submitted values 379 389 $form_data = []; 380 390 381 if (!empty($raw_fields)) { 382 foreach ($raw_fields as $field_key => $field_data) { 383 $form_data[$field_key] = $field_data['value'] ?? ''; // Ensure value is retrieved safely 384 } 385 } 386 387 // Process each field mapping 388 if (!empty($field_mapping_list)) { 389 foreach ($field_mapping_list as $field_mapping_details) { 390 if ((int)$field_mapping_details->integration_status === 1) { 391 392 $filter_criteria = $this->filter_criteria($form_data, $field_mapping_details->filter_criteria); 393 if ($filter_criteria === 1) { 394 // Map data and process submission 395 $crm_data = $this->map_form_data_to_crm($form_data, $field_mapping_details, 'elementor_forms'); 396 397 // Submit data to CRM and handle response 398 $response = $this->process_form_submission($form_data, $crm_data, $field_mapping_details); 399 400 // Log errors if the submission fails 401 $this->check_and_add_error_log($response, $form_data, $crm_data, $field_mapping_details); 402 } 403 } 404 } 405 } 406 } catch (Throwable $e) { 407 // Log the error for debugging purposes 391 // Definitions from form settings (builder-time) 392 $form_fields = $record->get_form_settings('form_fields'); 393 $form_fields = is_array($form_fields) ? $form_fields : []; 394 395 // Build map: custom_id => _id (to normalize submitted keys) 396 $custom_id_map = []; 397 foreach ($form_fields as $field_def) { 398 if (is_array($field_def) && isset($field_def['custom_id'], $field_def['_id'])) { 399 $custom_id_map[(string) $field_def['custom_id']] = (string) $field_def['_id']; 400 } 401 } 402 403 // Submitted runtime values 404 $raw_fields = $record->get('fields'); // ElementorPro\Forms\Record stores submitted fields here 405 $raw_fields = is_array($raw_fields) ? $raw_fields : []; 406 foreach ($raw_fields as $id => $field) { 407 if (! is_array($field)) { 408 continue; 409 } 410 411 $value = $field['value'] ?? ''; 412 $type = $field['type'] ?? ''; 413 414 // Normalize key to builder _id if we have custom_id 415 $field_key = isset($custom_id_map[$id]) ? $custom_id_map[$id] : (string) $id; 416 417 if ($type === 'upload') { 418 // Elementor may give array or CSV; normalize to array of paths 419 if (is_array($value)) { 420 $paths = array_map('strval', $value); 421 } else { 422 $paths = array_map('trim', explode(',', (string) $value)); 423 $paths = array_filter($paths, static function ($p) { 424 return $p !== ''; 425 }); 426 } 427 $form_data[$field_key] = array_values($paths); 428 } else { 429 // Scalar value as string 430 if (is_array($value)) { 431 // For checkbox/multi-select, implode safely 432 $form_data[$field_key] = implode(', ', array_map('strval', $value)); 433 } else { 434 $form_data[$field_key] = (string) $value; 435 } 436 } 437 } 438 439 // --- Process each active mapping 440 foreach ($field_mapping_list as $field_mapping_details) { 441 if ((int) $field_mapping_details->integration_status !== 1) { 442 continue; 443 } 444 445 $filter_ok = $this->filter_criteria($form_data, $field_mapping_details->filter_criteria); 446 if ((int) $filter_ok !== 1) { 447 continue; 448 } 449 450 // Build CRM payload and send 451 $crm_data = $this->map_form_data_to_crm($form_data, $field_mapping_details, 'elementor_forms'); 452 453 $response = $this->process_form_submission($form_data, $crm_data, $field_mapping_details); 454 455 // Log errors if any 456 $this->check_and_add_error_log($response, $form_data, $crm_data, $field_mapping_details); 457 } 458 } catch (Throwable $e) { 459 // Optional debug: 460 return; 408 461 } 409 462 }
Note: See TracChangeset
for help on using the changeset viewer.