Skip to content
Be-smart

Be-smart

  • Home
  • Blog
    • Most Visited Posts
    • Stories
    • Unisex
      • Kids
      • Man
      • Woman
    • ADS
    • Social Media
  • About
    • Contact
  • Login

Adding like / unlike functionality to WordPress posts, limited by visitor IP

Photo of author
Flora
28/01/2025
Views: 20

Estimated Reading Time: 8 min

Below is a basic approach for adding like / unlike functionality to WordPress posts, limited by visitor IP. When a visitor clicks “like” or “unlike,” the script will:

  1. Check if that visitor’s IP has previously liked/unliked the post.
  2. If not, it updates the stored count and logs that IP, preventing multiple votes from the same IP.

This is a simplified version for demonstration. In production, you may want to consider stronger methods (user accounts or cookies, rate-limiting, etc.).

1. Basic Setup

We’ll place everything in a custom plugin for easy maintenance. Create a folder named wp-like-unlike-ip in wp-content/plugins/, and inside it, create a file wp-like-unlike-ip.php.

<?php
/**
 * Plugin Name: WP Like/Unlike by IP
 * Description: Adds basic like/unlike functionality to WordPress posts, tracking votes by IP.
 * Version:     1.0
 * Author:      Tokyo Blade
 * License:     GPL2
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Enqueue JavaScript for handling AJAX like/unlike actions.
 */
function wpluip_enqueue_scripts() {
    // Only enqueue on single posts (or wherever you want the buttons)
    if ( is_single() ) {
        wp_enqueue_script(
            'wpluip-like-unlike',
            plugin_dir_url( __FILE__ ) . 'js/wpluip-like-unlike.js',
            array( 'jquery' ),
            '1.0',
            true
        );

        // Localize script with AJAX URL and nonce
        wp_localize_script( 'wpluip-like-unlike', 'wpluip_ajax_obj', array(
            'ajax_url' => admin_url( 'admin-ajax.php' ),
            'nonce'    => wp_create_nonce( 'wpluip_ajax_nonce' ),
        ) );
    }
}
add_action( 'wp_enqueue_scripts', 'wpluip_enqueue_scripts' );

/**
 * Register AJAX actions for logged-in and non-logged-in users.
 */
add_action( 'wp_ajax_wpluip_like_unlike', 'wpluip_like_unlike_callback' );
add_action( 'wp_ajax_nopriv_wpluip_like_unlike', 'wpluip_like_unlike_callback' );

/**
 * Handle the like/unlike AJAX request.
 */
function wpluip_like_unlike_callback() {
    // Check nonce
    check_ajax_referer( 'wpluip_ajax_nonce', 'security' );

    $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0;
    $action_type = isset( $_POST['action_type'] ) ? sanitize_text_field( $_POST['action_type'] ) : '';

    if ( ! $post_id || ! in_array( $action_type, array( 'like', 'unlike' ), true ) ) {
        wp_send_json_error( array( 'message' => 'Invalid parameters.' ) );
    }

    // Get user IP
    $user_ip = wpluip_get_user_ip();

    // Store IPs in post meta: wpluip_like_ips, wpluip_unlike_ips
    $like_ips   = get_post_meta( $post_id, 'wpluip_like_ips', true );
    $unlike_ips = get_post_meta( $post_id, 'wpluip_unlike_ips', true );

    if ( ! is_array( $like_ips ) ) {
        $like_ips = array();
    }
    if ( ! is_array( $unlike_ips ) ) {
        $unlike_ips = array();
    }

    // Check if this IP has already voted in the same category
    if ( $action_type === 'like' && in_array( $user_ip, $like_ips, true ) ) {
        wp_send_json_error( array( 'message' => 'You already liked this post.' ) );
    }
    if ( $action_type === 'unlike' && in_array( $user_ip, $unlike_ips, true ) ) {
        wp_send_json_error( array( 'message' => 'You already unliked this post.' ) );
    }

    // Remove this IP from the opposite list if it exists (switching vote)
    if ( $action_type === 'like' && in_array( $user_ip, $unlike_ips, true ) ) {
        $unlike_ips = array_diff( $unlike_ips, array( $user_ip ) );
    }
    if ( $action_type === 'unlike' && in_array( $user_ip, $like_ips, true ) ) {
        $like_ips = array_diff( $like_ips, array( $user_ip ) );
    }

    // Update IP list accordingly
    if ( $action_type === 'like' ) {
        $like_ips[] = $user_ip;
    } else { // 'unlike'
        $unlike_ips[] = $user_ip;
    }

    update_post_meta( $post_id, 'wpluip_like_ips',   $like_ips );
    update_post_meta( $post_id, 'wpluip_unlike_ips', $unlike_ips );

    // Update counters
    $like_count   = count( $like_ips );
    $unlike_count = count( $unlike_ips );

    // Send back updated data
    wp_send_json_success( array(
        'message'       => 'Vote recorded',
        'like_count'    => $like_count,
        'unlike_count'  => $unlike_count,
    ) );
}

/**
 * Utility function to get user IP.
 */
function wpluip_get_user_ip() {
    // Basic approach (there are many ways to get IP, see Note below)
    if ( isset( $_SERVER['HTTP_CLIENT_IP'] ) ) {
        return sanitize_text_field( $_SERVER['HTTP_CLIENT_IP'] );
    } elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
        return sanitize_text_field( $_SERVER['HTTP_X_FORWARDED_FOR'] );
    } else {
        return sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
    }
}

/**
 * Shortcode to display Like/Unlike buttons + counts.
 * Usage: [wpluip_like_unlike post_id="123"]
 * If post_id is omitted, it uses current post in a loop.
 */
function wpluip_like_unlike_shortcode( $atts ) {
    global $post;

    $atts = shortcode_atts(
        array(
            'post_id' => 0,
        ),
        $atts,
        'wpluip_like_unlike'
    );

    $post_id = absint( $atts['post_id'] );

    // If no post_id in shortcode, use the global $post if available
    if ( ! $post_id && $post ) {
        $post_id = $post->ID;
    }

    if ( ! $post_id ) {
        return '<p>No valid post ID specified.</p>';
    }

    // Get current counts
    $like_ips   = get_post_meta( $post_id, 'wpluip_like_ips', true );
    $unlike_ips = get_post_meta( $post_id, 'wpluip_unlike_ips', true );
    $like_count   = is_array( $like_ips ) ? count( $like_ips ) : 0;
    $unlike_count = is_array( $unlike_ips ) ? count( $unlike_ips ) : 0;

    ob_start();
    ?>
    <div class="wpluip-vote-container" data-post-id="<?php echo esc_attr( $post_id ); ?>">
        <button type="button" class="wpluip-like-button">
            Like (<span class="wpluip-like-count"><?php echo esc_html( $like_count ); ?></span>)
        </button>
        <button type="button" class="wpluip-unlike-button">
            Unlike (<span class="wpluip-unlike-count"><?php echo esc_html( $unlike_count ); ?></span>)
        </button>
    </div>
    <?php
    return ob_get_clean();
}
add_shortcode( 'wpluip_like_unlike', 'wpluip_like_unlike_shortcode' );

Notes on Getting IP Address

Getting the “real” user IP can be complicated if proxies or load balancers are involved. The above method is basic. If you need a more robust approach, use services like Cloudflare’s CF-Connecting-IP header or specialized libraries that parse various X-Forwarded-For headers.

2. Create the JavaScript File

Inside wp-like-unlike-ip/js/ create a file named wpluip-like-unlike.js:

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

    // Handle Like Button Click
    $(document).on('click', '.wpluip-like-button', function() {
        const container = $(this).closest('.wpluip-vote-container');
        const postId = container.data('post-id');

        // Prepare AJAX data
        const data = {
            action: 'wpluip_like_unlike',
            security: wpluip_ajax_obj.nonce,
            post_id: postId,
            action_type: 'like'
        };

        $.post(wpluip_ajax_obj.ajax_url, data, function(response) {
            if (response.success) {
                // Update displayed counts
                container.find('.wpluip-like-count').text(response.data.like_count);
                container.find('.wpluip-unlike-count').text(response.data.unlike_count);
                alert(response.data.message);
            } else {
                alert(response.data.message);
            }
        });
    });

    // Handle Unlike Button Click
    $(document).on('click', '.wpluip-unlike-button', function() {
        const container = $(this).closest('.wpluip-vote-container');
        const postId = container.data('post-id');

        // Prepare AJAX data
        const data = {
            action: 'wpluip_like_unlike',
            security: wpluip_ajax_obj.nonce,
            post_id: postId,
            action_type: 'unlike'
        };

        $.post(wpluip_ajax_obj.ajax_url, data, function(response) {
            if (response.success) {
                // Update displayed counts
                container.find('.wpluip-like-count').text(response.data.like_count);
                container.find('.wpluip-unlike-count').text(response.data.unlike_count);
                alert(response.data.message);
            } else {
                alert(response.data.message);
            }
        });
    });

});

3. Create the Css File

Customizing Additional CSS:


/* Adding like button functionality to WordPress posts */ 

.wpluip-like-button {
    margin-top:15px;
    max-width:150px;
    background-color:#eee;
    border-color:#888888;
    color:#333;
    display:inline-block;
    vertical-align:middle;
    text-align:center;
    text-decoration:none;
    align-items:flex-start;
    cursor:default;
    -webkit-appearence: push-button;
    border-style: solid;
    border-width: 1px;
    border-radius: 5px;
    font-size: 0.8rem;
    font-family: inherit;
    border-color: #000;
    padding-left: 5px;
    padding-right: 5px;
    width: 100%;
    min-height: 30px;
}

.wpluip-like-button a {
    margin-top:4px;
    display:inline-block;
    text-decoration:none;
    color:#333;
}

.wpluip-like-button:hover {
    background-color:#888;
}

.wpluip-like-button:active {
    background-color:#333;
}

.wpluip-like-button:hover a, .link-button:active a {
    color:#fff;
}


/* Adding  unlike functionality to WordPress posts */ 


.wpluip-unlike-button {
    margin-top:15px;
    max-width:150px;
    background-color:#eee;
    border-color:#888888;
    color:#333;
    display:inline-block;
    vertical-align:middle;
    text-align:center;
    text-decoration:none;
    align-items:flex-start;
    cursor:default;
    -webkit-appearence: push-button;
    border-style: solid;
    border-width: 1px;
    border-radius: 5px;
    font-size: 0.8rem;
    font-family: inherit;
    border-color: #000;
    padding-left: 5px;
    padding-right: 5px;
    width: 100%;
    min-height: 30px;
}

.wpluip-unlike-button a {
    margin-top:4px;
    display:inline-block;
    text-decoration:none;
    color:#333;
}

.wpluip-unlike-button:hover {
    background-color:#888;
}

.wpluip-unlike-button:active {
    background-color:#333;
}

.wpluip-unlike-button:hover a, .link-button:active a {
    color:#fff;
}







4 Usage

  1. Activate the Plugin: Go to Plugins > Installed Plugins and activate “WP Like/Unlike by IP.”
  2. Insert the Shortcode:
    • In the post content (e.g., the end of a blog post), add:

or

if you want to display buttons for a specific post outside of that post’s own page.

5. Test It:

  • Visit the post on the front end.
  • Click Like or Unlike and watch the counts update. If you try clicking again, you should get an error message saying you already voted from this IP.

6. Potential Enhancements

  1. User Accounts: Instead of IP-based tracking, you might require users to be logged in and store votes by user ID.
  2. Cookie Fallback: If you worry about dynamic IP addresses or proxies, you might combine IP checks with a browser cookie.
  3. Styling: Add custom CSS to style the buttons or place them in a more visually appealing layout.
  4. Security: For large sites, consider rate-limiting or more advanced checks to prevent malicious scripts from spamming votes.
  5. Display Past Votes: If you want to show whether the user already liked/unliked, you can check the IP in the page output and highlight the corresponding button.

Final Thoughts

This example provides a basic IP-based like/unlike system. Use it as a starting point and adapt it to your site’s requirements. If you later decide to expand functionality—like blocking repeat votes more robustly or switching from IP-based to user-based authentication—the structure above still applies.

Categories BSB, WordPress
How to Use Headline Analyzer in WordPress to Improve SEO Titles
What are the most effective ways to create high-quality content?
Share on Facebook Share on WhatsApp Share on X (Twitter) Share via Email

Related Posts

  • Fans will remember him as the best heavyweight
  • How to use BitLocker Device Encryption
  • Celebrities who became all world famous posthumously
  • How to create Trump Ticker price from binance app
Photo of author

Flora

Adding like / unlike functionality to WordPress posts, limited by visitor IP

Published 28/01/2025

Update 11/02/2025

Contact

  • X
  • TikTok
  • Facebook
  • WhatsApp
I am Flora, the publisher and founder of *Be-Smart*, a platform dedicated to sharing insights and inspiration for living a fulfilling life. With a strong background in the web, my goal is to empower people to genuinely recognize and celebrate admirable actions big or small in themselves and others.

Bitcoin Price (BTC)

$104,699.58

Download BTC Ticker

Trending Posts

  • Here are ten of the most iconic and celebrated BMW models of all time
  • BMW M4 Competition (F82): Redefining Performance and Style
  • How to Clear Cache BlueHost with Cron Job Command
  • Legendary ‘Killing Me Softly’ singer, dead at 88
  • Euro 2024 Qualification Groups: All You Need to Know

Recent Posts

  • Fresh and Healthy Heart of Palm Salad Recipe
  • Ultimate WordPress Countdown Timer: PHP, CSS & JavaScript Guide
  • How to create a related posts section
  • How to uninstall Windows programs using a batch script
  • Here are 5 cool WhatsApp tricks you might not know about:

Archives

  • March 2025 (1)
  • February 2025 (65)
  • January 2025 (94)
  • December 2024 (42)
  • November 2024 (69)
  • October 2024 (92)
  • September 2024 (31)

Recent Comments

No comments to show.

Partners Group

Amazon AliExpress BlueHost
GeneratePress SnepBelgium Takeaway

BlogRoll

Mirror

The MixedZone

Finance Digest

  • Facebook
  • X
  • WhatsApp
  • RSS Feed
  • Facebook
  • X
  • WhatsApp
  • RSS Feed

BSB (228) Celebrity (24) Europe (37) Food (14) Html (41) Lifestyle (23) Love (18) Medical (15) Movies (18) My Health (28) PC World (36) PHP (22) Science (15) Social Media (13) Software (14) Stories (96) Weekly Horoscopes (13) Windows (29) Woman (20) WordPress (76)

  • Privacy Policy
  • Terms and Conditions
  • Disclaimer
  • Cookie Policy

© 2024 Be-smart

All Rights Reserved

Built with GeneratePress

This website uses cookies to ensure you get the best experience. By continuing to browse, you agree to our Privacy Policy.