Changeset 3246282
- Timestamp:
- 02/25/2025 09:08:20 AM (13 months ago)
- Location:
- pdf-forms-for-wpforms/trunk
- Files:
-
- 3 edited
-
js/admin.js (modified) (15 diffs)
-
pdf-forms-for-wpforms.php (modified) (12 diffs)
-
readme.txt (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
pdf-forms-for-wpforms/trunk/js/admin.js
r3214289 r3246282 92 92 return false; 93 93 94 if(!item.hasOwnProperty("lowerText")) 95 item.lowerText = item.text.toLowerCase(); 96 97 var counts = item.lowerText.indexOf(upperTerm) >= 0; 98 94 var lowerText = item.hasOwnProperty("lowerText") ? item.lowerText : item.text.toLowerCase(); 95 var counts = lowerText.indexOf(upperTerm) >= 0; 99 96 if(counts) 100 97 count++; … … 113 110 jQuery.each(items, function(index, item) 114 111 { 115 if(!item.hasOwnProperty("lowerText")) 116 item.lowerText = String(item.text).toLowerCase(); 117 if(item.id == tag || item.lowerText == lowerTag) 112 var lowerText = item.hasOwnProperty("lowerText") ? item.lowerText : String(item.text).toLowerCase(); 113 if(item.id == tag || lowerText == lowerTag) 118 114 { 119 115 exists = true; … … 123 119 if(!exists) 124 120 { 125 items = Object.assign([], items); // shallow copy121 items = shallowCopy(items); 126 122 items.unshift({id: tag, text: tag, lowerText: lowerTag}); 127 123 } … … 133 129 134 130 callback({ 135 results: items,131 results: deepCopy(items), 136 132 pagination: { more: more } 137 133 }); … … 285 281 }); 286 282 283 var shallowCopy = function(obj) 284 { 285 if(obj === null || typeof obj !== 'object') 286 return obj; 287 if(Array.isArray(obj)) 288 return obj.slice(); 289 try 290 { 291 return Object.assign({}, obj); 292 } 293 catch (e) 294 { 295 console.error('shallowCopy: failed to copy value of type ' + typeof obj); 296 return obj; 297 } 298 }; 299 300 var deepCopy = function(obj) 301 { 302 // return primitive values as-is 303 if(obj === null || typeof obj !== 'object') 304 return obj; 305 306 // use structuredClone if available (modern browsers) 307 if(typeof structuredClone === 'function') 308 try { return structuredClone(obj); } catch (e) { } // ignore failure 309 310 // fallback implementation for older browsers 311 312 if(Array.isArray(obj)) 313 return obj.map(function(item) { return deepCopy(item); }); 314 315 try 316 { 317 var copy = {}; 318 Object.keys(obj).forEach(function(key) { copy[key] = deepCopy(obj[key]); }); 319 return copy; 320 } 321 catch (e) 322 { 323 console.error('deepCopy: failed to copy value of type ' + typeof obj); 324 return obj; 325 } 326 }; 327 287 328 var clearMessages = function() 288 329 { … … 405 446 return; 406 447 407 var all_attachment_data = Object.assign({}, field); // shallow copy408 var current_attachment_data = Object.assign({}, field); // shallow copy448 var all_attachment_data = shallowCopy(field); 449 var current_attachment_data = shallowCopy(field); 409 450 410 451 all_attachment_data['id'] = 'all-' + field.id; … … 533 574 try 534 575 { 535 var field = Object.assign({}, wpf.getField(id)); // shallow copy576 var field = deepCopy(wpf.getField(id)); 536 577 var name = "Field #" + id; 537 578 if(field.hasOwnProperty('label') && field.label != "") … … 685 726 if(!info) 686 727 return; 728 729 data = deepCopy(data); 687 730 688 731 var filename = info.filename; … … 840 883 jQuery.each(data.value_mappings, function(index, value_mapping) { 841 884 885 value_mapping = shallowCopy(value_mapping); 886 842 887 // find mapping id 843 888 for(var i=0, l=mappings.length; i<l; i++) … … 970 1015 || typeof data.pdf_value == 'undefined') 971 1016 return; 1017 1018 data = deepCopy(data); 972 1019 973 1020 data.value_mapping_id = generateId(); … … 1114 1161 var addMapping = function(data) 1115 1162 { 1163 data = deepCopy(data); 1164 1116 1165 data.mapping_id = generateId(); 1117 1166 pluginData["mappings"].push(data); … … 1349 1398 return; 1350 1399 } 1400 1401 embed = deepCopy(embed); 1351 1402 1352 1403 if(!embed.id) … … 1750 1801 setAttachmentData(data.attachment_id, data); 1751 1802 1752 var options = Object.assign({}, defaultPdfOptions); // shallow copy1803 var options = deepCopy(defaultPdfOptions); 1753 1804 1754 1805 // add first notification by default … … 1904 1955 if(pdf_field_data.hasOwnProperty('options') && (Array.isArray(pdf_field_data.options) || typeof pdf_field_data.options == 'object')) 1905 1956 { 1906 var options = Object.assign({}, pdf_field_data.options); // shallow copy1957 var options = shallowCopy(pdf_field_data.options); 1907 1958 if(!Array.isArray(options)) 1908 1959 options = Object.values(options); … … 2426 2477 jQuery(document).on('wpformsFieldUpdate', function(e, changeFields) { 2427 2478 2428 var fields = Object.assign({}, wpf.getFields()); // shallow copy 2429 2430 // update wpfFields labels in mappings 2431 jQuery.each(getMappings(), function(i, data) { 2432 if(!data.hasOwnProperty('wpf_field') || !fields.hasOwnProperty(data.wpf_field)) 2433 return; 2434 2435 var field = fields[data.wpf_field]; 2436 var field_caption = "Field #" + data.wpf_field; 2437 if(field.hasOwnProperty('label') && field.label != "") 2438 field_caption = field.label; 2439 2440 jQuery(".pdf-forms-for-wpforms-admin .pdf-mapping-row[data-mapping_id='" + data.mapping_id + "'] .wpf-field-name").text(field_caption); 2441 }); 2442 2443 // update value mapping drop-downs 2444 select2SharedData.wpfFieldsChoices = {}; 2445 jQuery.each(fields, function (index, field) { 2446 2447 if(!field.hasOwnProperty('choices')) 2448 return; 2449 2450 var id = field.id; 2451 select2SharedData.wpfFieldsChoices[id] = {}; 2452 jQuery.each(field.choices, function (i, choice) { 2453 var text = null; 2454 if(choice.hasOwnProperty('value') && choice.value) 2455 text = String(choice.value); 2456 else if(choice.hasOwnProperty('label') && choice.label) 2457 text = String(choice.label); 2458 if(text) 2459 select2SharedData.wpfFieldsChoices[id][text] = { id: text, text: text, lowerText: text.toLowerCase() }; 2479 if(!changeFields) 2480 return; 2481 2482 jQuery.each(changeFields, function(f, field) { 2483 var wpf_field = field.id; 2484 var field_caption = field.label; 2485 2486 // update wpfFields labels in mappings 2487 var mapping_id = null; 2488 jQuery.each(getMappings(), function(m, mapping) { 2489 if(mapping.wpf_field == wpf_field) 2490 { 2491 mapping_id = mapping.mapping_id; 2492 return false; // break 2493 } 2460 2494 }); 2461 select2SharedData.wpfFieldsChoices[id][''] = { id: '', text: pdf_forms_for_wpforms.__Null_Value_Mapping }; 2462 }); 2463 2464 // update wpfFields labels in embeds 2465 jQuery.each(getEmbeds(), function(i, data) { 2466 if(!data.hasOwnProperty('wpf_field') || !fields.hasOwnProperty(data.wpf_field)) 2467 return; 2468 2469 var field = fields[data.wpf_field]; 2470 var field_caption = "Field #" + data.wpf_field; 2471 if(field.hasOwnProperty('label') && field.label != "") 2472 field_caption = field.label; 2473 2474 jQuery(".pdf-forms-for-wpforms-admin .image-embeds-row[data-embed_id='" + data.id + "'] .wpf-field-caption").text(field_caption); 2495 if(mapping_id) 2496 jQuery(".pdf-forms-for-wpforms-admin .pdf-mapping-row[data-mapping_id='" + mapping_id + "'] .wpf-field-name").text(field_caption); 2497 2498 // update value mapping drop-downs 2499 if(field.hasOwnProperty('choices')) 2500 { 2501 select2SharedData.wpfFieldsChoices[wpf_field] = {}; 2502 jQuery.each(field.choices, function (i, choice) { 2503 var text = null; 2504 if(choice.hasOwnProperty('value') && choice.value) 2505 text = String(choice.value); 2506 else if(choice.hasOwnProperty('label') && choice.label) 2507 text = String(choice.label); 2508 if(text) 2509 select2SharedData.wpfFieldsChoices[wpf_field][text] = { id: text, text: text, lowerText: text.toLowerCase() }; 2510 }); 2511 select2SharedData.wpfFieldsChoices[wpf_field][''] = { id: '', text: pdf_forms_for_wpforms.__Null_Value_Mapping }; 2512 } 2513 else 2514 delete select2SharedData.wpfFieldsChoices[wpf_field]; 2515 2516 // update wpfFields labels in embeds 2517 var embed_id = null; 2518 jQuery.each(getEmbeds(), function(m, embed) { 2519 if(embed.wpf_field == wpf_field) 2520 { 2521 embed_id = embed.id; 2522 return false; // break 2523 } 2524 }); 2525 if(embed_id) 2526 jQuery(".pdf-forms-for-wpforms-admin .image-embeds-row[data-embed_id='" + embed_id + "'] .wpf-field-caption").text(field_caption); 2475 2527 }); 2476 2528 }); -
pdf-forms-for-wpforms/trunk/pdf-forms-for-wpforms.php
r3214289 r3246282 4 4 * Plugin URI: https://pdfformsfiller.org/ 5 5 * Description: Build WPForms from PDF forms. Get PDFs filled automatically and attached to email messages and/or website responses on form submissions. 6 * Version: 1. 1.116 * Version: 1.2.0 7 7 * Requires at least: 5.4 8 8 * Requires PHP: 5.5 … … 25 25 class Pdf_Forms_For_WPForms 26 26 { 27 const VERSION = '1. 1.11';27 const VERSION = '1.2.0'; 28 28 const MIN_WPFORMS_VERSION = '1.6.9'; 29 29 const MAX_WPFORMS_VERSION = '1.9.99'; … … 79 79 80 80 add_filter( 'wpforms_save_form_args', array( $this, 'wpforms_save_form_args' ), 10, 3 ); 81 add_action( 'wpforms_process', array( $this, 'fill_pdfs' ), 10, 3 ); 81 // fill_pdfs: we can't use wpforms_process_complete (because notifications have already been sent) and wpforms_process because uploaded files haven't been processed yet 82 add_filter( 'wpforms_process_after_filter', array( $this, 'fill_pdfs' ), 999999, 3 ); 82 83 add_action( 'wpforms_process_complete', array( $this, 'remove_tmp_dir' ), 99, 0 ); 83 84 add_filter( 'wpforms_emails_send_email_data', array( $this, 'attach_files' ), 10, 2 ); … … 805 806 "image/svg+xml", 806 807 "image/webp", 808 "application/pdf", 807 809 ); 808 810 … … 841 843 * We need to fill the pdf's document fields and then create attachment file and attach them 842 844 */ 843 public function fill_pdfs( $wpform _fields, $entry, $form_data )845 public function fill_pdfs( $wpforms_fields, $entry, $form_data ) 844 846 { 845 847 try 846 848 { 847 849 $entry_id = $entry["id"]; 848 $wpform_fields_data = $entry['fields'];849 850 850 851 $attachments = array(); … … 879 880 880 881 if( isset( $embed["wpf_field"] ) ) 881 { 882 $wpf_field_id = $embed["wpf_field"]; 883 $url = $wpform_fields_data[$wpf_field_id]; 884 } 882 $url = $wpforms_fields[$embed["wpf_field"]]['value']; 885 883 if( isset( $embed['smart_tags'] ) ) 886 { 887 $url = wpforms_process_smart_tags( $embed["smart_tags"], $form_data, $wpform_fields, $entry_id ); 888 } 884 $url = wpforms_process_smart_tags( $embed["smart_tags"], $form_data, $wpforms_fields, $entry_id ); 889 885 890 886 if( $url != null ) … … 990 986 } 991 987 992 $multiselectable_wpform _fields = array();993 foreach( $wpform _fields as $wpform_field )994 if( array_key_exists( 'name', $wpform _field ) )988 $multiselectable_wpforms_fields = array(); 989 foreach( $wpforms_fields as $wpforms_field ) 990 if( array_key_exists( 'name', $wpforms_field ) ) 995 991 { 996 992 if( 997 993 // WPForms checkboxes can have multiple values if the choice limit is more than one 998 ( $wpform _field['type'] == 'checkbox' && intval( $form_data['fields'][$wpform_field['id']]['choice_limit'] ) != 1 )994 ( $wpforms_field['type'] == 'checkbox' && intval( $form_data['fields'][$wpforms_field['id']]['choice_limit'] ) != 1 ) 999 995 1000 996 // WPForms drop-downs can have 'multiple' option 1001 || ( $wpform _field['type'] == 'select' && boolval( $form_data['fields'][$wpform_field['id']]['multiple'] ) )997 || ( $wpforms_field['type'] == 'select' && boolval( $form_data['fields'][$wpforms_field['id']]['multiple'] ) ) 1002 998 1003 999 // support for unknown field types: if field data is an array then it must be that this field supports multiple values 1004 || ( is_array( $ wpform_fields_data[$wpform_field['id']] ) )1000 || ( is_array( $entry['fields'][$wpforms_field['id']] ) ) 1005 1001 ) 1006 $multiselectable_wpform _fields[$wpform_field['name']] = $wpform_field['name'];1002 $multiselectable_wpforms_fields[ $wpforms_field['id'] ] = $wpforms_field['id']; 1007 1003 } 1008 1004 … … 1032 1028 1033 1029 $multiple = 1034 ( isset( $mapping["wpf_field"] ) && isset( $multiselectable_wpform _fields[ $mapping["wpf_field"] ] ) )1030 ( isset( $mapping["wpf_field"] ) && isset( $multiselectable_wpforms_fields[ $mapping["wpf_field"] ] ) ) 1035 1031 || ( isset( $fields[$field]['flags'] ) && in_array( 'MultiSelect', $fields[$field]['flags'] ) ); 1036 1032 1037 1033 if( isset( $mapping["wpf_field"] ) ) 1038 $data[$field] = $wpform _fields_data[$mapping["wpf_field"]];1034 $data[$field] = $wpforms_fields[$mapping["wpf_field"]]['value']; 1039 1035 1040 1036 if( isset( $mapping["smart_tags"] ) ) 1037 $data[$field] = wpforms_process_smart_tags( $mapping["smart_tags"], $form_data, $wpforms_fields, $entry_id ); 1038 1039 if( $multiple ) 1041 1040 { 1042 $data[$field] = wpforms_process_smart_tags( $mapping["smart_tags"], $form_data, $wpform_fields, $entry_id ); 1043 1044 if( $multiple ) 1045 { 1046 $data[$field] = explode( "\n" , $data[$field] ); 1047 foreach( $data[$field] as &$value ) 1048 $value = trim( $value ); 1049 unset( $value ); 1050 } 1041 $data[$field] = explode( "\n" , $data[$field] ); 1042 foreach( $data[$field] as &$value ) 1043 $value = trim( $value ); 1044 unset( $value ); 1051 1045 } 1052 1046 } … … 1288 1282 $destfilename = strval( $attachment['options']['filename'] ); 1289 1283 if( $destfilename != "" ) 1290 $destfilename = strval( wpforms_process_smart_tags( $destfilename, $form_data, $wpform _fields, $entry_id ) );1284 $destfilename = strval( wpforms_process_smart_tags( $destfilename, $form_data, $wpforms_fields, $entry_id ) ); 1291 1285 if( $destfilename == "" ) 1292 1286 $destfilename = sanitize_file_name( get_the_title( $attachment_id ) ); … … 1363 1357 $tag_replaced_path_elements = array(); 1364 1358 foreach ( $path_elements as $key => $value ) 1365 $tag_replaced_path_elements[$key] = wpforms_process_smart_tags( $value, $form_data, $wpform _fields, $entry_id );1359 $tag_replaced_path_elements[$key] = wpforms_process_smart_tags( $value, $form_data, $wpforms_fields, $entry_id ); 1366 1360 1367 1361 foreach( $tag_replaced_path_elements as $elmid => &$new_element ) … … 1401 1395 $this->wpforms_mail_attachments = array(); 1402 1396 } 1397 1398 return $wpforms_fields; 1403 1399 } 1404 1400 … … 1527 1523 { 1528 1524 return str_replace( 1529 array_map( array( get_class(), 'add_curly_braces' ), array_keys( $tags ) ),1525 array_map( array( __CLASS__, 'add_curly_braces' ), array_keys( $tags ) ), 1530 1526 array_values( $tags ), 1531 1527 $string -
pdf-forms-for-wpforms/trunk/readme.txt
r3214289 r3246282 1 1 === PDF Forms Filler for WPForms === 2 Version: 1.1.11 3 Stable tag: 1.1.11 4 Requires at least: 5.4 2 Version: 1.2.0 3 Stable tag: 1.2.0 5 4 Tested up to: 6.7 6 Requires PHP: 5.57 5 Tags: pdf, form, wpforms, email, download 8 6 Plugin URI: https://pdfformsfiller.org/ … … 10 8 Author URI: https://maximum.software/ 11 9 Contributors: maximumsoftware 10 Donate link: https://github.com/sponsors/maximum-software 12 11 License: GPLv3 13 12 License URI: https://www.gnu.org/licenses/gpl-3.0.html … … 52 51 53 52 == Changelog == 53 54 = 1.2.0 = 55 56 * Release date: February 25, 2025 57 58 * WARNING: This version includes changes that may affect plugin behavior. Please test your forms thoroughly after updating. 59 * Switched from `wpforms_process` action to `wpforms_process_after_filter` filter for filling PDFs to fix an issue with file upload fields 60 * Switched from using form submission raw data ($_POST) to formatted field data for filling PDFs 61 * Fixed an issue with file upload URL not being accessible with non-smart-tag mappings 62 * Fixed a bug with multi-selectable field detection 63 * Temporarily added PDF as a supported image format for embedding (until capabilities feature is implemented) 64 * Other minor fixes and improvements 54 65 55 66 = 1.1.11 = … … 159 170 * Initial release 160 171 172 == Upgrade Notice == 173 174 = 1.2.0 = 175 WARNING: This version includes changes that may affect plugin behavior. Please test your forms thoroughly after updating. 176 161 177 == Frequently Asked Questions == 162 178
Note: See TracChangeset
for help on using the changeset viewer.