Crocoblock / jetformbuilder

80 stars 16 forks source link

[Featured Request] [Solution] e-Signature | Media Upload | Send to PDF #371

Open EquilibriumTechx opened 12 months ago

EquilibriumTechx commented 12 months ago

HI, Croco team,

please help to improve this code to suit your JFB, so that this can be a new add on,

// Include the Dompdf library
if (!class_exists('Dompdf\Dompdf')) {
    require_once(WP_CONTENT_DIR . '/dompdf/autoload.inc.php');
}
use Dompdf\Dompdf;

// Add the signature field to the form on the 'contact' page
if (!has_action('wp_footer', 'my_custom_add_signature_field_to_contact_form')) {
    add_action('wp_footer', 'my_custom_add_signature_field_to_contact_form');
}

if (!function_exists('my_custom_add_signature_field_to_contact_form')) {
    function my_custom_add_signature_field_to_contact_form() {
        if (is_page('dashboard')) {
            ?>
            <script src="https://cdnjs.cloudflare.com/ajax/libs/signature_pad/1.5.3/signature_pad.min.js"></script>
            <script type="text/javascript">
                jQuery(document).ready(function ($) {

                    //signature pad 
                    if ($('#signature-pad').length === 0) {
                        var signatureFieldHTML = `
                            <div class="ev_signature_field">
                                <label for="ev_signature">Signature:</label>
                                <canvas id="signature-pad" width="400" height="200"></canvas>
                                <button type="button" id="clear-button">Clear</button>
                                <input type="hidden" name="ev_signature" id="ev_signature">
                            </div>`;

                        var submitButton = $('form .submit_ev_form').first();
                        submitButton.parent().before(signatureFieldHTML);

                        var canvas = document.getElementById('signature-pad');
                        var signaturePad = new SignaturePad(canvas);

                        $('#clear-button').on('click', function () {
                            signaturePad.clear();
                        });

                        $('form').on('submit', function (e) {
                            if (signaturePad.isEmpty()) {
                                e.preventDefault();
                                alert('Please provide a signature.');
                            } else {
                                $('#ev_signature').val(signaturePad.toDataURL());
                            }
                        });
                    }
                });
            </script>
            <style>
                .ev_signature_field {
                    text-align: left;
                    padding: 15px 0;
                }

                .ev_signature_field label {
                    display: block;
                    margin-bottom: 5px;
                }

                #signature-pad {
                    width: auto !important;
                    height: auto !important;
                    border: 1px solid #000;
                    border-radius: 10px;
                }

                #clear-button {
                    background-color: #ffffff;
                    color: #000000;
                    font-size: 12px;
                    font-weight: 400;
                    padding: 15px;
                    border: 1px solid #333333;
                    border-radius: 6px;
                    cursor: pointer;
                    display: block;
                    margin-top: 5px;
                    margin-bottom: 5px;
                    transition: background-color 0.3s ease, color 0.3s ease, border 0.3s ease;
                }

                #clear-button:hover {
                    background-color: #164afe;
                    color: #ffffff;
                    border: 1px solid #164afe;
                }
            </style>
            <?php
        }
    }
}

// Add a filter to wp_mail to modify the email before sending
if (!has_filter('wp_mail', 'attach_pdf_to_wp_mail_v2')) {
    add_filter('wp_mail', 'attach_pdf_to_wp_mail_v2', 10, 1);
}

if (!function_exists('attach_pdf_to_wp_mail_v2')) {
    function attach_pdf_to_wp_mail_v2($args) {

    // Define the subject line you set in JetFormBuilder for your form submission emails
    $expected_subject_line = 'EV Form Signed'; // Replace with your form's subject line

    // Check if the email is the result of a JetFormBuilder form submission by subject
    if (strpos($args['subject'], $expected_subject_line) !== false) {

        // Retrieve the form submission data
        $form_data = get_form_submission_data(); // Dynamic field retrieval

        // Handle media file upload
        $media = $_FILES['mediafield'];
        $file_url = '';
        if ($media['error'] === UPLOAD_ERR_OK) {
            $upload = wp_handle_upload($media, ['test_form' => false]);
            $file_url = $upload['url'];
            $form_data['mediafield'] = $file_url; // Add the media URL to form data
        }

        // Initialize Dompdf and generate the PDF
        $dompdf = new Dompdf();

        // Get the logo image data using cURL
        $logo_url = 'https://test1.equilibrium.my/wp-content/uploads/2023/10/valtech-logo.png'; //url of the logo
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $logo_url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        $logo_data = curl_exec($ch);
        curl_close($ch);

        // Generate a data URL for the logo image
        $logo_data_uri = 'data:image/webp;base64,' . base64_encode($logo_data);

        // Define CSS for the HTML content
        $css = "
            <style>
                body { font-family: 'Helvetica', 'Arial', sans-serif; }
                h1 { color: #333; margin-top: 20px; }
                p { color: #555; font-size: 14px; margin-bottom: 5px; }
                .content-wrapper { padding: 20px; }
                .header img { width: 150px; height: auto; margin-bottom: 10px; }
                .media-img { max-width: 300px; height: 200px; margin-top: 10px; margin-bottom: 10px;}
                .logo-img { max-width: 150px; height: 150px; margin-top: 10px;}
            </style>
        ";

        // Generate the HTML content for the PDF with the form data
        $html_content = $css . "
            <div class='header'>
                <img src='{$logo_data_uri}' alt='Company Logo'>
            </div>
            <div class='content-wrapper'>
                <h1>Submission Details</h1>";
        foreach ($form_data as $field_name => $value) {
                if ($field_name === 'mediafield' && !empty($value)) {
                    // Embed the media image
                    $media_data = base64_encode(file_get_contents($value));
                    $media_src = 'data:image/' . pathinfo($value, PATHINFO_EXTENSION) . ';base64,' . $media_data;
                    $html_content .= "<p><strong>Media:</strong></p><img src='" . $media_src . "' alt='Uploaded Media' class='media-img'>";
                } elseif ($field_name === 'ev_signature' && !empty($value)) {
                    $html_content .= "<p><strong>Signature:</strong></p><img src='$value' alt='Uploaded Signature' class='logo-img' >";
                } else {
                    // Convert line breaks to <br> tags and preserve HTML formatting
                    $formatted_value = nl2br($value);
                    $html_content .= "<p><strong>" . ucfirst(str_replace('_', ' ', $field_name)) . ":</strong> " . $formatted_value . "</p>";
                }
            }

        // Add the values of ev_f_name and ev_l_name
        $first_name = $form_data['ev_f_name'];
        $last_name = $form_data['ev_l_name'];
        $html_content .= "<p><strong><em>" . esc_html($first_name) . " ". esc_html($last_name) . "</em></p>";

        // Set the timezone to Asia/Kuala_Lumpur
        date_default_timezone_set('Asia/Kuala_Lumpur');

        // Add the current date and time
        $html_content .= "<p>" . date('Y-m-d H:i:s') . "</p>";

        //End Content Wrapper       
        $html_content .= "</div>";

        // Load the HTML content
        $dompdf->loadHtml($html_content);

        // Set paper size and orientation
        $dompdf->setPaper('A4', 'portrait');

        // Set options for page numbering
        $options = $dompdf->getOptions();
        $options->set("isHtml5ParserEnabled", true);
        $options->set("isPhpEnabled", true);
        $options->set("isHtml5PhpEnabled", true);
        $options->set("isPhpEnabled", true);

        // Render the PDF
        $dompdf->render();

        // Add page numbers to each page after rendering
        $canvas = $dompdf->getCanvas();
        $canvas->page_script(function ($pageNumber, $pageCount, $canvas, $fontMetrics) {
            $text = "Page $pageNumber of $pageCount";
            $size = 12; // adjust font size as needed
            $font = $fontMetrics->get_font('Arial, Helvetica, sans-serif', 'normal', $size);
            $canvas->text(270, 820, $text, $font, $size);
        });

        // Save the PDF to a file
        $pdf_output = $dompdf->output();
        $pdf_file_path = sys_get_temp_dir() . '/form_submission_' . time() . '.pdf'; //file name
        file_put_contents($pdf_file_path, $pdf_output);

        // Attach the PDF to the email
        $args['attachments'] = array($pdf_file_path);
    }

    // Return the modified email arguments
    return $args;
}
}

// Function to dynamically retrieve form submission data
function get_form_submission_data() {
    $form_data = array();

    // Criteria to exclude non-user-added fields
    $excluded_patterns = array(
        '/^wp_/', // WordPress specific fields
        '/^jet_/', // JetFormBuilder specific fields
        '/_id$/',  // Fields ending with '_id'
        '/^_/',    // Hidden or internal fields
    );

    foreach ($_POST as $key => $value) {
        // Skip fields that match the exclusion criteria
        foreach ($excluded_patterns as $pattern) {
            if (preg_match($pattern, $key)) {
                continue 2;
            }
        }

        // Allow HTML tags for specific fields (e.g., text areas)
        $allowed_html_tags = array(
            'a' => array(
                'href' => array(),
                'title' => array()
            ),
            'br' => array(),
            'em' => array(),
            'strong' => array(),
            'i' => array(),
            'b' => array(),
            'p' => array(),
            'h1' => array(),
            'h2' => array(),
            'h3' => array(),
            'h4' => array(),
            'h5' => array(),
            'h6' => array(),
        );

        // Sanitize the field based on its type
        switch (true) {
            case filter_var($value, FILTER_VALIDATE_EMAIL):
                $form_data[$key] = sanitize_email($value);
                break;
            case is_string($value):
                $form_data[$key] = wp_kses($value, $allowed_html_tags);
                break;
            case isset($_POST['ev_signature']):
                $form_data['ev_signature'] = $_POST['ev_signature'];
                break;
        }
    }
    return $form_data;
}

// Add a action to the form to add a media field upload
if (!has_action('wp_footer', 'add_media_upload_field_to_form')) {
    add_action('wp_footer', 'add_media_upload_field_to_form', 10, 1);
}

add_action('wp_footer', 'add_media_upload_field_to_form');
// Add the media upload field to the form
function add_media_upload_field_to_form() {
    ?>
    <style>
        input#mediafield {
            padding: 30px;
            border-style: solid;
            border-width: 1px;
            border-radius: 10px;
            width: 400px;

        }
        .media-upload-field {
            margin-bottom: 20px; /* Adjust as needed */
        }
        .media-upload-field label {
            display: block;
            margin-bottom:5px;
            margin-top: 20px;
        }

        @media only screen and (max-width: 768px) {
    input#mediafield {
        margin-bottom: 15px; /* Adjusted for smaller screens */
    width: 80% !important;
    }
    </style>
    <script type="text/javascript">
        jQuery(document).ready(function($) {
            // Function to add the media upload field
            function addMediaField() {
                // Check if the media upload field already exists to avoid duplicates
                if ($('#mediafield').length === 0) {
                    // Create the media upload field
                    var mediaField = '<div class="media-upload-field"><label for="mediafield">Media (Max: 1 file, 4MB):</label><input type="file" name="mediafield" id="mediafield" required></div>';

                    // Insert the media upload field before the specified class
                    $('.mediafield_class').before(mediaField);

                    // Add file upload restrictions
                    $('#mediafield').on('change', function(e) {
                        var file = e.target.files[0];
                        if (file) {
                            // Check file size
                            if (file.size > 4194304) { // 4MB in bytes
                                alert('Maximum file size: 4MB');
                                e.target.value = ''; // Clear the file input
                            }

                            // Check file type
                            if (!['image/png', 'image/jpeg', 'image/webp', 'image/gif'].includes(file.type)) {
                                alert('Allowed file types: png, jpg, webp, gif');
                                e.target.value = ''; // Clear the file input
                            }
                        }
                    });
                }
            }

            // Try to add the media field immediately
            addMediaField();

            // Retry adding the media field after a short delay to handle any timing issues
            setTimeout(addMediaField, 500);
        });
    </script>
    <?php
}