0

I have a custom plugin which allows users to follow each other. The follow and unfollow functionality works by ajax which is fine but there are just a few bugs that need sorting out which I am unsure as to how I fix them.

  1. When you first come on to a new user's page there is a button that is meant to appear which says "Subscribe" and when you click that button, the ajax fires and then upon success the button is toggled to a hidden button that says "Unsubscribe" but the problem is that when you first visit a new user's page, the "Unsubscribe" button shows up first which is not meant to be happening.

  2. When you subscribe to a new user and you then unsubscribe, if you try to click the unsubscribe button again, the ajax notifies you of an error because you can't unsubscribe twice which is fine but the problem lies when you try to subscribe to a user more than once, for some reason no error is returned and it's allowed.

Here are the functions, please let me know where the errors are and how I can fix the bugs please. Any help would be greatly appreciated.

function tb_get_following( $user_id ) {

if ( empty( $user_id ) ) {
    $user_id = get_current_user_id();
}

$following = get_user_meta( $user_id, '_tb_following', true );

return (array) apply_filters( 'tb_get_following', $following, $user_id );
}

function tb_get_followers( $user_id ) {

if ( empty( $user_id ) ) {
    $user_id = get_current_user_id();
}

$followers = get_user_meta( $user_id, '_tb_followers', true );

return (array) apply_filters( 'tb_get_followers', $followers, $user_id );

}



function tb_follow_user( $user_id, $user_to_follow ) {

$following = tb_get_following( $user_id );

if ( $following && is_array( $following ) ) {
    $following[] = $user_to_follow;
} else {
    $following = array();
    $following[] = $user_to_follow;
}

// retrieve the IDs of all users who are following $user_to_follow
$followers = tb_get_followers( $user_to_follow );

if ( $followers && is_array( $followers ) ) {
    $followers[] = $user_id;
} else {
    $followers = array();
    $followers[] = $user_id;
}

do_action( 'tb_pre_follow_user', $user_id, $user_to_follow );

// update the IDs that this user is following
$followed = update_user_meta( $user_id, '_tb_following', $following );

// update the IDs that follow $user_id
$followers = update_user_meta( $user_to_follow, '_tb_followers', $followers );

// increase the followers count
$followed_count = tb_increase_followed_by_count( $user_to_follow ) ;

if ( $followed ) {

    do_action( 'tb_post_follow_user', $user_id, $user_to_follow );

    return true;
}
return false;
}



function tb_unfollow_user( $user_id, $unfollow_user ) {

do_action( 'tb_pre_unfollow_user', $user_id, $unfollow_user );

// get all IDs that $user_id follows
$following = tb_get_following( $user_id );

if ( is_array( $following ) && in_array( $unfollow_user, $following ) ) {

    $modified = false;

    foreach ( $following as $key => $follow ) {
        if ( $follow == $unfollow_user ) {
            unset( $following[$key] );
            $modified = true;
        }
    }

    if ( $modified ) {
        if ( update_user_meta( $user_id, '_tb_following', $following ) ) {
            tb_decrease_followed_by_count( $unfollow_user );
        }
    }

}

// get all IDs that follow the user we have just unfollowed so that we can remove $user_id
$followers = tb_get_followers( $unfollow_user );

if ( is_array( $followers ) && in_array( $user_id, $followers ) ) {

    $modified = false;

    foreach ( $followers as $key => $follower ) {
        if ( $follower == $user_id ) {
            unset( $followers[$key] );
            $modified = true;
        }
    }

    if ( $modified ) {
        update_user_meta( $unfollow_user, '_tb_followers', $followers );
    }

}

if ( $modified ) {
    do_action( 'tb_post_unfollow_user', $user_id, $unfollow_user );
    return true;
}

return false;
}


function tb_get_following_count( $user_id ) {

if ( empty( $user_id ) ) {
    $user_id = get_current_user_id();
}

$following = tb_get_following( $user_id );

$count = 0;

if ( $following ) {
    $count = count( $following );
}

return (int) apply_filters( 'tb_get_following_count', $count, $user_id );
}



function tb_get_follower_count( $user_id ) {

if ( empty( $user_id ) ) {
    $user_id = get_current_user_id();
}

$followed_count = get_user_meta( $user_id, '_tb_followed_by_count', true );

$count = 0;

if ( $followed_count ) {
    $count = $followed_count;
}

return (int) apply_filters( 'tb_get_follower_count', $count, $user_id );
}

function tb_increase_followed_by_count( $user_id ) {

do_action( 'tb_pre_increase_followed_count', $user_id );

$followed_count = tb_get_follower_count( $user_id );

if ( $followed_count !== false ) {

    $new_followed_count = update_user_meta( $user_id, '_tb_followed_by_count', $followed_count + 1 );

} else {

    $new_followed_count = update_user_meta( $user_id, '_tb_followed_by_count', 1 );

}

do_action( 'tb_post_increase_followed_count', $user_id );

return $new_followed_count;
}

function tb_decrease_followed_by_count( $user_id ) {

do_action( 'tb_pre_decrease_followed_count', $user_id );

$followed_count = tb_get_follower_count( $user_id );

if ( $followed_count ) {

    $count = update_user_meta( $user_id, '_tb_followed_by_count', ( $followed_count - 1 ) );

    do_action( 'tb_post_increase_followed_count', $user_id );

}
return $count;
}



function tb_is_following( $user_id, $followed_user ) {

$following = tb_get_following( $user_id );

$ret = false; // is not following by default

if ( is_array( $following ) && in_array( $followed_user, $following ) ) {
    $ret = true; // is following
}

return (int) apply_filters( 'tb_is_following', $user_id, $followed_user );

}

Here is the functions for the html buttons:

function tb_get_follow_unfollow_links( $follow_id = null ) {

global $user_ID;

if( empty( $follow_id ) )
    return;


if ( $follow_id == $user_ID )
    return;

ob_start(); ?>
    <?php if(is_user_logged_in()): ?>

        <?php if ( pwuf_is_following( $user_ID, $follow_id ) ) { ?>
        <a href="#" data-user-id="<?php echo $user_ID; ?>" data-follow-id="<?php echo $follow_id; ?>" class="button unfollow followed"><i></i> Unsubscribe</a>
        <a href="#" class="button follow" style="display:none;" data-user-id="<?php echo $user_ID; ?>" data-follow-id="<?php echo $follow_id; ?>"><i></i> Subscribe</a>
        <?php } else { ?>
        <a href="#" class="button follow" data-user-id="<?php echo $user_ID; ?>" data-follow-id="<?php echo $follow_id; ?>"><i></i> Subscribe</a>
        <a href="#" class="button followed unfollow" style="display:none;" data-user-id="<?php echo $user_ID; ?>" data-follow-id="<?php echo $follow_id; ?>"><i></i> Unsubscribe</a>
        <?php } ?>
        <?php else: ?>
        <a class="not-logged-inbutton"><i></i> Subscribe</a>
        <?php endif; ?>
<?php
return ob_get_clean();
}

Here are the ajax actions and the ajax function:

function tb_process_new_follow() {
if ( isset( $_POST['user_id'] ) && isset( $_POST['follow_id'] ) ) {
    if( tb_follow_user( absint( $_POST['user_id'] ), absint( $_POST['follow_id'] ) ) ) {
        echo 'success';
    } else {
        echo 'failed';
    }
}
die();
}
add_action('wp_ajax_follow', 'tb_process_new_follow');

function tb_process_unfollow() {
if ( isset( $_POST['user_id'] ) && isset( $_POST['follow_id'] ) ) {
    if( tb_unfollow_user( absint( $_POST['user_id'] ), absint( $_POST['follow_id'] ) ) ) {
        echo 'success';
    } else {
        echo 'failed';
    }
}
die();
}
add_action('wp_ajax_unfollow', 'tb_process_unfollow');

jQuery:

jQuery(document).ready(function($) {
/*******************************
follow / unfollow a user
*******************************/
$( '.follow-links a' ).on('click', function(e) {
    e.preventDefault();

    var $this = $(this);

    var data      = {
        action:    $this.hasClass('follow') ? 'follow' : 'unfollow',
        user_id:   $this.data('user-id'),
        follow_id: $this.data('follow-id'),
        nonce:     pwuf_vars.nonce
    };

    $.post( pwuf_vars.ajaxurl, data, function(response) {
        console.log(data);
        if( response == 'success' ) {
            $('.follow-links a').toggle();
        } else {
            console.log( pwuf_vars.processing_error );
        }
    } );
});
});
2
  • You did not include any ajax code? Did you debug your code?
    – Bjorn
    Commented Jun 10, 2018 at 7:21
  • @Bjorn I edited the question and added them in. Please take a look.
    – Matt H
    Commented Jun 10, 2018 at 22:56

1 Answer 1

0

Here are some pointers:

Why are you using output buffering in tb_get_follow_unfollow_links()? I see no reason this is needed.

In tb_get_follow_unfollow_links() only echo 1 button. On page load use php to decide what classes and button text you have to set.

With jQuery change the button when you get a successfull ajax return. Change the button class, so you can trigger a different ajax call on click.

Use .on to get events from dynamic (loaded from ajax) elements: $( "#container" ).on( "click", ".element", function() {});.

Your second question is easy to detect with some debugging. To check if the user already subscribed, you can do something like this:

$following = get_user_meta( $user_id, '_tb_following', true );
if( ! in_array( $id_to_check, $following )) { // user not subscribed, do it now }

Regards, Bjorn

4
  • I am not the most experienced when it comes to this so you'll have to explain in a little more detail please. When you say output buffering, what do you mean? What way is it supposed to be written?
    – Matt H
    Commented Jun 13, 2018 at 0:34
  • Also what way would you write the jquery because I still think I'd have the same issue as I'm having now with the wrong button being displayed on page load. I think the issue is with the php, which leads me to my final question, where is this code supposed to go? $following = get_user_meta( $user_id, '_tb_following', true ); if( ! in_array( $id_to_check, $following )) { // user not subscribed, do it now }
    – Matt H
    Commented Jun 13, 2018 at 0:36
  • In your question you say: I have a custom plugin . Did you create it yourself? I can't debug your code, because it's not complete (missing many action hooks). This article will help with debugging.... You say: the wrong button being displayed , like i said, only output 1 button element and change it with jQuery. Use debugging to check your php that displays the button to see if all the params are correct, or which ones are returning unexpected data. I can't help much more then this, sorry.
    – Bjorn
    Commented Jun 13, 2018 at 11:13
  • I created it from a tutorial: pippinsplugins.com/user-follow-system-part-1 and I tried your method for debugging but I am not getting anything in the error logs unfortunately.
    – Matt H
    Commented Jun 14, 2018 at 0:10

Your Answer

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

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