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.
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.
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 );
}
} );
});
});