Working on a “Like” vs “Dislike” for blog post in WordPress. While all is working fine, the intention here is to make it work for guests and logged in users, but more importantly; to only allow one click (Like or Dislike) per post from the same user (trying to understand if I can use WordPress sessions here?).
Idea:
Guest / registered and logged in user clicks on Like or Dislike = both button for that specific post are deactivated (cannot be clicked again). If the same user visits a different post on the same website where the user has not yet clicked any of the two buttons; they can click either Like or Dislike.
I hope I am being clear and that you all understand me. I’m looking for advice and code examples and what not as to how to achieve this.
As of now; a user (logged in or not) can click on Like or Dislike as many times as they want and the count just keeps on ticking — which is NOT ideal.
This is the code I’m working on:
add_filter( 'the_content', 'post_likes' );
function post_likes( $content ) {
// only on posts
if ( is_singular( 'post' ) ) {
ob_start();
?>
<ul class="likes">
<li class="likes__item likes__item--like">
<a href="<?php echo add_query_arg( 'post_action', 'like'); ?>">
Useful (<?php echo get_post_like_count('likes') ?>)
</a>
</li>
<li class="likes__item likes__item--dislike">
<a href="<?php echo add_query_arg('post_action', 'dislike'); ?>">
Dislike (<?php echo get_post_like_count('dislikes') ?>)
</a>
</li>
</ul>
<?php
$output = ob_get_clean();
return $output . $content;
} else {
return $content;
}
}
function get_post_like_count( $type = 'likes' ) {
// like or dislike count
$current_count = get_post_meta( get_the_id(), $type, true );
return ( $current_count ? $current_count : 0 );
}
add_action( 'template_redirect', 'process_post_like_click' );
function process_post_like_click() {
$processed_like = false;
$redirect = false;
// Check if like or dislike
if ( is_singular( 'post' ) ) {
if ( isset( $_GET['post_action'] ) ) {
if ( $_GET['post_action'] == 'like' ) {
// Like
$like_count = get_post_meta( get_the_id(), 'likes', true );
if ( $like_count ) {
$like_count = $like_count + 1;
} else {
$like_count = 1;
}
$processed_like = update_post_meta( get_the_id(), 'likes', $like_count );
} elseif ( $_GET['post_action'] == 'dislike' ) {
// Dislike
$dislike_count = get_post_meta( get_the_id(), 'dislikes', true );
if ( $dislike_count ) {
$dislike_count = $dislike_count + 1;
} else {
$dislike_count = 1;
}
$processed_like = update_post_meta( get_the_id(), 'dislikes', $dislike_count );
}
if ( $processed_like ) {
$redirect = get_the_permalink();
// how do I deactivate both buttons on this post while keping them intact on other posts?
}
}
}
// redirect (refresh)
if ( $redirect ) {
wp_redirect( $redirect );
die;
}
}
Thanks all!
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Untested Pseudo-code examples, which you can expand to resolve the issues:
function get_the_user_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'];
}
return apply_filters( 'get_the_user_ip', $ip );
}
Then, you can store all data in a single post_meta field, you just need to structure your array correctly.
array(
'like' => array(
'ip1', 'ip2', 'ip3', 'etc'
),
'dislike' => array(
'ip4', 'ip5', 'ip6', 'etc'
)
)
This way you can create a few helper functions ( or, better a class with some getter and setter methods ) to reference when loading the UI and when saving data.
function get_like_count( $type = 'like' ) {
// get post meta ##
$array = get_post_meta( get_the_ID(), 'post_meta_field' );
// @todo -- validate it is an array and the requested key exists ##
// return count ##
return count( $array[ $type ] );
}
function set_like_count( $type = 'like' ) {
// get post meta ##
$array = get_post_meta( get_the_ID(), 'post_meta_field' );
// @todo -- validate it is an array and the requested key exists ##
// update count for post ##
$array[ $type ][] = get_the_user_ip();
// save ##
update_post_meta( get_the_ID(), 'post_meta_field', $array );
}
/** check if the user IP is already stored for this post */
function has_liked() {
// get post meta ##
$array = get_post_meta( get_the_ID(), 'post_meta_field' );
// @todo -- validate it is an array and the requested key exists ##
// search the array for the IP value
// this might need to search each array key if you want to know what action the user took ##
return in_array( get_the_user_ip(), $array );
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0