PluginProbe
E2Pdf – Export Pdf Tool for WordPress / 1.32.49
E2Pdf – Export Pdf Tool for WordPress v1.32.49
1.32.49 1.32.48 1.32.43 1.32.40 1.32.34 1.32.32 1.32.31 1.32.26 1.32.22 1.32.23 1.32.18 1.32.17 1.32.15 trunk 1.00.00 1.00.13 1.01.01 1.02.02 1.03.07 1.04.07 1.05.03 1.06.02 1.07.11 1.08.00 1.08.06 All 72 releases
e2pdf / classes / extension / e2pdf-divi.php

e2pdf-divi.php in E2Pdf – Export Pdf Tool for WordPress 1.32.49, at classes/extension/e2pdf-divi.php

2,161 lines 108.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * File: /extension/e2pdf-divi.php
5 *
6 * @package E2Pdf
7 * @license GPLv3
8 * @link https://e2pdf.com
9 */
10 if (!defined('ABSPATH')) {
11 die('Access denied.');
12 }
13
14 class Extension_E2pdf_Divi extends Model_E2pdf_Model {
15
16 private $options;
17 private $info = [
18 'key' => 'divi',
19 'title' => 'Divi Forms',
20 ];
21
22 // info
23 public function info($key = false) {
24 if ($key && isset($this->info[$key])) {
25 return $this->info[$key];
26 } else {
27 return [
28 $this->info['key'] => $this->info['title'],
29 ];
30 }
31 }
32
33 // active
34 public function active() {
35 if (file_exists(get_template_directory() . '/et-pagebuilder/et-pagebuilder.php')) {
36 return true;
37 } else {
38 if (defined('E2PDF_DIVI_EXTENSION') || $this->helper->load('extension')->is_plugin_active('divi-builder/divi-builder.php')) {
39 return true;
40 }
41 }
42 return false;
43 }
44
45 // set
46 public function set($key, $value) {
47 if (!isset($this->options)) {
48 $this->options = new stdClass();
49 }
50 $this->options->$key = $value;
51 switch ($key) {
52 case 'dataset':
53 $this->set('cached_entry', []);
54 $this->set('cached_meta', []);
55 if ($this->get('item') && $this->get('dataset')) {
56 $entry = new Model_E2pdf_Dataset();
57 if ($entry->load($this->get('dataset'), $this->get('item'), 'divi')) {
58 $cached_entry = $entry->get('entry');
59 $this->set('cached_entry', $cached_entry);
60
61 $meta_data = [];
62 if ($cached_entry && is_array($cached_entry)) {
63 // Divi5
64 if (!empty($cached_entry['E2PDF_VERSION'])) {
65 foreach ($cached_entry['fields'] as $field_key => $field) {
66 if (isset($field['type'])) {
67 switch ($field['type']) {
68 case 'signature-pad':
69 $meta_data['%%' . $field_key . '%%'] = $this->pwh_dcfh_resolve_file_url($field['value'], $cached_entry['options']);
70 break;
71 case 'file':
72 $attachments = is_array($field['value']) ? $field['value'] : explode(',', $field['value']);
73 foreach ($attachments as $attachment_key => $attachment) {
74 $attachments[$attachment_key] = $this->pwh_dcfh_resolve_file_url($attachment, $cached_entry['options']);
75 }
76 $meta_data['%%' . $field_key . '%%'] = implode(',', $attachments);
77 break;
78 default:
79 $meta_data['%%' . $field_key . '%%'] = is_array($field['value']) ? implode(', ', $field['value']) : $field['value'];
80 break;
81 }
82 }
83 }
84 } elseif (!empty($cached_entry['ET_CORE_VERSION'])) {
85 foreach ($cached_entry as $field_key => $value) {
86 $meta_data['%%' . $field_key . '%%'] = is_array($value) ? implode(', ', $value) : $value;
87 }
88 if (!isset($meta_data['%%e2pdf_entry_id%%'])) {
89 $meta_data['%%e2pdf_entry_id%%'] = (int) $this->get('dataset');
90 }
91 } else {
92 // Divi4
93 $processed_fields_values = [];
94 $et_contact_proccess = array_search('et_contact_proccess', $cached_entry);
95 $et_pb_contact_form_num = $et_contact_proccess === false ? 0 : str_replace('et_pb_contactform_submit_', '', $et_contact_proccess);
96 $current_form_fields = isset($cached_entry['et_pb_contact_email_fields_' . $et_pb_contact_form_num]) ? $cached_entry['et_pb_contact_email_fields_' . $et_pb_contact_form_num] : '';
97 if ('' !== $current_form_fields) {
98 $fields_data_json = str_replace('\\', '', $current_form_fields);
99 $fields_data_array = json_decode($fields_data_json, true);
100 if (!empty($fields_data_array)) {
101 foreach ($fields_data_array as $field_value) {
102 $processed_fields_values[$field_value['original_id']]['value'] = isset($cached_entry[$field_value['field_id']]) ? $cached_entry[$field_value['field_id']] : '';
103 $processed_fields_values[$field_value['original_id']]['label'] = $field_value['field_label'];
104
105 $is_file = isset($cached_entry[$field_value['field_id'] . '_is_file']) && $cached_entry[$field_value['field_id'] . '_is_file'] == 'yes';
106 $is_signature_pad = isset($cached_entry[$field_value['field_id'] . '_is_signature_pad']) && $cached_entry[$field_value['field_id'] . '_is_signature_pad'] == 'yes';
107
108 if (($is_signature_pad || $is_file) && $processed_fields_values[$field_value['original_id']]['value']) {
109 $subdir = isset($cached_entry['_subdir']) ? $cached_entry['_subdir'] : '';
110 if (isset($cached_entry['_save_files_to_media']) && $cached_entry['_save_files_to_media'] == 'on') {
111 if ($subdir && !file_exists(path_join(wp_upload_dir()['basedir'] . $subdir, $processed_fields_values[$field_value['original_id']]['value'])) && preg_match('/^\/\d{4}\/\d{2}$/', $subdir)) {
112 $tmpsubdir = '/' . date('Y/m', strtotime(str_replace('/', '-', ltrim($subdir, '/')) . ' -1 month'));
113 if (file_exists(path_join(wp_upload_dir()['basedir'] . $tmpsubdir, $processed_fields_values[$field_value['original_id']]['value']))) {
114 $subdir = $tmpsubdir;
115 }
116 }
117 $processed_fields_values[$field_value['original_id']]['value'] = path_join(wp_upload_dir()['baseurl'] . $subdir, $processed_fields_values[$field_value['original_id']]['value']);
118 } else {
119 $contact_form_id = isset($cached_entry['_unique_id']) ? $cached_entry['_unique_id'] : '';
120 if (function_exists('pwh_dcfh_file_helpers') && $contact_form_id) {
121 if ($subdir && !file_exists(pwh_dcfh_file_helpers()::get_form_upload_dir($contact_form_id, $subdir, $processed_fields_values[$field_value['original_id']]['value'])) && preg_match('/^\d{4}\/\d{2}$/', $subdir)) {
122 $tmpsubdir = date('Y/m', strtotime(str_replace('/', '-', ltrim($subdir, '/')) . " -1 month"));
123 if (file_exists(pwh_dcfh_file_helpers()::get_form_upload_dir($contact_form_id, $tmpsubdir, $processed_fields_values[$field_value['original_id']]['value']))) {
124 $subdir = $tmpsubdir;
125 }
126 }
127 $processed_fields_values[$field_value['original_id']]['value'] = pwh_dcfh_file_helpers()::get_form_upload_url($contact_form_id, $subdir, $processed_fields_values[$field_value['original_id']]['value']);
128 } elseif (function_exists('ks_pac_dcfh_file_helper') && $contact_form_id) {
129 if ($subdir && !file_exists(ks_pac_dcfh_file_helper()::get_form_upload_dir($contact_form_id, $subdir, $processed_fields_values[$field_value['original_id']]['value'])) && preg_match('/^\d{4}\/\d{2}$/', $subdir)) {
130 $tmpsubdir = date('Y/m', strtotime(str_replace('/', '-', ltrim($subdir, '/')) . " -1 month"));
131 if (file_exists(ks_pac_dcfh_file_helper()::get_form_upload_dir($contact_form_id, $tmpsubdir, $processed_fields_values[$field_value['original_id']]['value']))) {
132 $subdir = $tmpsubdir;
133 }
134 }
135 $processed_fields_values[$field_value['original_id']]['value'] = ks_pac_dcfh_file_helper()::get_form_upload_url($contact_form_id, $subdir, $processed_fields_values[$field_value['original_id']]['value']);
136 } else {
137 $processed_fields_values[$field_value['original_id']]['value'] = '';
138 }
139 }
140 }
141 }
142 }
143 }
144 if (!isset($processed_fields_values['_wp_http_referer'])) {
145 $processed_fields_values['_wp_http_referer'] = [
146 'value' => isset($cached_entry['_wp_http_referer']) ? $cached_entry['_wp_http_referer'] : '',
147 'label' => '_wp_http_referer',
148 ];
149 }
150 if (!isset($processed_fields_values['e2pdf_entry_id'])) {
151 $processed_fields_values['e2pdf_entry_id'] = [
152 'value' => (int) $this->get('dataset'),
153 'label' => 'e2pdf_entry_id',
154 ];
155 }
156 foreach ($processed_fields_values as $field_key => $field_value) {
157 $meta_data['%%' . $field_key . '%%'] = $field_value['value'];
158 }
159 }
160 }
161 $this->set('cached_meta', $meta_data);
162 }
163 }
164 break;
165 default:
166 break;
167 }
168 }
169
170 // get
171 public function get($key) {
172 if (isset($this->options->$key)) {
173 $value = $this->options->$key;
174 } else {
175 switch ($key) {
176 case 'args':
177 case 'cached_entry':
178 case 'cached_meta':
179 $value = [];
180 break;
181 default:
182 $value = false;
183 break;
184 }
185 }
186 return $value;
187 }
188
189 // items
190 public function items() {
191 global $wpdb;
192 $condition = [
193 'post_content' => [
194 'condition' => 'LIKE',
195 'value' => '%et_pb_contact_form%',
196 'type' => '%s',
197 'or' => [
198 [
199 'post_content' => [
200 'condition' => 'LIKE',
201 'value' => '%wp:divi/contact-form%',
202 'type' => '%s',
203 ],
204 ],
205 ],
206 ],
207 'post_type' => [
208 'condition' => '<>',
209 'value' => [
210 'revision',
211 'et_pb_layout',
212 ],
213 'type' => '%s',
214 ],
215 ];
216 $order_condition = [
217 'orderby' => 'id',
218 'order' => 'desc',
219 ];
220 $where = $this->helper->load('db')->prepare_where($condition);
221 $orderby = $this->helper->load('db')->prepare_orderby($order_condition);
222 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
223 $posts = $wpdb->get_results($wpdb->prepare('SELECT * FROM `' . $wpdb->prefix . 'posts`' . $where['sql'] . $orderby . '', $where['filter']));
224
225 $content = [];
226 foreach ($posts as $key => $post) {
227 foreach ($this->get_forms($post->post_content) as $form_key => $form_value) {
228 $content[] = $this->item($form_key);
229 }
230 }
231 return $content;
232 }
233
234 // get forms
235 public function get_forms($content) {
236 $forms = [];
237
238 if ($this->divi4_form($content)) {
239 $shortcode_tags = [
240 'et_pb_contact_form',
241 ];
242 preg_match_all('@\[([^<>&/\[\]\x00-\x20=]++)@', $content, $matches);
243 $tagnames = array_intersect($shortcode_tags, $matches[1]);
244 if (!empty($tagnames)) {
245 preg_match_all('/' . $this->helper->load('shortcode')->get_shortcode_regex($tagnames) . '/', $content, $shortcodes);
246 foreach ($shortcodes[0] as $key => $shortcode_value) {
247 $shortcode = $this->helper->load('shortcode')->get_shortcode($shortcodes, $key);
248 preg_match_all('/admin_label="(.*?)"/', $shortcode[3], $labels);
249 if (isset($labels['1'])) {
250 foreach ($labels['1'] as $label) {
251 $forms[$label] = $label;
252 }
253 }
254 }
255 }
256 } elseif ($this->divi5_form($content)) {
257 $blocks = $this->get_forms_blocks(parse_blocks($content));
258 foreach ($blocks as $block) {
259 $label = !empty($block['attrs']['module']['meta']['adminLabel']['desktop']['value']) ? $block['attrs']['module']['meta']['adminLabel']['desktop']['value'] : '';
260 if ($label) {
261 $forms[$label] = $label;
262 }
263 }
264 }
265 return $forms;
266 }
267
268 // datasets
269 public function datasets($item_id = false, $name = false) {
270 global $wpdb;
271 $datasets = [];
272 if ($item_id) {
273 $condition = [
274 'extension' => [
275 'condition' => '=',
276 'value' => 'divi',
277 'type' => '%s',
278 ],
279 'item' => [
280 'condition' => '=',
281 'value' => $item_id,
282 'type' => '%s',
283 ],
284 ];
285 $order_condition = [
286 'orderby' => 'ID',
287 'order' => 'desc',
288 ];
289 $where = $this->helper->load('db')->prepare_where($condition);
290 $orderby = $this->helper->load('db')->prepare_orderby($order_condition);
291 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
292 $entries = $wpdb->get_results($wpdb->prepare('SELECT * FROM `' . $wpdb->prefix . 'e2pdf_datasets`' . $where['sql'] . $orderby . '', $where['filter']));
293
294 if ($entries) {
295 $this->set('item', $item_id);
296 foreach ($entries as $key => $entry) {
297 $this->set('dataset', $entry->ID);
298 $entry_title = $this->render($name);
299 if (!$entry_title) {
300 $entry_title = $entry->ID;
301 }
302 $datasets[] = [
303 'key' => $entry->ID,
304 'value' => $entry_title,
305 ];
306 }
307 }
308 }
309 return $datasets;
310 }
311
312 // get dataset actions
313 public function get_dataset_actions($dataset_id = false) {
314 $dataset_id = (int) $dataset_id;
315 if (!$dataset_id) {
316 return;
317 }
318 $actions = new stdClass();
319 $actions->view = false;
320 $actions->delete = true;
321 return $actions;
322 }
323
324 // get template actions
325 public function get_template_actions($template = false) {
326 $template = (int) $template;
327 if (!$template) {
328 return;
329 }
330 $actions = new stdClass();
331 $actions->delete = true;
332 return $actions;
333 }
334
335 // get forms blocks
336 public function get_forms_blocks($blocks) {
337 $forms = [];
338 foreach ($blocks as $block) {
339 if ('divi/contact-form' === $block['blockName']) {
340 $forms[] = $block;
341 }
342 if (!empty($block['innerBlocks'])) {
343 $nested_forms = $this->get_forms_blocks($block['innerBlocks']);
344 $forms = array_merge($forms, $nested_forms);
345 }
346 }
347 return $forms;
348 }
349
350 // get fields blocks
351 public function get_fields_blocks($form) {
352 $fields = [];
353 if (!empty($form['innerBlocks'])) {
354 foreach ($form['innerBlocks'] as $block) {
355 if ('divi/contact-field' === $block['blockName']) {
356 $field_type = !empty($block['attrs']['fieldItem']['advanced']['type']['desktop']['value']) ? $block['attrs']['fieldItem']['advanced']['type']['desktop']['value'] : '';
357 $field_label = !empty($block['attrs']['fieldItem']['innerContent']['desktop']['value']) ? $block['attrs']['fieldItem']['innerContent']['desktop']['value'] : '';
358 $field_id = !empty($block['attrs']['fieldItem']['advanced']['id']['desktop']['value']) ? $block['attrs']['fieldItem']['advanced']['id']['desktop']['value'] : '';
359 $fields[] = [
360 'field_type' => $field_type,
361 'field_title' => $field_label,
362 'field_id' => $field_id,
363 ];
364 }
365 if (!empty($block['innerBlocks'])) {
366 $nested_fields = $this->get_fields_blocks($block);
367 $fields = array_merge($fields, $nested_fields);
368 }
369 }
370 }
371 return $fields;
372 }
373
374 // item
375 public function item($item_id = false) {
376 if (!$item_id && $this->get('item')) {
377 $item_id = $this->get('item');
378 }
379 $item = new stdClass();
380 if ($item_id) {
381 $item->id = (string) $item_id;
382 $item->name = $item_id;
383 $form = $this->get_form($item_id);
384 if (isset($form->ID)) {
385 $item->url = $this->helper->get_url(
386 [
387 'post' => $form->ID,
388 'action' => 'edit',
389 ], 'post.php?'
390 );
391 } else {
392 $item->url = '';
393 }
394 } else {
395 $item->id = '';
396 $item->name = '';
397 $item->url = '';
398 }
399 return $item;
400 }
401
402 // get form
403 public function get_form($item_id = false) {
404 global $wpdb;
405 $item_post = false;
406 $condition = [
407 'post_content' => [
408 'condition' => 'LIKE',
409 'value' => '%admin_label="' . $item_id . '"%',
410 'type' => '%s',
411 'or' => [
412 [
413 'post_content' => [
414 'condition' => 'LIKE',
415 'value' => '%"meta":{"adminLabel":{"desktop":{"value":"' . $item_id . '"%',
416 'type' => '%s',
417 ],
418 ],
419 ],
420 ],
421 'post_type' => [
422 'condition' => '<>',
423 'value' => [
424 'revision',
425 'et_pb_layout',
426 ],
427 'type' => '%s',
428 ],
429 ];
430
431 $order_condition = [
432 'orderby' => 'id',
433 'order' => 'desc',
434 ];
435
436 $where = $this->helper->load('db')->prepare_where($condition);
437 $orderby = $this->helper->load('db')->prepare_orderby($order_condition);
438 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
439 $posts = $wpdb->get_results($wpdb->prepare('SELECT * FROM `' . $wpdb->prefix . 'posts`' . $where['sql'] . $orderby . '', $where['filter']));
440 foreach ($posts as $post) {
441 if (in_array($item_id, $this->get_forms($post->post_content))) {
442 $item_post = $post;
443 break;
444 }
445 }
446 return $item_post;
447 }
448
449 // render
450 public function render($value, $field = [], $convert_shortcodes = true, $raw = false) {
451 $value = $this->render_shortcodes($value, $field);
452 if (!$raw) {
453 $value = $this->strip_shortcodes($value);
454 $value = $this->convert_shortcodes($value, $convert_shortcodes, isset($field['type']) && $field['type'] == 'e2pdf-html' ? true : false);
455 $value = $this->helper->load('field')->render_checkbox($value, $this, $field);
456 }
457 return $value;
458 }
459
460 // render shortcodes
461 public function render_shortcodes($value, $field = []) {
462 $element_id = isset($field['element_id']) ? $field['element_id'] : false;
463 if ($this->verify()) {
464 if (false !== strpos($value, '[')) {
465 $value = $this->helper->load('field')->pre_shortcodes($value, $this, $field);
466 $value = $this->helper->load('field')->inner_shortcodes($value, $this, $field);
467 $value = $this->helper->load('field')->wrapper_shortcodes($value, $this, $field);
468 }
469 $value = $this->helper->load('field')->do_shortcodes($value, $this, $field);
470 if (!empty($this->get('cached_meta'))) {
471 $value = $this->helper->load('convert')->stritr($value, $this->get('cached_meta'));
472 }
473 $value = $this->helper->load('field')->render(
474 apply_filters('e2pdf_extension_render_shortcodes_pre_value', $value, $element_id, $this->get('template_id'), $this->get('item'), $this->get('dataset'), false, false),
475 $this,
476 $field
477 );
478 }
479 return apply_filters(
480 'e2pdf_extension_render_shortcodes_value', $value, $element_id, $this->get('template_id'), $this->get('item'), $this->get('dataset'), false, false
481 );
482 }
483
484 // strip shortcodes
485 public function strip_shortcodes($value) {
486 $value = preg_replace('~(?:\[/?)[^/\]]+/?\]~s', '', $value);
487 $value = preg_replace('~%%[^%%]*%%~', '', $value);
488 return $value;
489 }
490
491 // convert shortcodes
492 public function convert_shortcodes($value, $to = false, $html = false) {
493 if ($value) {
494 if ($to) {
495 $value = stripslashes_deep($value);
496 $value = str_replace('&#91;', '[', $value);
497 if (!$html) {
498 $value = wp_specialchars_decode($value, ENT_QUOTES);
499 }
500 } else {
501 $value = str_replace('[', '&#91;', $value);
502 }
503 }
504 return $value;
505 }
506
507 // auto
508 public function auto() {
509
510 $elements = [];
511
512 if ($this->get('item')) {
513 $post = $this->get_form($this->get('item'));
514 if ($post && isset($post->post_content)) {
515
516 $source = '';
517 $content = $post->post_content;
518
519 if ($this->divi4_form($content)) {
520 $shortcode_tags = [
521 'et_pb_contact_form',
522 ];
523 preg_match_all('@\[([^<>&/\[\]\x00-\x20=]++)@', $content, $matches);
524 $tagnames = array_intersect($shortcode_tags, $matches[1]);
525 if (!empty($tagnames)) {
526 preg_match_all('/' . $this->helper->load('shortcode')->get_shortcode_regex($tagnames) . '/', $content, $shortcodes);
527 foreach ($shortcodes[0] as $key => $shortcode_value) {
528 $shortcode = $this->helper->load('shortcode')->get_shortcode($shortcodes, $key);
529 $atts = shortcode_parse_atts($shortcode[3]);
530 if (isset($atts['admin_label']) && $atts['admin_label'] == $this->get('item')) {
531 $this->divi4_load();
532 $source = do_shortcode($shortcode_value);
533 }
534 }
535 }
536 } elseif ($this->divi5_form($content)) {
537 $blocks = $this->get_forms_blocks(parse_blocks($content));
538 foreach ($blocks as $key => $block) {
539 $label = !empty($block['attrs']['module']['meta']['adminLabel']['desktop']['value']) ? $block['attrs']['module']['meta']['adminLabel']['desktop']['value'] : '';
540 if ($label == $this->get('item')) {
541 $source = render_block($block);
542 break;
543 }
544 }
545 }
546
547 if ($source) {
548 $dom = new DOMDocument();
549 $html = $this->helper->load('convert')->load_html($source, $dom, true);
550 if ($html) {
551 $xml = $this->helper->load('xml');
552 $xpath = new DomXPath($dom);
553
554 // remove parent by class
555 $remove_parent_by_class = [
556 'et_pb_contact_captcha_question',
557 ];
558 foreach ($remove_parent_by_class as $key => $class) {
559 $xml_elements = $xpath->query("//*[contains(@class, '{$class}')]/parent::*");
560 foreach ($xml_elements as $xml_element) {
561 $xml_element->parentNode->removeChild($xml_element);
562 }
563 }
564
565 $blocks = $xpath->query("//*[contains(@class, 'et_pb_contact_field')]");
566 foreach ($blocks as $element) {
567
568 if ($xml->get_node_value($element, 'data-type') == 'radio') {
569
570 $label = $xpath->query('.//label', $element)->item(0);
571 $check_handler = $xpath->query(".//input[contains(@class, 'et_pb_checkbox_handle')]", $element)->item(0);
572
573 $name = '';
574 if ($check_handler) {
575 $name = '%%' . $xml->get_node_value($check_handler, 'data-original_id') . '%%';
576 }
577
578 if ($label) {
579 $elements[] = $this->auto_field(
580 $element,
581 [
582 'type' => 'e2pdf-html',
583 'block' => true,
584 'class' => $xml->get_node_value($element, 'class'),
585 'properties' => [
586 'top' => '20',
587 'left' => '20',
588 'right' => '20',
589 'width' => '100%',
590 'height' => 'auto',
591 'value' => $label->nodeValue,
592 ],
593 ]
594 );
595 }
596
597 $fields = $xpath->query(".//*[contains(@class, 'et_pb_contact_field_radio')]", $element);
598 foreach ($fields as $field) {
599 $radio_label = $xpath->query('.//label', $field)->item(0);
600 $radio = $xpath->query(".//input[@type='radio']", $field)->item(0);
601
602 if (
603 $radio->attributes->getNamedItem('data-original_id') &&
604 $radio->attributes->getNamedItem('value')
605 ) {
606 $elements[] = $this->auto_field(
607 $field,
608 [
609 'type' => 'e2pdf-radio',
610 'class' => $xml->get_node_value($field, 'class'),
611 'properties' => [
612 'top' => '5',
613 'width' => 'auto',
614 'height' => 'auto',
615 'value' => '%%' . $xml->get_node_value($radio, 'data-original_id') . '%%',
616 'option' => sanitize_text_field($xml->get_node_value($radio, 'value')),
617 'group' => '%%' . $xml->get_node_value($radio, 'data-original_id') . '%%',
618 ],
619 ]
620 );
621 }
622
623 if ($radio_label) {
624 $elements[] = $this->auto_field(
625 $radio,
626 [
627 'type' => 'e2pdf-html',
628 'float' => true,
629 'class' => $xml->get_node_value($radio, 'class'),
630 'properties' => [
631 'left' => '5',
632 'width' => '100%',
633 'height' => 'auto',
634 'value' => $radio_label->nodeValue,
635 ],
636 ]
637 );
638 }
639 }
640 } elseif ($xml->get_node_value($element, 'data-type') == 'checkbox') {
641 $label = $xpath->query('.//label', $element)->item(0);
642 $check_handler = $xpath->query(".//input[contains(@class, 'et_pb_checkbox_handle')]", $element)->item(0);
643
644 $name = '';
645 if ($check_handler) {
646 $name = '%%' . $xml->get_node_value($check_handler, 'data-original_id') . '%%';
647 }
648
649 if ($label) {
650 $elements[] = $this->auto_field(
651 $element,
652 [
653 'type' => 'e2pdf-html',
654 'block' => true,
655 'class' => $xml->get_node_value($element, 'class'),
656 'properties' => [
657 'top' => '20',
658 'left' => '20',
659 'right' => '20',
660 'width' => '100%',
661 'height' => 'auto',
662 'value' => $label->nodeValue,
663 ],
664 ]
665 );
666 }
667
668 $fields = $xpath->query(".//*[contains(@class, 'et_pb_contact_field_checkbox')]", $element);
669 foreach ($fields as $field) {
670 $checkbox_label = $xpath->query('.//label', $field)->item(0);
671 $checkbox = $xpath->query(".//input[@type='checkbox']", $field)->item(0);
672
673 $elements[] = $this->auto_field(
674 $field,
675 [
676 'type' => 'e2pdf-checkbox',
677 'class' => $xml->get_node_value($field, 'class'),
678 'properties' => [
679 'top' => '5',
680 'width' => 'auto',
681 'height' => 'auto',
682 'value' => $name,
683 'option' => sanitize_text_field($xml->get_node_value($checkbox, 'value')),
684 ],
685 ]
686 );
687
688 if ($checkbox_label) {
689 $elements[] = $this->auto_field(
690 $checkbox,
691 [
692 'type' => 'e2pdf-html',
693 'float' => true,
694 'class' => $xml->get_node_value($checkbox, 'class'),
695 'properties' => [
696 'left' => '5',
697 'width' => '100%',
698 'height' => 'auto',
699 'value' => $checkbox_label->nodeValue,
700 ],
701 ]
702 );
703 }
704 }
705 } else {
706 $label = $xpath->query('.//label', $element)->item(0);
707 $input_text = $xpath->query(".//input[@type='text']", $element)->item(0);
708 $select = $xpath->query('.//select', $element)->item(0);
709 $textarea = $xpath->query('.//textarea', $element)->item(0);
710
711 if ($label && ($input_text || $select || $textarea)) {
712 $elements[] = $this->auto_field(
713 $element,
714 [
715 'type' => 'e2pdf-html',
716 'block' => true,
717 'class' => $xml->get_node_value($element, 'class'),
718 'properties' => [
719 'top' => '20',
720 'left' => '20',
721 'right' => '20',
722 'width' => '100%',
723 'height' => 'auto',
724 'value' => $label->nodeValue,
725 ],
726 ]
727 );
728 }
729
730 if ($input_text) {
731 $data_type = $input_text->parentNode->getAttribute('data-type');
732 if ($data_type === 'signature-pad') {
733 $elements[] = $this->auto_field(
734 $input_text,
735 [
736 'type' => 'e2pdf-signature',
737 'properties' => [
738 'top' => '5',
739 'width' => '100%',
740 'height' => '150',
741 'dimension' => '1',
742 'block_dimension' => '1',
743 'value' => '%%' . $xml->get_node_value($input_text, 'data-original_id') . '%%',
744 ],
745 ]
746 );
747 } elseif ($data_type === 'file') {
748 $elements[] = $this->auto_field(
749 $input_text,
750 [
751 'type' => 'e2pdf-textarea',
752 'class' => $xml->get_node_value($input_text, 'class'),
753 'properties' => [
754 'top' => '5',
755 'width' => '100%',
756 'height' => '150',
757 'value' => '%%' . $xml->get_node_value($input_text, 'data-original_id') . '%%',
758 ],
759 ]
760 );
761 } else {
762 $elements[] = $this->auto_field(
763 $input_text,
764 [
765 'type' => 'e2pdf-input',
766 'class' => $xml->get_node_value($input_text, 'class'),
767 'properties' => [
768 'top' => '5',
769 'width' => '100%',
770 'height' => 'auto',
771 'value' => '%%' . $xml->get_node_value($input_text, 'data-original_id') . '%%',
772 ],
773 ]
774 );
775 }
776 } elseif ($select) {
777 $options_tmp = [];
778 $options = $xpath->query('.//option', $select);
779 foreach ($options as $option) {
780 $options_tmp[] = sanitize_text_field($xml->get_node_value($option, 'value'));
781 }
782
783 $elements[] = $this->auto_field(
784 $select,
785 [
786 'type' => 'e2pdf-select',
787 'class' => $xml->get_node_value($select, 'class'),
788 'properties' => [
789 'top' => '5',
790 'width' => '100%',
791 'height' => 'auto',
792 'options' => implode("\n", $options_tmp),
793 'value' => '%%' . $xml->get_node_value($select, 'data-original_id') . '%%',
794 ],
795 ]
796 );
797 } elseif ($textarea) {
798 $elements[] = $this->auto_field(
799 $textarea,
800 [
801 'type' => 'e2pdf-textarea',
802 'class' => $xml->get_node_value($textarea, 'class'),
803 'properties' => [
804 'top' => '5',
805 'width' => '100%',
806 'height' => '150',
807 'value' => '%%' . $xml->get_node_value($textarea, 'data-original_id') . '%%',
808 ],
809 ]
810 );
811 }
812 }
813 }
814 }
815 }
816 }
817 }
818 return [
819 'page' => [
820 'bottom' => '20',
821 'top' => '20',
822 'right' => '20',
823 'left' => '20',
824 ],
825 'elements' => $elements,
826 ];
827 }
828
829 // auto map
830 public function auto_map($name = false) {
831 $item = $this->get('item');
832 if ($item) {
833 $post = $this->get_form($item);
834 if ($post && isset($post->post_content)) {
835 $content = $post->post_content;
836 if ($this->divi4_form($content)) {
837 $shortcode_tags = [
838 'et_pb_contact_form',
839 ];
840 preg_match_all('@\[([^<>&/\[\]\x00-\x20=]++)@', $content, $matches);
841 $tagnames = array_intersect($shortcode_tags, $matches[1]);
842 if (!empty($tagnames)) {
843 preg_match_all('/' . $this->helper->load('shortcode')->get_shortcode_regex($tagnames) . '/', $content, $shortcodes);
844 foreach ($shortcodes[0] as $key => $shortcode_value) {
845 $shortcode = $this->helper->load('shortcode')->get_shortcode($shortcodes, $key);
846 $atts = shortcode_parse_atts($shortcode[3]);
847 if (isset($atts['admin_label']) && $atts['admin_label'] == $this->get('item')) {
848 $field_content = $shortcode_value;
849 $field_shortcode_tags = [
850 'et_pb_contact_field',
851 ];
852 preg_match_all('@\[([^<>&/\[\]\x00-\x20=]++)@', $field_content, $field_matches);
853 $field_tagnames = array_intersect($field_shortcode_tags, $field_matches[1]);
854 if (!empty($field_tagnames)) {
855 preg_match_all('/' . $this->helper->load('shortcode')->get_shortcode_regex($field_tagnames) . '/', $field_content, $field_shortcodes);
856 foreach ($field_shortcodes[0] as $field_key => $field_shortcode_value) {
857 $field_shortcode = [];
858 $field_shortcode[3] = $field_shortcodes[3][$field_key];
859 $field = shortcode_parse_atts($field_shortcode[3]);
860 if (isset($field['field_title']) && isset($field['field_id'])) {
861 if ($field['field_title'] == $name || $field['field_id'] == $name) {
862 return '%%' . strtolower($field['field_id']) . '%%';
863 }
864 }
865 }
866 }
867 }
868 }
869 }
870 } elseif ($this->divi5_form($content)) {
871 $blocks = $this->get_forms_blocks(parse_blocks($content));
872 foreach ($blocks as $key => $block) {
873 $label = !empty($block['attrs']['module']['meta']['adminLabel']['desktop']['value']) ? $block['attrs']['module']['meta']['adminLabel']['desktop']['value'] : '';
874 if ($label == $this->get('item')) {
875 $fields = $this->get_fields_blocks($block);
876 if (!empty($fields)) {
877 foreach ($fields as $field) {
878 if (isset($field['field_title']) && isset($field['field_id'])) {
879 if ($field['field_title'] == $name || $field['field_id'] == $name) {
880 return '%%' . strtolower($field['field_id']) . '%%';
881 }
882 }
883 }
884 }
885 }
886 break;
887 }
888 }
889 }
890 }
891
892 return false;
893 }
894
895 // auto field
896 public function auto_field($field = false, $element = []) {
897
898 if (!$field) {
899 return false;
900 }
901
902 if (!isset($element['block'])) {
903 $element['block'] = false;
904 }
905
906 if (!isset($element['float'])) {
907 $element['float'] = false;
908 }
909
910 $classes = [];
911 if (isset($element['class']) && $element['class']) {
912 $classes = explode(' ', $element['class']);
913 unset($element['class']);
914 }
915
916 $float_classes = [
917 'et_pb_contact_field_half',
918 ];
919 $array_intersect = array_intersect($classes, $float_classes);
920
921 if (!empty($array_intersect) && $element['block']) {
922 $element['float'] = true;
923 };
924
925 $primary_class = false;
926 if (!empty($array_intersect)) {
927 $primary_class = end($array_intersect);
928 }
929
930 if ($element['block']) {
931 switch ($primary_class) {
932 case 'et_pb_contact_field_half':
933 $element['width'] = '50%';
934 break;
935 default:
936 break;
937 }
938 }
939
940 return $element;
941 }
942
943 // verify
944 public function verify() {
945 if ($this->get('cached_entry')) {
946 return true;
947 }
948 return false;
949 }
950
951 // visual mapper
952 public function visual_mapper() {
953
954 $source = '';
955 $html = '';
956
957 if ($this->get('item')) {
958 $post = $this->get_form($this->get('item'));
959 if ($post && isset($post->post_content)) {
960 $content = $post->post_content;
961
962 if ($this->divi4_form($content)) {
963 $shortcode_tags = [
964 'et_pb_contact_form',
965 ];
966 preg_match_all('@\[([^<>&/\[\]\x00-\x20=]++)@', $content, $matches);
967 $tagnames = array_intersect($shortcode_tags, $matches[1]);
968 if (!empty($tagnames)) {
969 preg_match_all('/' . $this->helper->load('shortcode')->get_shortcode_regex($tagnames) . '/', $content, $shortcodes);
970 foreach ($shortcodes[0] as $key => $shortcode_value) {
971 $shortcode = $this->helper->load('shortcode')->get_shortcode($shortcodes, $key);
972 $atts = shortcode_parse_atts($shortcode[3]);
973 if (isset($atts['admin_label']) && $atts['admin_label'] == $this->get('item')) {
974 $this->divi4_load();
975 $source = do_shortcode($shortcode_value);
976 }
977 }
978 }
979 } elseif ($this->divi5_form($content)) {
980 $blocks = $this->get_forms_blocks(parse_blocks($content));
981 foreach ($blocks as $key => $block) {
982 $label = !empty($block['attrs']['module']['meta']['adminLabel']['desktop']['value']) ? $block['attrs']['module']['meta']['adminLabel']['desktop']['value'] : '';
983 if ($label == $this->get('item')) {
984 $source = render_block($block);
985 break;
986 }
987 }
988 }
989
990 if ($source) {
991 $dom = new DOMDocument();
992 $html = $this->helper->load('convert')->load_html($source, $dom, true);
993 }
994 if (!$source) {
995 return '<div class="e2pdf-vm-error">' . __("The form source is empty or doesn't exist", 'e2pdf') . '</div>';
996 } elseif (!$html) {
997 return '<div class="e2pdf-vm-error">' . __('The form could not be parsed due the incorrect HTML', 'e2pdf') . '</div>';
998 } else {
999 $xml = $this->helper->load('xml');
1000 $xpath = new DomXPath($dom);
1001
1002 // remove by name
1003 $remove_by_name = [
1004 'et_pb_contactform_submit_0',
1005 '_wpnonce-et-pb-contact-form-submitted-0',
1006 '_wp_http_referer',
1007 ];
1008 foreach ($remove_by_name as $key => $name) {
1009 $xml_elements = $xpath->query('//*[@name="' . $name . '"]');
1010 foreach ($xml_elements as $xml_element) {
1011 $xml_element->parentNode->removeChild($xml_element);
1012 }
1013 }
1014
1015 // replace names
1016 $fields = $xpath->query("//*[contains(@name, 'et_pb_contact_')]");
1017 foreach ($fields as $xml_element) {
1018 $xml->set_node_value($xml_element, 'name', '%%' . $xml->get_node_value($xml_element, 'data-original_id') . '%%');
1019 }
1020
1021 // checkboxes
1022 $checkboxes = $xpath->query("//*[contains(@class, 'et_pb_contact_field') and @data-type='checkbox']");
1023 foreach ($checkboxes as $xml_element) {
1024 $check_handler = $xpath->query(".//input[contains(@class, 'et_pb_checkbox_handle')]", $xml_element)->item(0);
1025 $name = '';
1026 if ($check_handler) {
1027 $name = '%%' . $xml->get_node_value($check_handler, 'data-original_id') . '%%';
1028 }
1029 $checks = $xpath->query(".//input[@type='checkbox']", $xml_element);
1030 foreach ($checks as $check) {
1031 $xml->set_node_value($check, 'name', $name);
1032 $xml->set_node_value($check, 'value', sanitize_text_field($xml->get_node_value($check, 'value')));
1033 }
1034 }
1035
1036 // uploads
1037 $uploads = $xpath->query("//*[contains(@class, 'et_pb_contact_hidden_files')]");
1038 foreach ($uploads as $xml_element) {
1039 $xml->set_node_value($xml_element, 'type', 'file');
1040 }
1041
1042 $radios = $xpath->query("//input[@type='radio']");
1043 foreach ($radios as $xml_element) {
1044 $xml->set_node_value($xml_element, 'value', sanitize_text_field($xml->get_node_value($xml_element, 'value')));
1045 }
1046
1047 $selects = $xpath->query('//select/option');
1048 foreach ($selects as $xml_element) {
1049 $xml->set_node_value($xml_element, 'value', sanitize_text_field($xml->get_node_value($xml_element, 'value')));
1050 }
1051
1052 // remove by class
1053 $remove_by_class = [
1054 'et_pb_contact_submit',
1055 'et_pb_contactform_validate_field',
1056 'et_pb_checkbox_handle',
1057 'et_pb_form_bottom_stepper_container',
1058 'stepper__progress',
1059 ];
1060 foreach ($remove_by_class as $key => $class) {
1061 $xml_elements = $xpath->query("//*[contains(@class, '{$class}')]");
1062 foreach ($xml_elements as $xml_element) {
1063 $xml_element->parentNode->removeChild($xml_element);
1064 }
1065 }
1066
1067 $xml_elements = $xpath->query('//*[@data-step]');
1068 foreach ($xml_elements as $xml_element) {
1069 $xml_element->removeAttribute('style');
1070 }
1071
1072 // remove parent by class
1073 $remove_parent_by_class = [
1074 'et_pb_contact_captcha_question',
1075 ];
1076 foreach ($remove_parent_by_class as $key => $class) {
1077 $xml_elements = $xpath->query("//*[contains(@class, '{$class}')]/parent::*");
1078 foreach ($xml_elements as $xml_element) {
1079 $xml_element->parentNode->removeChild($xml_element);
1080 }
1081 }
1082 }
1083
1084 if (defined('LIBXML_HTML_NOIMPLIED') && defined('LIBXML_HTML_NODEFDTD')) {
1085 return str_replace(['<html>', '</html>'], '', $dom->saveHTML());
1086 } else {
1087 return $dom->saveHTML();
1088 }
1089 }
1090 }
1091
1092 return false;
1093 }
1094
1095 // filter mail
1096 public function filter_wp_mail($args) {
1097
1098 if (!$this->get('process')) {
1099 return $args;
1100 }
1101
1102 if ((defined('PWH_DCFH_PLUGIN_VERSION') && version_compare(PWH_DCFH_PLUGIN_VERSION, '1.5.1', '>=')) || defined('KS_PAC_DCFH_PLUGIN_FILE')) {
1103 $args['message'] = preg_replace('/(\{)((e2pdf-download|e2pdf-view|e2pdf-save|e2pdf-attachment|e2pdf-adobesign|e2pdf-zapier)[^\}]*?)(\})/', '[$2]', $args['message']);
1104 }
1105
1106 if (isset($args['message'])) {
1107 if (false !== strpos($args['message'], '[')) {
1108 $shortcode_tags = [
1109 'e2pdf-download',
1110 'e2pdf-save',
1111 'e2pdf-attachment',
1112 'e2pdf-adobesign',
1113 'e2pdf-zapier',
1114 ];
1115 preg_match_all('@\[([^<>&/\[\]\x00-\x20=]++)@', $args['message'], $matches);
1116 $tagnames = array_intersect($shortcode_tags, $matches[1]);
1117 if (!empty($tagnames)) {
1118 preg_match_all('/' . $this->helper->load('shortcode')->get_shortcode_regex($tagnames) . '/', $args['message'], $shortcodes);
1119 foreach ($shortcodes[0] as $key => $shortcode_value) {
1120 $shortcode = $this->helper->load('shortcode')->get_shortcode($shortcodes, $key);
1121 $atts = shortcode_parse_atts($shortcode[3]);
1122 if (!isset($atts['apply'])) {
1123 $shortcode[3] .= ' apply="true"';
1124 }
1125 if (!isset($atts['filter'])) {
1126 $shortcode[3] .= ' filter="true"';
1127 }
1128 $file = false;
1129 if ($this->helper->load('shortcode')->is_attachment($shortcode, $atts)) {
1130 $file = do_shortcode_tag($shortcode);
1131 if ($file) {
1132 $tmp = false;
1133 if (substr($file, 0, 4) === 'tmp:') {
1134 $file = substr($file, 4);
1135 $tmp = true;
1136 }
1137 if ($shortcode[2] === 'e2pdf-save' || isset($atts['pdf'])) {
1138 if ($tmp) {
1139 $this->helper->add('divi_attachments', $file);
1140 }
1141 } else {
1142 $this->helper->add('divi_attachments', $file);
1143 }
1144 $args['attachments'][] = $file;
1145 if (!has_action('wp_mail_succeeded', [$this, 'filter_wp_mail_attachments'])) {
1146 add_action('wp_mail_succeeded', [$this, 'filter_wp_mail_attachments']);
1147 }
1148 if (!has_action('wp_mail_failed', [$this, 'filter_wp_mail_attachments'])) {
1149 add_action('wp_mail_failed', [$this, 'filter_wp_mail_attachments']);
1150 }
1151 }
1152 $args['message'] = str_replace($shortcode_value, '', $args['message']);
1153 } else {
1154 if (is_array($args['headers']) && !in_array('Content-Type: text/html; charset=UTF-8', $args['headers'])) {
1155 $args['headers'][] = 'Content-Type: text/html; charset=UTF-8';
1156 }
1157 $args['message'] = str_replace($shortcode_value, do_shortcode_tag($shortcode), $args['message']);
1158 $args['message'] = str_replace("\r\n", '<br/>', $args['message']);
1159 }
1160 }
1161 }
1162 }
1163 }
1164 $wp_mail = [
1165 'to' => $args['to'],
1166 'subject' => $args['subject'],
1167 'message' => $args['message'],
1168 'headers' => $args['headers'],
1169 'attachments' => $args['attachments'],
1170 ];
1171 return $wp_mail;
1172 }
1173
1174 public function filter_wp_mail_attachments() {
1175 $files = $this->helper->get('divi_attachments');
1176 if (is_array($files) && !empty($files)) {
1177 foreach ($files as $key => $file) {
1178 $this->helper->delete_dir(dirname($file) . '/');
1179 }
1180 $this->helper->deset('divi_attachments');
1181 }
1182 }
1183
1184 // load actions
1185 public function load_actions() { // phpcs:ignore Squiz.WhiteSpace.SuperfluousWhitespace.EndLine
1186 add_action('et_pb_contact_form_submit', [$this, 'action_et_pb_contact_form_submit'], 11);
1187 }
1188
1189 public function action_et_pb_contact_form_submit() {
1190 if ($this->divi5()) {
1191 add_filter('wp_mail', [$this, 'filter_wp_mail'], 1000);
1192 }
1193 }
1194
1195 // load filters
1196 public function load_filters() {
1197 // Divi Contact Form Helper Confirmation Email compatibility fix
1198 if (defined('PWH_DCFH_PLUGIN_FILE') || defined('KS_PAC_DCFH_PLUGIN_FILE')) {
1199 add_filter('et_pb_module_shortcode_attributes', [$this, 'filter_et_pb_module_shortcode_attributes'], 9, 5);
1200 } else {
1201 add_filter('et_pb_module_shortcode_attributes', [$this, 'filter_et_pb_module_shortcode_attributes'], 30, 5);
1202 }
1203 add_filter('et_module_shortcode_output', [$this, 'filter_et_module_shortcode_output'], 30, 3);
1204
1205 // Divi 5
1206 add_filter('divi_module_library_register_module_attrs', [$this, 'filter_divi_module_library_register_module_attrs'], 11, 2);
1207 }
1208
1209 public function filter_divi_module_library_register_module_attrs($module_attrs, $filter_args) {
1210
1211 if ('divi/contact-form' !== $filter_args['name']) {
1212 return $module_attrs;
1213 }
1214
1215 if (!isset($_SERVER['REQUEST_METHOD']) || 'POST' !== $_SERVER['REQUEST_METHOD']) {
1216 return $module_attrs;
1217 }
1218
1219 $module_id = !empty($filter_args['id']) ? $filter_args['id'] : '';
1220 $store_instance = !empty($filter_args['storeInstance']) ? $filter_args['storeInstance'] : 0;
1221
1222 if (
1223 !class_exists('\ET\Builder\FrontEnd\BlockParser\BlockParserStore') ||
1224 !method_exists('\ET\Builder\FrontEnd\BlockParser\BlockParserStore', 'get')
1225 ) {
1226 return $module_attrs;
1227 }
1228
1229 $module = \ET\Builder\FrontEnd\BlockParser\BlockParserStore::get($module_id, $store_instance);
1230
1231 if (!$module) {
1232 return $module_attrs;
1233 }
1234
1235 if (
1236 !class_exists('\ET\Builder\Packages\ModuleLibrary\ContactForm\ContactFormUtils') ||
1237 !method_exists('\ET\Builder\Packages\ModuleLibrary\ContactForm\ContactFormUtils', 'get_unique_id') ||
1238 !class_exists('\ET\Builder\Packages\ModuleLibrary\ContactForm\ContactFormHandler') ||
1239 !class_exists('\ET\Builder\Packages\ModuleLibrary\ContactField\ContactFieldModule') ||
1240 !method_exists('\ET\Builder\Packages\ModuleLibrary\ContactField\ContactFieldModule', 'get_field_unique_id')
1241 ) {
1242 return $module_attrs;
1243 }
1244
1245 $unique_id = \ET\Builder\Packages\ModuleLibrary\ContactForm\ContactFormUtils::get_unique_id($module_attrs, (array) $module);
1246
1247 $submitted = isset($_POST['_wpnonce-et-pb-contact-form-submitted-' . $unique_id]);
1248 if (!$submitted) {
1249 return $module_attrs;
1250 }
1251
1252 if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_wpnonce-et-pb-contact-form-submitted-' . $unique_id])), 'et-pb-contact-form-submit-' . $unique_id)) {
1253 return $module_attrs;
1254 }
1255
1256 $use_basic_captcha = $module_attrs['module']['advanced']['spamProtection']['desktop']['value']['useBasicCaptcha'] ?? 'on';
1257 $use_spam_service = $module_attrs['module']['advanced']['spamProtection']['desktop']['value']['enabled'] ?? 'off';
1258
1259 if ('on' === $use_basic_captcha && 'off' === $use_spam_service) {
1260 $captcha_answer = sanitize_text_field(wp_unslash($_POST['et_pb_contact_captcha_' . $unique_id] ?? ''));
1261 $first_digit = sanitize_text_field(wp_unslash($_POST['et_pb_contact_captcha_first_digit_' . $unique_id] ?? ''));
1262 $second_digit = sanitize_text_field(wp_unslash($_POST['et_pb_contact_captcha_second_digit_' . $unique_id] ?? ''));
1263
1264 if (!$captcha_answer || ((int) $first_digit + (int) $second_digit) !== (int) $captcha_answer) {
1265 return $module_attrs;
1266 }
1267 } elseif ('on' === $use_spam_service) {
1268 $provider = $module_attrs['module']['advanced']['spamProtection']['desktop']['value']['provider'] ?? 'recaptcha';
1269 $account = $module_attrs['module']['advanced']['spamProtection']['desktop']['value']['account'] ?? '';
1270 $min_score = (float) ($module_attrs['module']['advanced']['spamProtection']['desktop']['value']['minScore'] ?? 0.0);
1271
1272 if (empty($_POST['token']) || !SpamProtectionService::validate_token($provider, $account, $min_score)) {
1273 return $module_attrs;
1274 }
1275 }
1276
1277 $messages = [
1278 'successMessage' => isset($module_attrs['module']['advanced']['successMessage']['desktop']['value']) ? $module_attrs['module']['advanced']['successMessage']['desktop']['value'] : '',
1279 ];
1280 if (defined('KS_PAC_DCFH_PLUGIN_FILE')) {
1281 $send_admin_email = isset($module_attrs['adminEmail']['advanced']['adminEmailEnabled']['desktop']['value']) ? $module_attrs['adminEmail']['advanced']['adminEmailEnabled']['desktop']['value'] : 'on';
1282 if ($send_admin_email === 'on') {
1283 $admin_email_rich_text = isset($module_attrs['adminEmail']['advanced']['emailRichTextEnabled']['desktop']['value']) ? $module_attrs['adminEmail']['advanced']['emailRichTextEnabled']['desktop']['value'] : 'off';
1284 if ($admin_email_rich_text === 'on') {
1285 $messages['adminEmailRichTextMessage'] = isset($module_attrs['adminEmail']['innerContent']['emailRichTextMessage']['desktop']['value']) ? $this->decode_shortcodes($module_attrs['adminEmail']['innerContent']['emailRichTextMessage']['desktop']['value']) : '';
1286 } else {
1287 $messages['email'] = isset($module_attrs['email']['innerContent']['desktop']['value']) ? $module_attrs['email']['innerContent']['desktop']['value'] : '';
1288 }
1289 }
1290 $send_user_email = isset($module_attrs['confirmationEmail']['advanced']['sendEmailToSubmitter']['desktop']['value']) ? $module_attrs['confirmationEmail']['advanced']['sendEmailToSubmitter']['desktop']['value'] : 'off';
1291 if ($send_user_email === 'on') {
1292 $user_email_rich_text = isset($module_attrs['confirmationEmail']['advanced']['emailMessageRichTextEnabled']['desktop']['value']) ? $module_attrs['confirmationEmail']['advanced']['emailMessageRichTextEnabled']['desktop']['value'] : 'off';
1293 if ($user_email_rich_text === 'on') {
1294 $messages['confirmationEmailRichTextMessage'] = isset($module_attrs['confirmationEmail']['innerContent']['emailRichTextMessage']['desktop']['value']) ? $this->decode_shortcodes($module_attrs['confirmationEmail']['innerContent']['emailRichTextMessage']['desktop']['value']) : '';
1295 } else {
1296 $messages['confirmationEmailMessage'] = isset($module_attrs['confirmationEmail']['innerContent']['emailMessage']['desktop']['value']) ? $module_attrs['confirmationEmail']['innerContent']['emailMessage']['desktop']['value'] : '';
1297 }
1298 }
1299 } else {
1300 $messages['email'] = isset($module_attrs['email']['innerContent']['desktop']['value']) ? $module_attrs['email']['innerContent']['desktop']['value'] : '';
1301 }
1302
1303 foreach ($messages as $message_key => $message) {
1304 if (false !== strpos($message, '[')) {
1305 $shortcode_tags = [
1306 'e2pdf-download',
1307 'e2pdf-save',
1308 'e2pdf-view',
1309 'e2pdf-adobesign',
1310 'e2pdf-zapier',
1311 'e2pdf-attachment',
1312 ];
1313 preg_match_all('@\[([^<>&/\[\]\x00-\x20=]++)@', $message, $matches);
1314 $tagnames = array_intersect($shortcode_tags, $matches[1]);
1315 if (!empty($tagnames)) {
1316 $this->set('process', true);
1317 } else {
1318 unset($messages[$message_key]);
1319 }
1320 } else {
1321 unset($messages[$message_key]);
1322 }
1323 }
1324
1325 $_POST = $this->sanitize($_POST);
1326
1327 if (!$this->get('process')) {
1328 return $module_attrs;
1329 }
1330
1331 if (
1332 !class_exists('\ET\Builder\Packages\ModuleLibrary\ModuleRegistration') ||
1333 !method_exists('\ET\Builder\Packages\ModuleLibrary\ModuleRegistration', 'get_default_attrs')) {
1334 return $module_attrs;
1335 }
1336
1337 $fields_raw = [];
1338 $filtered_field_attrs = [];
1339 $fields = \ET\Builder\FrontEnd\BlockParser\BlockParserStore::get_children($module_id, $store_instance);
1340 $default_child_attrs = \ET\Builder\Packages\ModuleLibrary\ModuleRegistration::get_default_attrs(
1341 'divi/contact-field'
1342 );
1343 foreach ($fields as $field) {
1344 // Skip nested modules (Text, Button, Divider, etc.), only process Contact Field modules.
1345 if ('divi/contact-field' !== $field->blockName) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- This is a property of the WP Core class.
1346 continue;
1347 }
1348 $merged_child_attrs = array_replace_recursive(
1349 $default_child_attrs,
1350 $field->attrs ?? []
1351 );
1352 $child_filter_args = [
1353 'id' => $field->id,
1354 'name' => $field->blockName,
1355 'parentId' => $module_id,
1356 'parentName' => 'divi/contact-form',
1357 'parentAttrs' => $module_attrs,
1358 'storeInstance' => $store_instance,
1359 ];
1360 $filtered_field_attrs[$field->id] = apply_filters(
1361 'divi_module_library_register_module_attrs',
1362 $merged_child_attrs,
1363 $child_filter_args
1364 );
1365
1366 // Use pre-filtered field attributes if provided, otherwise use field attributes from storage.
1367 $field_attrs = !empty($filtered_field_attrs[$field->id]) ? $filtered_field_attrs[$field->id] : $field->attrs;
1368 $field_unique_id = \ET\Builder\Packages\ModuleLibrary\ContactField\ContactFieldModule::get_field_unique_id($field->id, $store_instance);
1369 $field_type = $field_attrs['fieldItem']['advanced']['type']['desktop']['value'] ?? 'input';
1370 $field_id = $field_attrs['fieldItem']['advanced']['id']['desktop']['value'] ?? '';
1371 $field_key = strtolower($field_id);
1372 $field_label = $field_attrs['fieldItem']['innerContent']['desktop']['value'] ?? '';
1373
1374 if (!$field_label) {
1375 $field_label = __('New Field', 'et_builder_5');
1376 }
1377
1378 $fields_raw[$field_key]['id'] = $field_id;
1379 $fields_raw[$field_key]['label'] = $field_label;
1380 $fields_raw[$field_key]['type'] = $field_type;
1381 $fields_raw[$field_key]['allowedSymbols'] = $field_attrs['fieldItem']['advanced']['allowedSymbols']['desktop']['value'] ?? '';
1382 $fields_raw[$field_key]['maxLength'] = $field_attrs['fieldItem']['advanced']['maxLength']['desktop']['value'] ?? '';
1383 $fields_raw[$field_key]['minLength'] = $field_attrs['fieldItem']['advanced']['minLength']['desktop']['value'] ?? '';
1384 $fields_raw[$field_key]['isRequired'] = 'on' === ($field_attrs['fieldItem']['advanced']['required']['desktop']['value'] ?? 'on');
1385
1386 $fields_raw[$field_key]['conditionalLogic'] = [
1387 'enabled' => 'on' === ($field_attrs['conditionalLogic']['advanced']['enable']['desktop']['value'] ?? 'off'),
1388 'matchAll' => 'on' === ($field_attrs['conditionalLogic']['advanced']['relation']['desktop']['value'] ?? 'off'),
1389 'rules' => $field_attrs['conditionalLogic']['innerContent']['desktop']['value'] ?? [],
1390 ];
1391
1392 if ('text' === $field_type) {
1393 $fields_raw[$field_key]['value'] = isset($_POST[$field_unique_id]) ? sanitize_textarea_field(wp_unslash($_POST[$field_unique_id])) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated and sanitized.
1394 } elseif ('checkbox' === $field_type) {
1395 // For checkbox fields, decode and sanitize immediately, store as array.
1396 $raw_value = isset($_POST[$field_unique_id]) ? wp_unslash($_POST[$field_unique_id]) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated and sanitized.
1397
1398 if ('' !== $raw_value) {
1399 // Split the URL-encoded comma-separated values.
1400 $parts = explode(',', $raw_value);
1401 $parts = array_map('urldecode', $parts);
1402 $parts = array_map('sanitize_text_field', $parts);
1403 $parts = array_map('trim', $parts);
1404 $fields_raw[$field_key]['value'] = $parts;
1405 } else {
1406 $fields_raw[$field_key]['value'] = [];
1407 }
1408 } else {
1409 $fields_raw[$field_key]['value'] = isset($_POST[$field_unique_id]) ? sanitize_text_field(wp_unslash($_POST[$field_unique_id])) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated and sanitized.
1410 }
1411
1412 switch ($field_type) {
1413 case 'checkbox':
1414 $options = $field_attrs['fieldItem']['advanced']['checkboxOptions']['desktop']['value'] ?? [];
1415 $fields_raw[$field_key]['options'] = is_array($options) ? array_map(
1416 function ($option) {
1417 return wp_strip_all_tags($option['value'] ?? '');
1418 },
1419 $options
1420 ) : [];
1421 break;
1422 case 'radio':
1423 $options = $field_attrs['fieldItem']['advanced']['radioOptions']['desktop']['value'] ?? [];
1424 $fields_raw[$field_key]['options'] = is_array($options) ? array_map(
1425 function ($option) {
1426 return sanitize_text_field($option['value'] ?? '');
1427 },
1428 $options
1429 ) : [];
1430 break;
1431 case 'select':
1432 $options = $field_attrs['fieldItem']['advanced']['selectOptions']['desktop']['value'] ?? [];
1433 $fields_raw[$field_key]['options'] = is_array($options) ? array_map(
1434 function ($option) {
1435 return sanitize_text_field($option['value'] ?? '');
1436 },
1437 $options
1438 ) : [];
1439 break;
1440 default:
1441 $fields_raw[$field_key]['options'] = [];
1442 break;
1443 }
1444 }
1445
1446 $refClass = new ReflectionClass('\ET\Builder\Packages\ModuleLibrary\ContactForm\ContactFormHandler');
1447 $obj = $refClass->newInstanceWithoutConstructor();
1448
1449 try {
1450 $refFields = $refClass->getProperty('_fields_raw');
1451 $refFields->setAccessible(true);
1452 $refFields->setValue($obj, $fields_raw);
1453
1454 $refError = $refClass->getProperty('_error');
1455 $refError->setAccessible(true);
1456 $refError->setValue($obj, new WP_Error());
1457 } catch (\ReflectionException $e) {
1458 return $module_attrs;
1459 }
1460
1461 $obj->validate_fields();
1462 $errorObj = $refError->getValue($obj);
1463
1464 if ($errorObj->has_errors()) {
1465 return $module_attrs;
1466 }
1467
1468 $fields_raw = $refFields->getValue($obj);
1469
1470 $item = !empty($module_attrs['module']['meta']['adminLabel']['desktop']['value']) ? $module_attrs['module']['meta']['adminLabel']['desktop']['value'] : '';
1471 if (!$item) {
1472 return $module_attrs;
1473 }
1474
1475 $data = [
1476 'E2PDF_VERSION' => '1.32.40',
1477 'fields' => [],
1478 'options' => [
1479 'timestamp' => current_time('mysql'),
1480 'saveFilesToMedia' => !empty($module_attrs['entryPreferences']['advanced']['saveFilesToMedia']['desktop']['value']) ? $module_attrs['entryPreferences']['advanced']['saveFilesToMedia']['desktop']['value'] : '',
1481 'uniqueId' => !empty($module_attrs['module']['advanced']['uniqueId']['desktop']['value']) ? $module_attrs['module']['advanced']['uniqueId']['desktop']['value'] : '',
1482 ],
1483 ];
1484
1485 if (!empty($fields_raw) && is_array($fields_raw)) {
1486 foreach ($fields_raw as $field_key => $field_raw) {
1487 if (isset($field_raw['value'])) {
1488 $data['fields'][$field_key] = [
1489 'type' => isset($field_raw['type']) ? $field_raw['type'] : '',
1490 'value' => $field_raw['value'],
1491 ];
1492 }
1493 }
1494 }
1495 if (empty($data['fields']['_wp_http_referer']) && !empty($_POST['_wp_http_referer'])) {
1496 $data['fields']['_wp_http_referer'] = [
1497 'type' => '',
1498 'value' => esc_url_raw($_POST['_wp_http_referer']),
1499 ];
1500 }
1501
1502 $entry = new Model_E2pdf_Dataset();
1503 $entry->set('extension', 'divi');
1504 $entry->set('item', $item);
1505 $entry->set('entry', $data);
1506 $dataset = $entry->save();
1507
1508 foreach ($messages as $message_key => $message) {
1509 if (false !== strpos($message, '[')) {
1510 $shortcode_tags = [
1511 'e2pdf-download',
1512 'e2pdf-save',
1513 'e2pdf-view',
1514 'e2pdf-adobesign',
1515 'e2pdf-zapier',
1516 'e2pdf-attachment',
1517 ];
1518 preg_match_all('@\[([^<>&/\[\]\x00-\x20=]++)@', $message, $matches);
1519 $tagnames = array_intersect($shortcode_tags, $matches[1]);
1520 if (!empty($tagnames)) {
1521 preg_match_all('/' . $this->helper->load('shortcode')->get_shortcode_regex($tagnames) . '/', $message, $shortcodes);
1522 foreach ($shortcodes[0] as $key => $shortcode_value) {
1523 $item = false;
1524 $shortcode = $this->helper->load('shortcode')->get_shortcode($shortcodes, $key);
1525 $atts = shortcode_parse_atts($shortcode[3]);
1526
1527 if (!isset($atts['dataset']) && isset($atts['id'])) {
1528 $template = new Model_E2pdf_Template();
1529 $template->load($atts['id']);
1530 if ($template->get('extension') === 'divi') {
1531 $item = $template->get('item');
1532 $atts['dataset'] = $dataset;
1533 $shortcode[3] .= ' dataset="' . $dataset . '"';
1534 }
1535 }
1536 if (!isset($atts['apply'])) {
1537 $shortcode[3] .= ' apply="true"';
1538 }
1539 if (!isset($atts['iframe_download'])) {
1540 $shortcode[3] .= ' iframe_download="true"';
1541 }
1542 switch ($message_key) {
1543 case 'successMessage':
1544 $module_attrs['module']['advanced']['successMessage']['desktop']['value'] = str_replace($shortcode_value, do_shortcode_tag($shortcode), $module_attrs['module']['advanced']['successMessage']['desktop']['value']);
1545 break;
1546 case 'email':
1547 $module_attrs['email']['innerContent']['desktop']['value'] = str_replace($shortcode_value, '[' . $shortcode[2] . $shortcode[3] . ']', $module_attrs['email']['innerContent']['desktop']['value']);
1548 break;
1549 case 'adminEmailRichTextMessage':
1550 case 'confirmationEmailMessage':
1551 case 'confirmationEmailRichTextMessage':
1552 $messages[$message_key] = str_replace($shortcode_value, '{' . $shortcode[2] . $shortcode[3] . '}', $messages[$message_key]);
1553 break;
1554 default:
1555 break;
1556 }
1557 }
1558 }
1559 }
1560 }
1561
1562 foreach ($messages as $message_key => $message) {
1563 switch ($message_key) {
1564 case 'adminEmailRichTextMessage':
1565 $class = '\KS_PAC_DCFH\Frontend\Controllers\ContactFormDataRepository';
1566 if (class_exists($class) && method_exists($class, 'instance')) {
1567 $contact_form_rep = $class::instance();
1568 $contact_form_rep->admin_message = $messages[$message_key];
1569 }
1570 break;
1571 case 'confirmationEmailMessage':
1572 case 'confirmationEmailRichTextMessage':
1573 $class = '\KS_PAC_DCFH\Frontend\Services\ConfirmationEmailService';
1574 if (class_exists($class) && method_exists($class, 'instance')) {
1575 $contact_form_rep = $class::instance();
1576 $contact_form_rep->email_message = $messages[$message_key];
1577 }
1578 break;
1579 default:
1580 break;
1581 }
1582 }
1583 return $module_attrs;
1584 }
1585
1586 // filter shortcode attributes
1587 public function filter_et_pb_module_shortcode_attributes($props, $attrs, $render_slug, $address, $content) {
1588
1589 if ($render_slug !== 'et_pb_contact_form') {
1590 return $props;
1591 }
1592
1593 $et_contact_proccess = array_search('et_contact_proccess', (array) $_POST);
1594 if ($et_contact_proccess === false) {
1595 return $props;
1596 }
1597
1598 $success_message = isset($props['success_message']) ? $this->decode_shortcodes($props['success_message'], true) : '';
1599
1600 if (false !== strpos($success_message, '[')) {
1601 $shortcode_tags = [
1602 'e2pdf-download',
1603 'e2pdf-save',
1604 'e2pdf-view',
1605 'e2pdf-adobesign',
1606 'e2pdf-zapier',
1607 ];
1608 preg_match_all('@\[([^<>&/\[\]\x00-\x20=]++)@', $success_message, $matches);
1609 $tagnames = array_intersect($shortcode_tags, $matches[1]);
1610 if (!empty($tagnames)) {
1611 $this->set('process', true);
1612 } else {
1613 $success_message = '';
1614 }
1615 }
1616
1617 $admin_email_rich_text = isset($props['use_custom_message_richtext']) && $props['use_custom_message_richtext'] == 'on' && isset($props['custom_message_richtext']) ? true : false;
1618 if ($admin_email_rich_text) {
1619 $admin_email_message = $this->decode_shortcodes($props['custom_message_richtext']);
1620 } else {
1621 $admin_email_message = isset($props['custom_message']) ? $this->decode_shortcodes($props['custom_message']) : '';
1622 }
1623 if (false !== strpos($admin_email_message, '[')) {
1624 $shortcode_tags = [
1625 'e2pdf-download',
1626 'e2pdf-save',
1627 'e2pdf-attachment',
1628 'e2pdf-adobesign',
1629 'e2pdf-zapier',
1630 ];
1631 preg_match_all('@\[([^<>&/\[\]\x00-\x20=]++)@', $admin_email_message, $matches);
1632 $tagnames = array_intersect($shortcode_tags, $matches[1]);
1633 if (!empty($tagnames)) {
1634 $this->set('process', true);
1635 } else {
1636 $admin_email_message = '';
1637 }
1638 }
1639
1640 /* Divi Contact Form Helper Confirmation Email and Confirmation Email RichText */
1641 $user_email_rich_text = isset($props['use_confirmation_email']) && $props['use_confirmation_email'] == 'on' && isset($props['use_confirmation_message_richtext']) && $props['use_confirmation_message_richtext'] == 'on' && isset($props['confirmation_message_richtext']) ? true : false;
1642 if ($user_email_rich_text) {
1643 $user_email_message = $this->decode_shortcodes($props['confirmation_message_richtext']);
1644 } else {
1645 $user_email_message = isset($props['use_confirmation_email']) && $props['use_confirmation_email'] == 'on' && isset($props['confirmation_email_message']) ? $this->decode_shortcodes($props['confirmation_email_message']) : '';
1646 }
1647 if (false !== strpos($user_email_message, '[')) {
1648 $shortcode_tags = [
1649 'e2pdf-download',
1650 'e2pdf-save',
1651 'e2pdf-attachment',
1652 'e2pdf-adobesign',
1653 'e2pdf-zapier',
1654 ];
1655 preg_match_all('@\[([^<>&/\[\]\x00-\x20=]++)@', $user_email_message, $matches);
1656 $tagnames = array_intersect($shortcode_tags, $matches[1]);
1657 if (!empty($tagnames)) {
1658 $this->set('process', true);
1659 } else {
1660 $user_email_message = '';
1661 }
1662 }
1663
1664 $_POST = $this->sanitize($_POST);
1665
1666 // check if E2Pdf shortcodes exist in messages
1667 if (!$this->get('process')) {
1668 return $props;
1669 }
1670
1671 $data = $_POST;
1672 if (isset($props['_unique_id'])) {
1673 $data['_unique_id'] = $props['_unique_id'];
1674 }
1675 if (isset($props['save_files_to_media']) && $props['save_files_to_media'] == 'on') {
1676 $data['_save_files_to_media'] = $props['save_files_to_media'];
1677 $data['_subdir'] = wp_upload_dir()['subdir'];
1678 } elseif (function_exists('pwh_dcfh_file_helpers')) {
1679 $subdir = pwh_dcfh_file_helpers()::get_subdir();
1680 if (is_array($subdir)) {
1681 $data['_subdir'] = implode('/', $subdir);
1682 }
1683 } elseif (function_exists('ks_pac_dcfh_file_helper')) {
1684 $subdir = ks_pac_dcfh_file_helper()::get_subdir();
1685 if (is_array($subdir)) {
1686 $data['_subdir'] = implode('/', $subdir);
1687 }
1688 }
1689
1690 $captcha = isset($props['captcha']) ? $props['captcha'] : '';
1691 $use_spam_service = isset($props['use_spam_service']) ? $props['use_spam_service'] : 'off';
1692 $et_pb_contact_form_num = str_replace('et_pb_contactform_submit_', '', $et_contact_proccess);
1693 $et_contact_error = false;
1694 $current_form_fields = isset($data['et_pb_contact_email_fields_' . $et_pb_contact_form_num]) ? $data['et_pb_contact_email_fields_' . $et_pb_contact_form_num] : '';
1695 $contact_email = '';
1696 $nonce_result = isset($data['_wpnonce-et-pb-contact-form-submitted-' . $et_pb_contact_form_num]) && wp_verify_nonce($data['_wpnonce-et-pb-contact-form-submitted-' . $et_pb_contact_form_num], 'et-pb-contact-form-submit') ? true : false;
1697
1698 if ($nonce_result && isset($data['et_pb_contactform_submit_' . $et_pb_contact_form_num]) && empty($data['et_pb_contact_et_number_' . $et_pb_contact_form_num])) {
1699 if ('' !== $current_form_fields) {
1700 $fields_data_json = str_replace('\\', '', $current_form_fields);
1701 $fields_data_array = json_decode($fields_data_json, true);
1702
1703 // check whether captcha field is not empty
1704 if ('on' === $captcha && 'off' === $use_spam_service && (!isset($data['et_pb_contact_captcha_' . $et_pb_contact_form_num]) || empty($data['et_pb_contact_captcha_' . $et_pb_contact_form_num]))) {
1705 $et_contact_error = true;
1706 } elseif ('on' === $use_spam_service) {
1707 if (class_exists('ET_Builder_Element')) {
1708 $contact_form = ET_Builder_Element::get_module('et_pb_contact_form');
1709 if ($contact_form && is_object($contact_form) && method_exists($contact_form, 'is_spam_submission')) {
1710 $contact_form->props = $props;
1711 if ($contact_form->is_spam_submission()) {
1712 if (!empty($_POST['token'])) {
1713 unset($_POST['token']);
1714 }
1715 $et_contact_error = true;
1716 } else {
1717 $props['use_spam_service'] = 'off';
1718 $props['captcha'] = 'off';
1719 }
1720 }
1721 }
1722 }
1723
1724 // check all fields on current form and generate error message if needed
1725 if (!empty($fields_data_array)) {
1726 foreach ($fields_data_array as $value) {
1727 if (isset($value['field_id']) && 'et_pb_contact_et_number_' . $et_pb_contact_form_num === $value['field_id']) {
1728 continue;
1729 }
1730 /* Check all the required fields, generate error message if required field is empty */
1731 $field_value = isset($data[$value['field_id']]) ? trim($data[$value['field_id']]) : '';
1732 if ('required' === $value['required_mark'] && empty($field_value) && !is_numeric($field_value)) {
1733 $et_contact_error = true;
1734 continue;
1735 }
1736 /* Additional check for email field */
1737 if ('email' === $value['field_type'] && 'required' === $value['required_mark'] && !empty($field_value)) {
1738 $contact_email = isset($data[$value['field_id']]) ? sanitize_email($data[$value['field_id']]) : '';
1739 if (!empty($contact_email) && !is_email($contact_email)) {
1740 $et_contact_error = true;
1741 }
1742 }
1743 }
1744 }
1745 } else {
1746 $et_contact_error = true;
1747 }
1748 } else {
1749 $et_contact_error = true;
1750 }
1751
1752 if (!$et_contact_error && $nonce_result) {
1753 // divi contact form helper 2.1.3 bug fix wp_mail filter removed at maybe_filter_wp_mail
1754 if (defined('KS_PAC_DCFH_PLUGIN_VERSION') && version_compare(KS_PAC_DCFH_PLUGIN_VERSION, '2.1.3', '>=')) {
1755 add_filter(
1756 'wp_mail', function ($args) {
1757 return $args;
1758 }, 999
1759 );
1760 }
1761 add_filter('wp_mail', [$this, 'filter_wp_mail'], 1000);
1762
1763 $dataset = false;
1764 if (false !== strpos($success_message, '[')) {
1765 $shortcode_tags = [
1766 'e2pdf-download',
1767 'e2pdf-save',
1768 'e2pdf-view',
1769 'e2pdf-adobesign',
1770 'e2pdf-zapier',
1771 ];
1772 preg_match_all('@\[([^<>&/\[\]\x00-\x20=]++)@', $success_message, $matches);
1773 $tagnames = array_intersect($shortcode_tags, $matches[1]);
1774 if (!empty($tagnames)) {
1775 preg_match_all('/' . $this->helper->load('shortcode')->get_shortcode_regex($tagnames) . '/', $success_message, $shortcodes);
1776 foreach ($shortcodes[0] as $key => $shortcode_value) {
1777 $item = false;
1778 $shortcode = $this->helper->load('shortcode')->get_shortcode($shortcodes, $key);
1779 $atts = shortcode_parse_atts($shortcode[3]);
1780 if ($this->helper->load('shortcode')->is_attachment($shortcode, $atts)) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedIf
1781 } else {
1782 if (!isset($atts['dataset']) && isset($atts['id'])) {
1783 $template = new Model_E2pdf_Template();
1784 $template->load($atts['id']);
1785 if ($template->get('extension') === 'divi') {
1786 $item = $template->get('item');
1787 if (!$dataset) {
1788 $entry = new Model_E2pdf_Dataset();
1789 $entry->set('extension', 'divi');
1790 $entry->set('item', $item);
1791 $entry->set('entry', $data);
1792 $dataset = $entry->save();
1793 }
1794 $atts['dataset'] = $dataset;
1795 $shortcode[3] .= ' dataset="' . $dataset . '"';
1796 }
1797 }
1798 if (!isset($atts['apply'])) {
1799 $shortcode[3] .= ' apply="true"';
1800 }
1801 if (!isset($atts['iframe_download'])) {
1802 $shortcode[3] .= ' iframe_download="true"';
1803 }
1804 $props['success_message'] = str_replace($this->encode_shortcodes($shortcode_value), '[' . $shortcode[2] . $shortcode[3] . ']', $props['success_message']);
1805 }
1806 }
1807 }
1808 }
1809
1810 if (false !== strpos($admin_email_message, '[')) {
1811 $shortcode_tags = [
1812 'e2pdf-download',
1813 'e2pdf-save',
1814 'e2pdf-attachment',
1815 'e2pdf-adobesign',
1816 'e2pdf-zapier',
1817 ];
1818 preg_match_all('@\[([^<>&/\[\]\x00-\x20=]++)@', $admin_email_message, $matches);
1819 $tagnames = array_intersect($shortcode_tags, $matches[1]);
1820 if (!empty($tagnames)) {
1821 preg_match_all('/' . $this->helper->load('shortcode')->get_shortcode_regex($tagnames) . '/', $admin_email_message, $shortcodes);
1822 foreach ($shortcodes[0] as $key => $shortcode_value) {
1823 $item = false;
1824 $shortcode = $this->helper->load('shortcode')->get_shortcode($shortcodes, $key);
1825 $atts = shortcode_parse_atts($shortcode[3]);
1826 if (!isset($atts['dataset']) && isset($atts['id'])) {
1827 $template = new Model_E2pdf_Template();
1828 $template->load($atts['id']);
1829 if ($template->get('extension') === 'divi') {
1830 $item = $template->get('item');
1831 if (!$dataset) {
1832 $entry = new Model_E2pdf_Dataset();
1833 $entry->set('extension', 'divi');
1834 $entry->set('item', $item);
1835 $entry->set('entry', $data);
1836 $dataset = $entry->save();
1837 }
1838 $atts['dataset'] = $dataset;
1839 $shortcode[3] .= ' dataset="' . $dataset . '"';
1840 }
1841 }
1842 if ($admin_email_rich_text) {
1843 if ((defined('PWH_DCFH_PLUGIN_VERSION') && version_compare(PWH_DCFH_PLUGIN_VERSION, '1.5.1', '>=')) || defined('KS_PAC_DCFH_PLUGIN_FILE')) {
1844 $props['custom_message_richtext'] = str_replace($this->encode_shortcodes($shortcode_value), '{' . $shortcode[2] . $shortcode[3] . '}', $props['custom_message_richtext']);
1845 } else {
1846 $props['custom_message_richtext'] = str_replace($this->encode_shortcodes($shortcode_value), '[' . $shortcode[2] . $shortcode[3] . ']', $props['custom_message_richtext']);
1847 }
1848 } else {
1849 $props['custom_message'] = str_replace($this->encode_shortcodes($shortcode_value), '[' . $shortcode[2] . $shortcode[3] . ']', $props['custom_message']);
1850 }
1851 }
1852 }
1853 }
1854
1855 if (false !== strpos($user_email_message, '[')) {
1856 $shortcode_tags = [
1857 'e2pdf-download',
1858 'e2pdf-save',
1859 'e2pdf-attachment',
1860 'e2pdf-adobesign',
1861 'e2pdf-zapier',
1862 ];
1863 preg_match_all('@\[([^<>&/\[\]\x00-\x20=]++)@', $user_email_message, $matches);
1864 $tagnames = array_intersect($shortcode_tags, $matches[1]);
1865 if (!empty($tagnames)) {
1866 preg_match_all('/' . $this->helper->load('shortcode')->get_shortcode_regex($tagnames) . '/', $user_email_message, $shortcodes);
1867 foreach ($shortcodes[0] as $key => $shortcode_value) {
1868 $item = false;
1869 $shortcode = $this->helper->load('shortcode')->get_shortcode($shortcodes, $key);
1870 $atts = shortcode_parse_atts($shortcode[3]);
1871 if (!isset($atts['dataset']) && isset($atts['id'])) {
1872 $template = new Model_E2pdf_Template();
1873 $template->load($atts['id']);
1874 if ($template->get('extension') === 'divi') {
1875 $item = $template->get('item');
1876 if (!$dataset) {
1877 $entry = new Model_E2pdf_Dataset();
1878 $entry->set('extension', 'divi');
1879 $entry->set('item', $item);
1880 $entry->set('entry', $data);
1881 $dataset = $entry->save();
1882 }
1883 $atts['dataset'] = $dataset;
1884 $shortcode[3] .= ' dataset="' . $dataset . '"';
1885 }
1886 }
1887 if ((defined('PWH_DCFH_PLUGIN_VERSION') && version_compare(PWH_DCFH_PLUGIN_VERSION, '1.5.1', '>=')) || defined('KS_PAC_DCFH_PLUGIN_FILE')) {
1888 if ($user_email_rich_text) {
1889 $props['confirmation_message_richtext'] = str_replace($this->encode_shortcodes($shortcode_value), '{' . $shortcode[2] . $shortcode[3] . '}', $props['confirmation_message_richtext']);
1890 } else {
1891 $props['confirmation_email_message'] = str_replace($this->encode_shortcodes($shortcode_value), '{' . $shortcode[2] . $shortcode[3] . '}', $props['confirmation_email_message']);
1892 }
1893 } else {
1894 if ($user_email_rich_text) {
1895 $props['confirmation_message_richtext'] = str_replace($this->encode_shortcodes($shortcode_value), '[' . $shortcode[2] . $shortcode[3] . ']', $props['confirmation_message_richtext']);
1896 } else {
1897 $props['confirmation_email_message'] = str_replace($this->encode_shortcodes($shortcode_value), '[' . $shortcode[2] . $shortcode[3] . ']', $props['confirmation_email_message']);
1898 }
1899 }
1900 }
1901 }
1902 }
1903 }
1904
1905 return $props;
1906 }
1907
1908 // filter shortcode output
1909 public function filter_et_module_shortcode_output($output, $render_slug, $form) {
1910
1911 if ($render_slug !== 'et_pb_contact_form') {
1912 return $output;
1913 }
1914
1915 $et_contact_proccess = array_search('et_contact_proccess', (array) $_POST);
1916 if ($et_contact_proccess === false) {
1917 return $output;
1918 }
1919
1920 $et_pb_contact_form_num = str_replace(['pwh_dcfh_et_pb_contactform_submit_', 'et_pb_contactform_submit_'], ['', ''], $et_contact_proccess);
1921 $nonce_result = isset($_POST['_wpnonce-et-pb-contact-form-submitted-' . $et_pb_contact_form_num]) && wp_verify_nonce($_POST['_wpnonce-et-pb-contact-form-submitted-' . $et_pb_contact_form_num], 'et-pb-contact-form-submit') ? true : false;
1922
1923 if ($nonce_result && (
1924 (isset($_POST['et_pb_contactform_submit_' . $et_pb_contact_form_num]) && empty($_POST['et_pb_contact_et_number_' . $et_pb_contact_form_num])) ||
1925 (isset($_POST['pwh_dcfh_et_pb_contactform_submit_' . $et_pb_contact_form_num]) && $_POST['pwh_dcfh_et_pb_contactform_submit_' . $et_pb_contact_form_num] == 'et_contact_proccess')
1926 )
1927 ) {
1928 $success_message = isset($form->props['success_message']) ? $this->decode_shortcodes($form->props['success_message'], true) : '';
1929 if (false !== strpos($success_message, '[')) {
1930 $shortcode_tags = [
1931 'e2pdf-download',
1932 'e2pdf-save',
1933 'e2pdf-view',
1934 'e2pdf-adobesign',
1935 'e2pdf-zapier',
1936 ];
1937 preg_match_all('@\[([^<>&/\[\]\x00-\x20=]++)@', $success_message, $matches);
1938 $tagnames = array_intersect($shortcode_tags, $matches[1]);
1939 if (!empty($tagnames)) {
1940 preg_match_all('/' . $this->helper->load('shortcode')->get_shortcode_regex($tagnames) . '/', $success_message, $shortcodes);
1941 foreach ($shortcodes[0] as $key => $shortcode_value) {
1942 $shortcode = $this->helper->load('shortcode')->get_shortcode($shortcodes, $key);
1943 if (isset($form->props['enable_multistep']) && 'on' === $form->props['enable_multistep']) {
1944 $output = str_replace($shortcode_value, do_shortcode_tag($shortcode), $output);
1945 } else {
1946 $output = str_replace(str_replace(['"'], ['&quot;'], $shortcode_value), do_shortcode_tag($shortcode), $output);
1947 }
1948 }
1949 }
1950 }
1951 }
1952 return $output;
1953 }
1954
1955 // delete item
1956 public function delete_item($template_id = false, $dataset = false) {
1957 global $wpdb;
1958 $template = new Model_E2pdf_Template();
1959 if ($template_id && $dataset && $template->load($template_id)) {
1960 if ($template->get('extension') === 'divi' && $template->get('item')) {
1961 $item = $template->get('item');
1962 $where = [
1963 'ID' => $dataset,
1964 'item' => $item,
1965 'extension' => 'divi',
1966 ];
1967 $wpdb->delete($wpdb->prefix . 'e2pdf_datasets', $where);
1968 return true;
1969 }
1970 }
1971 return false;
1972 }
1973
1974 // delete items
1975 public function delete_items($template_id = false) {
1976 global $wpdb;
1977 $template = new Model_E2pdf_Template();
1978 if ($template_id && $template->load($template_id)) {
1979 if ($template->get('extension') === 'divi' && $template->get('item')) {
1980 $where = [
1981 'item' => $template->get('item'),
1982 'extension' => 'divi',
1983 ];
1984 $wpdb->delete($wpdb->prefix . 'e2pdf_datasets', $where);
1985 return true;
1986 }
1987 }
1988 return false;
1989 }
1990
1991 // styles
1992 public function styles($item_id = false) {
1993 $styles = [];
1994 if ($this->divi5()) {
1995 $assets_list = \ET\Builder\FrontEnd\Assets\DynamicAssetsUtils::get_assets_list(
1996 [
1997 'prefix' => \ET\Builder\FrontEnd\Assets\DynamicAssetsUtils::get_dynamic_assets_path(),
1998 'suffix' => '',
1999 'specialty_suffix' => '',
2000 ]
2001 );
2002 foreach ($assets_list as $list) {
2003 if (!empty($list['css']) && is_array($list['css'])) {
2004 foreach ($list['css'] as $css) {
2005 $styles[] = $this->wp_convert_path_to_url($css);
2006 }
2007 }
2008 }
2009 }
2010 $styles[] = plugins_url('css/extension/divi.css?v=' . time(), $this->helper->get('plugin_file_path'));
2011 return $styles;
2012 }
2013
2014 public function wp_convert_path_to_url($path) {
2015 // Standardize slashes for Windows/Linux compatibility
2016 $path = wp_normalize_path($path);
2017 $root = wp_normalize_path(ABSPATH);
2018
2019 // Replace the server root with the Site URL
2020 return str_replace($root, site_url('/'), $path);
2021 }
2022
2023 // sanitize
2024 public function sanitize($value) {
2025 if (is_array($value)) {
2026 foreach ($value as $k => $v) {
2027 $value[$k] = $this->sanitize($v);
2028 }
2029 return $value;
2030 }
2031 if (!is_string($value)) {
2032 return $value;
2033 }
2034 if (stripos($value, 'e2pdf-') === false) {
2035 return $value;
2036 }
2037 return preg_replace('/(?:\[|&#91;|\{)(e2pdf-download|e2pdf-view|e2pdf-save|e2pdf-attachment|e2pdf-adobesign|e2pdf-zapier)[^\]}\r\n]*(?:\]|&#93;|\})/i', '', $value);
2038 }
2039
2040 // decode shortcodes
2041 public function decode_shortcodes($value = '', $quote = false) {
2042 return preg_replace_callback(
2043 '/(&#91;)((e2pdf-download|e2pdf-view|e2pdf-save|e2pdf-attachment|e2pdf-adobesign|e2pdf-zapier)[^&]*?)(&#93;)/',
2044 function ($m) use ($quote) {
2045 $shortcode = $m[2];
2046 if ($quote !== false) {
2047 $shortcode = str_replace('&quot;', '"', $shortcode);
2048 }
2049
2050 return '[' . $shortcode . ']';
2051 },
2052 $value
2053 );
2054 }
2055
2056 // encode shortcodes
2057 public function encode_shortcodes($value = '', $quote = false) {
2058 return preg_replace_callback(
2059 '/(\[)((e2pdf-download|e2pdf-view|e2pdf-save|e2pdf-attachment|e2pdf-adobesign|e2pdf-zapier)[^\]]*?)(\])/',
2060 function ($m) use ($quote) {
2061 $shortcode = $m[2];
2062 if ($quote !== false) {
2063 $shortcode = str_replace('"', '&quot;', $shortcode);
2064 }
2065
2066 return '&#91;' . $shortcode . '&#93;';
2067 },
2068 $value
2069 );
2070 }
2071
2072 // divi4 load
2073 public function divi4_load() {
2074 if (defined('ET_BUILDER_DIR') && !$this->divi5()) {
2075 require_once ET_BUILDER_DIR . 'class-et-builder-element.php';
2076 require_once ET_BUILDER_DIR . 'functions.php';
2077 require_once ET_BUILDER_DIR . 'ab-testing.php';
2078 require_once ET_BUILDER_DIR . 'class-et-global-settings.php';
2079 if (file_exists(ET_BUILDER_DIR . 'module/type/WithSpamProtection.php')) {
2080 require_once ET_BUILDER_DIR . 'module/type/WithSpamProtection.php';
2081 }
2082 require_once ET_BUILDER_DIR . 'module/ContactForm.php';
2083 require_once ET_BUILDER_DIR . 'module/ContactFormItem.php';
2084 new ET_Builder_Module_Contact_Form();
2085 new ET_Builder_Module_Contact_Form_Item();
2086 }
2087 }
2088
2089 // is divi5
2090 public function divi5() {
2091 if (defined('ET_CORE_VERSION') && version_compare(ET_CORE_VERSION, '4.99', '>')) {
2092 return true;
2093 }
2094 return false;
2095 }
2096
2097 // is divi4 form
2098 public function divi4_form($content = '') {
2099 return (false !== strpos($content, '[et_pb_contact_form'));
2100 }
2101
2102 // is divi 5 form
2103 public function divi5_form($content = '') {
2104 return (false !== strpos($content, 'wp:divi/contact-form'));
2105 }
2106
2107 // pwh dcfh resolve file url
2108 public function pwh_dcfh_resolve_file_url($file, $options) {
2109
2110 if (!$file) {
2111 return $file;
2112 }
2113
2114 if (!function_exists('ks_pac_dcfh_app') || !function_exists('path_join')) {
2115 return $file;
2116 }
2117
2118 $contact_form_id = $options['uniqueId'];
2119 $timestamp = strtotime($options['timestamp']);
2120 $saveFilesToMedia = $options['saveFilesToMedia'] === 'on' ? true : false;
2121
2122 $upload_dir = path_join(
2123 'pwh-dcfh-uploads',
2124 'forms/' . $contact_form_id . '/'
2125 );
2126 $upload_path = ks_pac_dcfh_app()->file_utils()::get_wp_upload_dir(
2127 $upload_dir,
2128 'basedir'
2129 );
2130 $upload_url = ks_pac_dcfh_app()->file_utils()::get_wp_upload_dir(
2131 $upload_dir,
2132 'baseurl'
2133 );
2134 if ($saveFilesToMedia) {
2135 $wp_upload_dir = wp_upload_dir();
2136 $upload_path = $wp_upload_dir['basedir'];
2137 $upload_url = $wp_upload_dir['baseurl'];
2138 }
2139 $dates = [
2140 date('Y/m', $timestamp),
2141 date('Y/m', strtotime('-1 month', $timestamp)),
2142 date('Y/m', strtotime('+1 month', $timestamp)),
2143 ];
2144
2145 foreach ($dates as $date) {
2146 $date_path = path_join(
2147 $upload_path,
2148 $date
2149 );
2150 if (@file_exists(path_join($date_path, $file))) {
2151 $file = path_join(
2152 trailingslashit($upload_url) . $date,
2153 $file
2154 );
2155 break;
2156 }
2157 }
2158 return $file;
2159 }
2160 }
2161