PHP mail() function not notifying jQuery of succes

2019-09-09 09:44发布

问题:

PHP mail() loop is running, and sending properly, with no errors. However, my jQuery isn't working, to notify either a success or error message on the front end.

PHP:

add_action( 'wp_ajax_invfr_process_ajax', 'invfr_sendmail');
add_action( 'wp_ajax_nopriv_invfr_process_ajax', 'invfr_sendmail');
function invfr_sendmail() {
    $post = ( !empty( $_POST ) ) ? true : false;

    if( $post ) {
        $subject = invfr_get_settings( 'subject' );
        $message = invfr_get_settings( 'message' );
        $friends = $_POST['friend_email'];
        $errors = array();
        foreach ( $friends as $key => $friend ) {
            $name = stripslashes( $_POST['friend_name'][$key] );
            $email = trim( $_POST['friend_email'][$key] );

            // Check name
            if( !$name )
                $errors[] = '#friend_name-' . $key;

            if( !$email )
                $errors[] = '#friend_email-' . $key;

            if( $email && !is_email( $email ) )
                $errors[] = '#friend_email-' . $key;
        }

        // send email 
        if( !$errors ) {
            foreach ( $friends as $key => $friend )
                $mail = wp_mail( $email, invfr_tokens_replacement( $subject, $_POST, $key ), invfr_tokens_replacement( $message, $_POST, $key ) );
            if( $mail )
                echo 'sent';
        }
        else
            echo json_encode( $errors );
    }
}

jQuery:

<script type="text/javascript"> 
            var jQuery = jQuery.noConflict();
            jQuery(window).load(function(){ 
                jQuery('#invfr_form').submit(function() {
                    // change visual indicators
                    jQuery('td').removeClass('error');
                    jQuery('.loading').show();
                    jQuery('.submit input').attr('disabled', 'disabled');
                    // validate and process form here
                    var str = jQuery(this).serialize();                  
                       jQuery.ajax({
                           type: 'POST',
                           url: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
                           data: str,
                           success: function(msg) { 
                                jQuery('#invfr_note').ajaxComplete(function(event, request, settings) {
                                    msg = msg.replace(/(\s+)?.$/, "");  
                                    if( msg == 'sent' ) {
                                        result = '<div class="updated"><p><?php _e( 'Your invitation has been sent! Send another?', 'invfr' ); ?></p></div>';
                                        jQuery('#invfr_form input[type=text], #invfr_form input[type=email]').val('');
                                    } else {
                                        //loop through the error items to indicate which fields have errors
                                        msg = msg.replace(/[\[\]']+/g,'');
                                        msg = msg.split(',');
                                        jQuery.each( msg, function ( i, id ) {
                                            id = id.replace(/["']{1}/g, '');
                                            jQuery(id).parent('td').addClass('error');
                                        });
                                        result = '<div class="error"><p><?php _e( '<strong>ERROR:</strong> Check your form for the errors which are highlighted below.', 'invfr' ); ?></p></div>';
                                        //result = msg;
                                        msg = '';
                                    }
                                    jQuery(this).html(result);
                                    // visual indicators
                                    jQuery('.loading').hide();
                                    jQuery('.submit input').removeAttr('disabled');                      
                                });                  
                            }                    
                        });                  
                    return false;
                });         
            });
        </script>

Thanks for any help!

回答1:

Here are some generic steps to follow. Please note, these are examples, not complete code. You must find the correct ways to apply this information in your case.

First, in WP, add your function as an ajax callback:

add_action ( 'wp_ajax_my_action', 'invfr_sendmail' ); 
// The AJAX command is 'my_action'

You must make some modifications in your function. For one, echoing things there won't give a reply. But let's start at the beginning! Inside your callback function invfr_sendmail, add the code that receives the form from jQuery. Since they come as an encoded string, we must parse them on the top:

$my_form_data = array(); // Create an empty array
parse_str( $_POST['my_form_data'], $my_form_data ); // Fills $my_form_data

Now, instead of using $_POST['fieldname'], you use $my_form_data['fieldname'].

In the end of your PHP code, you must send the JSON encoded replies to jQuery. For example:

$success = true;
$errors = array( 'This one was wrong', 'That one too' );
$some_other_value = false;
// Put these variables in an array
$results = compact( 'success', 'errors', 'some_other_value' ); 
wp_send_json( $results );

Send your form via AJAX and listen for the answer.

jQuery('form#my_form_name').on('submit', function(event){
    event.preventDefault(); // Stops the form from being submitted via POST
    var data = {
        command: 'my_action', // The same name you used in WP 'add_action' above
        my_form_data: jQuery('form#my_form_name').serialize()
    };
    jQuery('.loading').show();
    jQuery.ajax({ 
        type: 'POST',
        url: ajaxurl,
        data: data
    }).done( function( response ) {
        // This runs when the server replies something
        if (response.success) {
            // This corresponds to the $success variable we set  
            jQuery('#someElement').html('The operation was a success!')
        }
        if (response.errors) {
            // This would be the $errors array from PHP
            response.errors.each( function(errorMessage) {
                jQuery('#someElement').append( errorMessage );
            } );
        }
        if (response.some_other_value) {
            // Here nothing happens if $some_other_value in PHP was false
        }
    }).fail( function( jqXHR, textStatus, errorThrown ) {
        // This runs when the request fails (i.e. timeout)
        jQuery('#someElement').html( 'The AJAX request failed with error message ' + errorThrown ); 

    }).always( function() {
        // This runs always after an AJAX request, even a failed one
        jQuery('.loading').hide();
    });
});

Hope this example will set you well on your way with your plugin!