1

I am creating a like system in PHP . My code looks like this .

<?php 
class Like_System {
    private $userid;
    private $postid;
    private $user_ko_like_count;
    private $post_ko_like_count;
    private $user_ko_dislike_count;
    private $post_ko_dislike_count;
    private $user_ip;

    public function __construct(){
    }
    public function our_ajax_script(){
        wp_enqueue_script( 'sb_like_post', get_template_directory_uri().'/data/js/post-like.min.js', false, '1.0', 1 );
        wp_localize_script( 'sb_like_post', 'ajax_var', array(
            'url' => admin_url( 'admin-ajax.php' ),
            'nonce' => wp_create_nonce( 'like_system' )
            )
        );
    }
    public function load_our_ajax_script(){
        add_action( 'init', array($this,"our_ajax_script") );
        add_action( 'wp_ajax_nopriv_like_system',array($this,"like_dislike_kernal"));
        add_action( 'wp_ajax_like_system',array($this,"like_dislike_kernal"));
    }
    public function verify_nonce($nonce){
        if ( ! wp_verify_nonce( $nonce, 'like_system' ) )
        die ();
    }
    public function like_dislike_kernal(){
        extract($_POST);
        $this->verify_nonce($nonce);

        $this->postid=$postid;
        $this->userid=get_current_user_id();
        $this->post_ko_like_count = get_post_meta( $postid, "_post_ko_like_count", true );

        if($system=="like"){
            if(is_user_logged_in()){
                $this->logged_in_user_like_kernal();
            }else{
                $this->anonymous_user_like_kernal();
            }
        }
        die();
    }
    private function make_array_if_not_exist($var){
        if(!is_array($var)){
            $var=[];
            return $var;
        }
        return $var;
    }
    private function already_liked_or_disliked($whattocheck="liked"){
        if(is_user_logged_in()){
            $post_ma_like_garney_user=$this->make_array_if_not_exist(get_post_meta( $this->postid, "_post_ma_like_garney_user", true ));
            if(in_array($this->userid,$post_ma_like_garney_user)) return true;
        }
        return false;
    }
    private function logged_in_user_like_kernal(){  
        $user_lay_like_gareko_posts=$this->make_array_if_not_exist(get_user_option( "_user_lay_like_gareko_posts", $this->userid  ));
        $post_ma_like_garney_user=$this->make_array_if_not_exist(get_post_meta( $this->postid, "_post_ma_like_garney_user", true ));

        $user_lay_like_gareko_posts["Post_ID_".$this->postid]=$this->postid;
        $post_ma_like_garney_user["User_ID_".$this->userid]=$this->userid;

        if($this->already_liked_or_disliked()==false){
            update_post_meta( $this->postid, "_post_ko_like_count", $this->post_ko_like_count + 1 ); 
            echo $this->post_ko_like_count + 1; // update count on front end
        }else{
            $ukey= array_search( $this->userid,  $post_ma_like_garney_user);
            $pkey= array_search( $this->postid, $user_lay_like_gareko_posts );

            unset( $user_lay_like_gareko_posts[$pkey] ); // remove from array
            unset( $post_ma_like_garney_user[$ukey] ); // remove from array
            update_post_meta( $this->postid, "_post_ko_like_count", --$this->post_ko_like_count );
            echo $this->post_ko_like_count; 
        }

    }

}
$like_system=new Like_System();
$like_system->load_our_ajax_script();
?>

Basically, when user click like button the ajax works and this like_system class works will add like count on data base by +1

Problem Everything works fine if user click like button slowly . For instance if i click like button and it showed like count 5. When i clicked like after 5 second(suppose) it will unlike and show like count 4 and as we expect if i click the like count will show 5.Like this here is one of test where i consoled log the like counter which toogle correctly when i click button after some interval. enter image description here

But supposed i clicked like button very fast say 5 times in a second . We might expect like count should toggle between 4 and 5 but it doesn't sometimes it shows -1 or -3 and sometime even 8 . Why is this happening ?

Here is the test when i click the like button very fast. enter image description here Digged in to code for hours but still cannot find any problem :(

I even don't know is ajax a problem or php problem :( Thanks.

migrated from stackoverflow.com Oct 30 '15 at 14:26

This question came from our site for professional and enthusiast programmers.

  • That like script needs to prevent more clicks until a response has been received. – popnoodles Oct 13 '15 at 15:15
  • @charlietfl If the path was invalid then the php should not update database show like count isn't it? By the which invalid path you are saying ? – user80946 Oct 13 '15 at 15:16
  • idk why this happens, but an alternative solution from the ui perspective is to disable the button until all the liking/unliking processes are complete, then re-enable it, so they cant spam click and mess up the system. i would still try to figure out why the spam clicking breaks the system though, but the ui solution is like a safety net just in case. gl – indubitablee Oct 13 '15 at 15:22
  • What about the flow ? User click like button -> javascript update count -> ajax request fire ->ajax response->javascript update the like button to show that it is liked. Something like this? Can you tell exactly how it is ? – frz3993 Oct 13 '15 at 15:28
  • @indubitablee yea but first we need to find the problem isn't it . We might disable button but adding disabled attributes but client can easily control the html javascript etc. They can do anything isn't it ? – user80946 Oct 13 '15 at 15:29
0

You can try to use .one()

From documentation:

The .one() method is identical to .on(), except that the handler is unbound after its first invocation.

  • Yeah by the way we know all user are not loyal. They may know these problem and modify the jquery code. And may ruin all the like creating huge problem isn't it? – user80946 Oct 13 '15 at 16:13
  • of course, you need to check on server side is current object already liked by current user. For example, you can keep likes in table with two columns(object_id, user_id). Then you can "select count(*) where object_id is your current". And before saving like, you can check, is user_id already exists for current object_id. – Sergio Ivanuzzo Oct 13 '15 at 16:37
0

Use a flag to check if the ajax is still doing something

Something like this:

$('.yourdiv').click(function(){
    if(ajax_working)
       return false;

    ajax_working = true;
    $.post('/your/url',function(){
       ajax_working = false;
    })
})
  • yea this may be workaround . But still the thing is jquery is client side isn't it? user can modify code and ruin the databse etc.. isn't it? – user80946 Oct 13 '15 at 16:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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