Plugin Directory

Changeset 3246282


Ignore:
Timestamp:
02/25/2025 09:08:20 AM (13 months ago)
Author:
maximumsoftware
Message:

Deploy from Git

Location:
pdf-forms-for-wpforms/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • pdf-forms-for-wpforms/trunk/js/admin.js

    r3214289 r3246282  
    9292                            return false;
    9393                       
    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;
    9996                        if(counts)
    10097                            count++;
     
    113110                    jQuery.each(items, function(index, item)
    114111                    {
    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)
    118114                        {
    119115                            exists = true;
     
    123119                    if(!exists)
    124120                    {
    125                         items = Object.assign([], items); // shallow copy
     121                        items = shallowCopy(items);
    126122                        items.unshift({id: tag, text: tag, lowerText: lowerTag});
    127123                    }
     
    133129               
    134130                callback({
    135                     results: items,
     131                    results: deepCopy(items),
    136132                    pagination: { more: more }
    137133                });
     
    285281    });
    286282   
     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   
    287328    var clearMessages = function()
    288329    {
     
    405446                    return;
    406447               
    407                 var all_attachment_data = Object.assign({}, field); // shallow copy
    408                 var current_attachment_data = Object.assign({}, field); // shallow copy
     448                var all_attachment_data = shallowCopy(field);
     449                var current_attachment_data = shallowCopy(field);
    409450               
    410451                all_attachment_data['id'] = 'all-' + field.id;
     
    533574        try
    534575        {
    535             var field = Object.assign({}, wpf.getField(id)); // shallow copy
     576            var field = deepCopy(wpf.getField(id));
    536577            var name = "Field #" + id;
    537578            if(field.hasOwnProperty('label') && field.label != "")
     
    685726        if(!info)
    686727            return;
     728       
     729        data = deepCopy(data);
    687730       
    688731        var filename = info.filename;
     
    840883            jQuery.each(data.value_mappings, function(index, value_mapping) {
    841884               
     885                value_mapping = shallowCopy(value_mapping);
     886               
    842887                // find mapping id
    843888                for(var i=0, l=mappings.length; i<l; i++)
     
    9701015        || typeof data.pdf_value == 'undefined')
    9711016            return;
     1017       
     1018        data = deepCopy(data);
    9721019       
    9731020        data.value_mapping_id = generateId();
     
    11141161    var addMapping = function(data)
    11151162    {
     1163        data = deepCopy(data);
     1164       
    11161165        data.mapping_id = generateId();
    11171166        pluginData["mappings"].push(data);
     
    13491398                return;
    13501399        }
     1400       
     1401        embed = deepCopy(embed);
    13511402       
    13521403        if(!embed.id)
     
    17501801                    setAttachmentData(data.attachment_id, data);
    17511802                   
    1752                     var options = Object.assign({}, defaultPdfOptions); // shallow copy
     1803                    var options = deepCopy(defaultPdfOptions);
    17531804                   
    17541805                    // add first notification by default
     
    19041955                        if(pdf_field_data.hasOwnProperty('options') && (Array.isArray(pdf_field_data.options) || typeof pdf_field_data.options == 'object'))
    19051956                        {
    1906                             var options = Object.assign({}, pdf_field_data.options); // shallow copy
     1957                            var options = shallowCopy(pdf_field_data.options);
    19071958                            if(!Array.isArray(options))
    19081959                                options = Object.values(options);
     
    24262477    jQuery(document).on('wpformsFieldUpdate', function(e, changeFields) {
    24272478       
    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                }
    24602494            });
    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);
    24752527        });
    24762528    });
  • pdf-forms-for-wpforms/trunk/pdf-forms-for-wpforms.php

    r3214289 r3246282  
    44 * Plugin URI: https://pdfformsfiller.org/
    55 * 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.11
     6 * Version: 1.2.0
    77 * Requires at least: 5.4
    88 * Requires PHP: 5.5
     
    2525    class Pdf_Forms_For_WPForms
    2626    {
    27         const VERSION = '1.1.11';
     27        const VERSION = '1.2.0';
    2828        const MIN_WPFORMS_VERSION = '1.6.9';
    2929        const MAX_WPFORMS_VERSION = '1.9.99';
     
    7979           
    8080            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 );
    8283            add_action( 'wpforms_process_complete', array( $this, 'remove_tmp_dir' ), 99, 0 );
    8384            add_filter( 'wpforms_emails_send_email_data', array( $this, 'attach_files' ), 10, 2 );
     
    805806                    "image/svg+xml",
    806807                    "image/webp",
     808                    "application/pdf",
    807809                );
    808810           
     
    841843         * We need to fill the pdf's document fields and then create attachment file and attach them
    842844         */
    843         public function fill_pdfs( $wpform_fields, $entry, $form_data )
     845        public function fill_pdfs( $wpforms_fields, $entry, $form_data )
    844846        {
    845847            try
    846848            {
    847849                $entry_id = $entry["id"];
    848                 $wpform_fields_data = $entry['fields'];
    849850               
    850851                $attachments = array();
     
    879880                   
    880881                    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'];
    885883                    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 );
    889885                   
    890886                    if( $url != null )
     
    990986                }
    991987               
    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 ) )
    995991                    {
    996992                        if(
    997993                            // 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 )
    999995                           
    1000996                            // 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'] ) )
    1002998                           
    1003999                            // 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']] ) )
    10051001                        )
    1006                             $multiselectable_wpform_fields[$wpform_field['name']] = $wpform_field['name'];
     1002                            $multiselectable_wpforms_fields[ $wpforms_field['id'] ] = $wpforms_field['id'];
    10071003                    }
    10081004               
     
    10321028                       
    10331029                        $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"] ] ) )
    10351031                            || ( isset( $fields[$field]['flags'] ) && in_array( 'MultiSelect', $fields[$field]['flags'] ) );
    10361032                       
    10371033                        if( isset( $mapping["wpf_field"] ) )
    1038                             $data[$field] = $wpform_fields_data[$mapping["wpf_field"]];
     1034                            $data[$field] = $wpforms_fields[$mapping["wpf_field"]]['value'];
    10391035                       
    10401036                        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 )
    10411040                        {
    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 );
    10511045                        }
    10521046                    }
     
    12881282                    $destfilename = strval( $attachment['options']['filename'] );
    12891283                    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 ) );
    12911285                    if( $destfilename == "" )
    12921286                        $destfilename = sanitize_file_name( get_the_title( $attachment_id ) );
     
    13631357                            $tag_replaced_path_elements = array();
    13641358                            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 );
    13661360                           
    13671361                            foreach( $tag_replaced_path_elements as $elmid => &$new_element )
     
    14011395                $this->wpforms_mail_attachments = array();
    14021396            }
     1397           
     1398            return $wpforms_fields;
    14031399        }
    14041400       
     
    15271523        {
    15281524            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 ) ),
    15301526                array_values( $tags ),
    15311527                $string
  • pdf-forms-for-wpforms/trunk/readme.txt

    r3214289 r3246282  
    11=== PDF Forms Filler for WPForms ===
    2 Version: 1.1.11
    3 Stable tag: 1.1.11
    4 Requires at least: 5.4
     2Version: 1.2.0
     3Stable tag: 1.2.0
    54Tested up to: 6.7
    6 Requires PHP: 5.5
    75Tags: pdf, form, wpforms, email, download
    86Plugin URI: https://pdfformsfiller.org/
     
    108Author URI: https://maximum.software/
    119Contributors: maximumsoftware
     10Donate link: https://github.com/sponsors/maximum-software
    1211License: GPLv3
    1312License URI: https://www.gnu.org/licenses/gpl-3.0.html
     
    5251
    5352== 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
    5465
    5566= 1.1.11 =
     
    159170* Initial release
    160171
     172== Upgrade Notice ==
     173
     174= 1.2.0 =
     175WARNING: This version includes changes that may affect plugin behavior. Please test your forms thoroughly after updating.
     176
    161177== Frequently Asked Questions ==
    162178
Note: See TracChangeset for help on using the changeset viewer.