4

For the plugin i wrote, AJAX request on the frontend works properly if i am admin, but the same thing doesn't work when i try it as normal user, it always returns 0.

This is plugin's core php file where i am doing all the enqueue and localize stuff:

require_once ( plugin_dir_path(__FILE__) . 'like-user-request.php' );

function lr_enqueue_ui_scripts() {
    wp_enqueue_script( 'core-likeranker-js', plugins_url( 'js/like.js', __FILE__ ), array( 'jquery', 'jquery-ui-datepicker' ), false, true );
    wp_enqueue_style( 'jquery-style', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/smoothness/jquery-ui.css' );
    wp_localize_script( 'core-likeranker-js', 'my_ajax_object', array( 'ajax_url' => admin_url('admin-ajax.php'), 'security' => wp_create_nonce('user-like') ) );
}

add_action( 'wp_enqueue_scripts', 'lr_enqueue_ui_scripts');

This is javascript file

jQuery(document).ready(function($){

var state = $('#post-like-count').data('user-state');

$('.like-button').on('click', function(){
    var count = $('#post-like-count').data('id');
    var postId = $('#post-like-count').data('post-id');
    state == 1 ? count++ : count--;

    $.ajax({
        url: my_ajax_object.ajax_url,
        type: 'POST',
        dataType: 'json',
        data: {
            action: 'save_like',
            likeCount: count,
            id: postId,
            userState: state,
            security: my_ajax_object.security
        },
        success: function(response) {
            if(response.success === true){
                $('#post-like-count').html(count + ' Likes');
                $('#post-like-count').data('id', count);
                if(state == 1){
                    state = 2;
                    $('.like-button').html('Dislike');
                }
                else {
                    state = 1;
                    $('.like-button').html('Like !');
                }
                $('#post-like-count').data('user-state', state);
            }
        },
        error:function(error) {
            $('.like-box').after('Error');
        }
    });
  })
});

Php file that i handle the AJAX request

<?php
function lr_save_like_request() {
    if ( ! check_ajax_referer( 'user-like', 'security' ) ) {
        wp_send_json_error( 'Invalid Nonce !' );
    }

    $count = $_POST['likeCount'];
    $postId = $_POST['id'];
    $ip;

    if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
        //check ip from share internet
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
        //to check ip is pass from proxy
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } else {
        $ip = $_SERVER['REMOTE_ADDR'];
    }

    $voters_ip = get_post_meta( $postId, '_voters_ip', false );

    $flag = empty( $voters_ip ) ? 1 : 0;

    if( $_POST['userState'] == 1 ) {
        if( $flag == 1 ) {
            $voters_ip_buffer = $voters_ip;
            $voters_ip_buffer[] = $ip;
        } else {
            $voters_ip_buffer = $voters_ip[0];
            $voters_ip_buffer[] = $ip;
        }
    } else {
        $voters_ip_buffer = $voters_ip[0];
        for ( $i=0; $i < count($voters_ip_buffer); $i++ ) {
            if( $ip == $voters_ip_buffer[$i] ) {
                unset( $voters_ip_buffer );
            }
        }
    }

    if( ! update_post_meta( $postId, '_Like', $count ) ) {
        add_post_meta ( $postId, '_Like', $count, true );
    }

    if( ! update_post_meta( $postId, '_voters_ip', $voters_ip_buffer ) ) {
        add_post_meta ( $postId, '_voters_ip', $voters_ip_buffer, true );
    }

    wp_send_json_success( array(
        'state' => $_POST['userState']
    ));

    wp_die();
}

add_action( 'wp_ajax_save_like', 'lr_save_like_request' );
1
  • 5
    hook starting with wp_ajax_ are for connected user. for unconnected visitors, you need wp_ajax_nopriv_save_like
    – mmm
    Apr 8, 2017 at 8:38

2 Answers 2

4

As mmm didn't post an answer but just wrote a comment, here is the answer:

As the documentation for wp_ajax states in its notes, the hook only fires for logged in users. If you want to use an ajax call on the frontend for users that are not logged in, you have to use the wp_ajax_nopriv hook.

So instead of

add_action( 'wp_ajax_save_like', 'lr_save_like_request' );

you have to write

add_action( 'wp_ajax_nopriv_save_like', 'lr_save_like_request' );

Thats all, the functionality of the two hooks is exactly the same, the only difference is that one fires only for logged in users and the other one for everybody.

1
  • 1
    Thanka @Larzan, you save my day. :) Apr 8, 2020 at 13:44
1

Everything has to match here:

JS:
data: {
action: 'save_like',
likeCount: count,
id: postId,
userState: state,
security: my_ajax_object.security
},

ACTION HOOKS:
add_action('wp_ajax_save_like', 'save_like');
add_action('wp_ajax_nopriv_save_like', 'save_like');

FUNCTION TO PROCESS AJAX REQUEST
function save_like() {}

http://www.makeuseof.com/tag/tutorial-ajax-wordpress/

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.