1

I'm trying to do a simple form submit with ajax (so page won't refresh)

functions.php

add_action('wp_ajax_send_projectmessage', 'send_projectmessage');
function send_projectmessage($projectid, $userid, $message) {
    global $wpdb;
    $wpdb->insert('tbl_messages', array(
        'project_id' => $projectid,
        'user_id' => $userid,
        'message_body' => $message
    ));
    echo 'success?'; //this shows up in console.log but 3 parameters are empty
    wp_die();
}

js:

$('#form-pm').on('submit',function(e) {

    e.preventDefault();

    //hardcode stuff for testing
        var testdata = { 
            'action': 'send_projectmessage',
            'projectid': '71', 
            'userid': '1', 
            'message': 'voila' 
        };

        var ajaxRequest =
        $.ajax({
            url: admin_ajax.ajax_url,
            type: 'post',
            data: testdata
        });

        ajaxRequest.done(function(data) { console.log(data); });
        ajaxRequest.fail(function(jqXHR) { alert('You are fail. ' + jqXHR); });      
});

admin-ajax.php is wired up properly. My error.log says send_projectmessage function is being called, but the parameters are empty. Am I missing something here? I've been pulling my hair since yesterday.

error.log

PHP Warning:  Missing argument 2 for send_projectmessage(), called in /var/www/html/wp-includes/class-wp-hook.php on line 286 and defined in /var/www/html/wp-content/themes/mytheme_child/functions.php on line 178, referer: https://xxxxx
PHP Warning:  Missing argument 3 for send_projectmessage(), called in /var/www/html/wp-includes/class-wp-hook.php on line 286 and defined in /var/www/html/wp-content/themes/mytheme_child/functions.php on line 178, referer: https://xxxxx
WordPress database error Column 'user_id' cannot be null for query INSERT INTO `tbl_messages` (`project_id`, `user_id`, `message_body`) VALUES ('', NULL, NULL) made by do_action('wp_ajax_send_projectmessage'), WP_Hook->do_action, WP_Hook->apply_filters, send_projectmessage, referer: https://xxxxx/

1 Answer 1

2

The values are not passed as parameters, but passed in the $_POST array.

Here's how this should be done:

add_action( 'wp_ajax_send_projectmessage', 'send_projectmessage' );

function send_projectmessage() {

    global $wpdb;

    check_ajax_referer( 'send_projectmessage', 'send_projectmessage_nonce' );

    $projectid = sanitize_text_field( $_POST['projectid'] );
    $userid = sanitize_text_field( $_POST['userid'] );
    $message = sanitize_text_field( $_POST['message'] );

    $wpdb->insert( 'tbl_messages', array(
        'project_id'   => $projectid,
        'user_id'      => $userid,
        'message_body' => $message
    ) );

    wp_send_json_success();
}

I also don't recommend submitting the userid via the POST as that allows users to define it themselves. If this is the WordPress user ID you should instead use internal core function to obtain that value:

add_action( 'wp_ajax_send_projectmessage', 'send_projectmessage' );

function send_projectmessage() {

    global $wpdb;

    check_ajax_referer( 'send_projectmessage', 'send_projectmessage_nonce' );
    $user_id = get_current_user_id();

    if ( empty( $user_id ) ) {
        wp_send_json_error( array( 'not_logged_in' => 'User is not logged in' ) );
        return;
    }

    $projectid = sanitize_text_field( $_POST['projectid'] );
    $message = sanitize_text_field( $_POST['message'] );

    $wpdb->insert( 'tbl_messages', array(
        'project_id'   => $projectid,
        'user_id'      => $user_id,
        'message_body' => $message
    ) );

    wp_send_json_success();
}

For the nonce, see here:

https://codex.wordpress.org/WordPress_Nonces https://codex.wordpress.org/Function_Reference/wp_nonce_field

Somewhere on the page you need to include that hidden nonce field:

<?php wp_nonce_field( 'send_projectmessage', 'send_projectmessage_nonce' ); ?>

And make sure to include it in the POST:

$('#form-pm').on('submit',function(e) {

    e.preventDefault();
    var send_projectmessage_nonce = $('#send_projectmessage_nonce').val();
    //hardcode stuff for testing
        var testdata = { 
            'action': 'send_projectmessage',
            'projectid': '71', 
            'userid': '1', 
            'message': 'voila',
            'send_projectmessage_nonce': send_projectmessage_nonce
        };

        var ajaxRequest =
        $.ajax({
            url: admin_ajax.ajax_url,
            type: 'post',
            data: testdata
        });

        ajaxRequest.done(function(data) { console.log(data); });
        ajaxRequest.fail(function(jqXHR) { alert('You are fail. ' + jqXHR); });      
});
5
  • Thank you, I have no idea about nonce. I am reading about it now. Also I see you're using wp_send_json_success() in place of my wp_die(). From previous readings, people have been saying to put wp_die() there Commented Feb 21, 2019 at 17:29
  • @Rollor no problem, wp_send_json_success, wp_send_json_error both call wp_send_json which calls die for you so no need to add it yourself. Please don’t forget to accept the answer if this resolves your issue (answer will be marked with green check) — this helps other to know that your question/issue has been resolved. Commented Feb 21, 2019 at 17:39
  • This answer is very detailed and easy to understand, with some bonus useful suggestions. Merci beaucoup! Commented Feb 21, 2019 at 17:44
  • Question about the nonce check: On top of my page template, I check if the user is logged in, if( !is_user_logged_in()) { //get out } Therefore, do I still need the nonce check? Commented Feb 21, 2019 at 17:47
  • 1
    @Rollor yes you should ALWAYS use nonce, otherwise they can just strip out the AJAX params from your site and then run it outside of your website and be able to do anything. Always keep security as a first thought even if you think it's not absolutely necessary, it's always better to have it in place, instead of not. Commented Feb 22, 2019 at 14:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.