<?php

/*
Name:  WordPress Post Like System
Description:  A simple and efficient post like system for WordPress.
Version:      0.5.2
Author:       Jon Masterson
Author URI:   http://jonmasterson.com/
License:
Copyright (C) 2015 Jon Masterson
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


/**
 * Processes like/unlike
 * @since    0.5
 */
add_action( 'wp_ajax_nopriv_process_simple_like', 'passport_process_simple_like' );
add_action( 'wp_ajax_process_simple_like', 'passport_process_simple_like' );

if( ! function_exists( 'passport_process_simple_like' ) ) {

    function passport_process_simple_like() {
	    // Security
	    $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( $_REQUEST['nonce'] ) : 0;
	    if ( ! wp_verify_nonce( $nonce, 'simple-likes-nonce' ) ) {
		    exit( esc_html__( 'Not permitted', 'passport' ) );
	    }
	    // Test if javascript is disabled
	    $disabled = ( isset( $_REQUEST['disabled'] ) && true == $_REQUEST['disabled'] ) ? true : false;
	    // Test if this is a comment
	    $is_comment = ( isset( $_REQUEST['is_comment'] ) && 1 == $_REQUEST['is_comment'] ) ? 1 : 0;
	    // Base variables
	    $post_id = ( isset( $_REQUEST['post_id'] ) && is_numeric( $_REQUEST['post_id'] ) ) ? $_REQUEST['post_id'] : '';
	    $result = array();
	    $post_users = NULL;
	    $like_count = 0;
	    // Get plugin options
	    if ( '' != $post_id ) {
		    $count = ( 1 == $is_comment ) ? get_comment_meta( $post_id, "_comment_like_count", true ) : get_post_meta( $post_id, "_post_like_count", true ); // like count
		    $count = ( isset( $count ) && is_numeric( $count ) ) ? $count : 0;
		    if ( ! passport_already_liked( $post_id, $is_comment ) ) { // Like the post
			    if ( is_user_logged_in() ) { // user is logged in
				    $user_id    = get_current_user_id();
				    $post_users = passport_post_user_likes( $user_id, $post_id, $is_comment );
				    if ( 1 == $is_comment ) {
					    // Update User & Comment
					    $user_like_count = get_user_option( "_comment_like_count", $user_id );
					    $user_like_count =  ( isset( $user_like_count ) && is_numeric( $user_like_count ) ) ? $user_like_count : 0;
					    update_user_option( $user_id, "_comment_like_count", ++$user_like_count );
					    if ( $post_users ) {
						    update_comment_meta( $post_id, "_user_comment_liked", $post_users );
					    }
				    } else {
					    // Update User & Post
					    $user_like_count = get_user_option( "_user_like_count", $user_id );
					    $user_like_count =  ( isset( $user_like_count ) && is_numeric( $user_like_count ) ) ? $user_like_count : 0;
					    update_user_option( $user_id, "_user_like_count", ++$user_like_count );
					    if ( $post_users ) {
						    update_post_meta( $post_id, "_user_liked", $post_users );
					    }
				    }
			    } else { // user is anonymous
				    $user_ip    = passport_sl_get_ip();
				    $post_users = passport_post_ip_likes( $user_ip, $post_id, $is_comment );
				    // Update Post
				    if ( $post_users ) {
					    if ( 1 == $is_comment ) {
						    update_comment_meta( $post_id, "_user_comment_IP", $post_users );
					    } else { 
						    update_post_meta( $post_id, "_user_IP", $post_users );
					    }
				    }
			    }
			    $like_count = ++$count;
			    $response['status'] = "liked";
			    $response['icon']   = passport_get_liked_icon();
		    } else { // Unlike the post
			    if ( is_user_logged_in() ) { // user is logged in
				    $user_id    = get_current_user_id();
				    $post_users = passport_post_user_likes( $user_id, $post_id, $is_comment );
				    // Update User
				    if ( 1 == $is_comment ) {
					    $user_like_count = get_user_option( "_comment_like_count", $user_id );
					    $user_like_count =  ( isset( $user_like_count ) && is_numeric( $user_like_count ) ) ? $user_like_count : 0;
					    if ( $user_like_count > 0 ) {
						    update_user_option( $user_id, "_comment_like_count", --$user_like_count );
					    }
				    } else {
					    $user_like_count = get_user_option( "_user_like_count", $user_id );
					    $user_like_count =  ( isset( $user_like_count ) && is_numeric( $user_like_count ) ) ? $user_like_count : 0;
					    if ( $user_like_count > 0 ) {
						    update_user_option( $user_id, '_user_like_count', --$user_like_count );
					    }
				    }
				    // Update Post
				    if ( $post_users ) {	
					    $uid_key = array_search( $user_id, $post_users );
					    unset( $post_users[$uid_key] );
					    if ( 1 == $is_comment ) {
						    update_comment_meta( $post_id, "_user_comment_liked", $post_users );
					    } else { 
						    update_post_meta( $post_id, "_user_liked", $post_users );
					    }
				    }
			    } else { // user is anonymous
				    $user_ip    = passport_sl_get_ip();
				    $post_users = passport_post_ip_likes( $user_ip, $post_id, $is_comment );
				    // Update Post
				    if ( $post_users ) {
					    $uip_key = array_search( $user_ip, $post_users );
					    unset( $post_users[$uip_key] );
					    if ( 1 == $is_comment ) {
						    update_comment_meta( $post_id, "_user_comment_IP", $post_users );
					    } else { 
						    update_post_meta( $post_id, "_user_IP", $post_users );
					    }
				    }
			    }
			    $like_count = ( $count > 0 ) ? --$count : 0; // Prevent negative number
			    $response['status'] = "unliked";
			    $response['icon']   = passport_get_unliked_icon();
		    }
		    if ( 1 == $is_comment ) {
			    update_comment_meta( $post_id, "_comment_like_count", $like_count );
			    update_comment_meta( $post_id, "_comment_like_modified", date( 'Y-m-d H:i:s' ) );
		    } else { 
			    update_post_meta( $post_id, "_post_like_count", $like_count );
			    update_post_meta( $post_id, "_post_like_modified", date( 'Y-m-d H:i:s' ) );
		    }
		    $response['count']   = passport_get_like_count( $like_count );
		    $response['testing'] = $is_comment;
		    if ( true == $disabled ) {
			    if ( 1 == $is_comment ) {
				    wp_redirect( get_permalink( get_the_ID() ) );
				    exit();
			    } else {
				    wp_redirect( get_permalink( $post_id ) );
				    exit();
			    }
		    } else {
			    wp_send_json( $response );
		    }
	    }
    }

}


/**
 * Utility to test if the post is already liked
 * @since    0.5
 */
if( ! function_exists( 'passport_already_liked' ) ) {

    function passport_already_liked( $post_id, $is_comment ) {
	    $post_users = NULL;
	    $user_id = NULL;
	    if ( is_user_logged_in() ) { // user is logged in
		    $user_id = get_current_user_id();
		    $post_meta_users = ( 1 == $is_comment ) ? get_comment_meta( $post_id, "_user_comment_liked" ) : get_post_meta( $post_id, "_user_liked" );
		    if ( 0 != count( $post_meta_users ) ) {
			    $post_users = $post_meta_users[0];
		    }
	    } else { // user is anonymous
		    $user_id = passport_sl_get_ip();
		    $post_meta_users = ( 1 == $is_comment ) ? get_comment_meta( $post_id, "_user_comment_IP" ) : get_post_meta( $post_id, "_user_IP" ); 
		    if ( 0 != count( $post_meta_users ) ) { // meta exists, set up values
			    $post_users = $post_meta_users[0];
		    }
	    }
	    if ( is_array( $post_users ) && in_array( $user_id, $post_users ) ) {
		    return true;
	    } else {
		    return false;
	    }
    } 

}// passport_already_liked()


/**
 * Output the like button
 * @since    0.5
 */
if( ! function_exists( 'passport_get_simple_likes_button' ) ) {

    function passport_get_simple_likes_button( $post_id, $is_comment = NULL ) {
	    $is_comment = ( NULL == $is_comment ) ? 0 : 1;
	    $output = '';
	    $nonce = wp_create_nonce( 'simple-likes-nonce' ); // Security
	    if ( 1 == $is_comment ) {
		    $post_id_class  = esc_attr( ' sl-comment-button-' . $post_id );
		    $comment_class  = esc_attr( ' sl-comment' );
		    $like_count     = get_comment_meta( $post_id, "_comment_like_count", true );
		    $like_count     = ( isset( $like_count ) && is_numeric( $like_count ) ) ? $like_count : 0;
	    } else {
		    $post_id_class  = esc_attr( ' sl-button-' . $post_id );
		    $comment_class  = esc_attr( '' );
		    $like_count     = get_post_meta( $post_id, "_post_like_count", true );
		    $like_count     = ( isset( $like_count ) && is_numeric( $like_count ) ) ? $like_count : 0;
	    }
	    $count      = passport_get_like_count( $like_count );
	    $icon_empty = passport_get_unliked_icon();
	    $icon_full  = passport_get_liked_icon();
	    // Loader
	    $loader = '<span class="sl-loader"></span>';
	    // Liked/Unliked Variables
	    if ( passport_already_liked( $post_id, $is_comment ) ) {
		    $class = esc_attr( ' liked' );
		    $title = esc_html__( 'Unlike', 'passport' );
		    $icon   = $icon_full;
	    } else {
		    $class = '';
		    $title = esc_html__( 'Like', 'passport' );
		    $icon   = $icon_empty;
	    }
	    $output = '<span class="sl-wrapper"><a href="' . esc_url( admin_url( 'admin-ajax.php?action=passport_process_simple_like' . '&nonce=' . $nonce . '&post_id=' . $post_id . '&disabled=true&is_comment=' . $is_comment ) ) . '" class="sl-button' . $post_id_class . $class . $comment_class . '" data-nonce="' . $nonce . '" data-post-id="' . $post_id . '" data-iscomment="' . $is_comment . '" title="' . esc_attr( $title ) . '">' . $icon . $count . '</a>' . $loader . '</span>';
	    return $output;
    } 

}// passport_get_simple_likes_button()


/**
 * Utility retrieves post meta user likes (user id array), 
 * then adds new user id to retrieved array
 * @since    0.5
 */
if( ! function_exists( 'passport_post_user_likes' ) ) {

    function passport_post_user_likes( $user_id, $post_id, $is_comment ) {
	    $post_users = '';
	    $post_meta_users = ( 1 == $is_comment ) ? get_comment_meta( $post_id, "_user_comment_liked" ) : get_post_meta( $post_id, "_user_liked" );
	    if ( 0 != count( $post_meta_users ) ) {
		    $post_users = $post_meta_users[0];
	    }
	    if ( !is_array( $post_users ) ) {
		    $post_users = array();
	    }
	    if ( !in_array( $user_id, $post_users ) ) {
		    $post_users['user-' . $user_id] = $user_id;
	    }
	    return $post_users;
    } 

}// passport_post_user_likes()


/**
 * Utility retrieves post meta ip likes (ip array), 
 * then adds new ip to retrieved array
 * @since    0.5
 */
if( ! function_exists( 'passport_post_ip_likes' ) ) {

    function passport_post_ip_likes( $user_ip, $post_id, $is_comment ) {
	    $post_users = '';
	    $post_meta_users = ( 1 == $is_comment ) ? get_comment_meta( $post_id, "_user_comment_IP" ) : get_post_meta( $post_id, "_user_IP" );
	    // Retrieve post information
	    if ( 0 != count( $post_meta_users ) ) {
		    $post_users = $post_meta_users[0];
	    }
	    if ( !is_array( $post_users ) ) {
		    $post_users = array();
	    }
	    if ( !in_array( $user_ip, $post_users ) ) {
		    $post_users['ip-' . $user_ip] = $user_ip;
	    }
	    return $post_users;
    } 

}// passport_post_ip_likes()


/**
 * Utility to retrieve IP address
 * @since    0.5
 */
if( ! function_exists( 'passport_sl_get_ip' ) ) {

    function passport_sl_get_ip() {
	    if ( isset( $_SERVER['HTTP_CLIENT_IP'] ) && ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
		    $ip = $_SERVER['HTTP_CLIENT_IP'];
	    } elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) && ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
		    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
	    } else {
		    $ip = ( isset( $_SERVER['REMOTE_ADDR'] ) ) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
	    }
	    $ip = filter_var( $ip, FILTER_VALIDATE_IP );
	    $ip = ( false == $ip ) ? '0.0.0.0' : $ip;
	    return $ip;
    } 

}// passport_sl_get_ip()


/**
 * Utility returns the button icon for "like" action
 * @since    0.5
 */
if( ! function_exists( 'passport_get_liked_icon' ) ) {

    function passport_get_liked_icon() {
	    /* If already using Font Awesome with your theme, replace svg with: <i class="fa fa-heart"></i> */
	    $icon = '<span class="sl-icon"><i class="fa fa-heart"></i></span>';
	    return $icon;
    } 

}// passport_get_liked_icon()


/**
 * Utility returns the button icon for "unlike" action
 * @since    0.5
 */
if( ! function_exists( 'passport_get_unliked_icon' ) ) {

    function passport_get_unliked_icon() {
	    /* If already using Font Awesome with your theme, replace svg with: <i class="fa fa-heart-o"></i> */
	    $icon = '<span class="sl-icon"><i class="fa fa-heart-o"></i></span>';
	    return $icon;
    } 

}// passport_get_unliked_icon()


/**
 * Utility function to format the button count,
 * appending "K" if one thousand or greater,
 * "M" if one million or greater,
 * and "B" if one billion or greater (unlikely).
 * $precision = how many decimal points to display (1.25K)
 * @since    0.5
 */
if( ! function_exists( 'passport_sl_format_count' ) ) {

    function passport_sl_format_count( $number ) {
	    $precision = 2;
	    if ( $number >= 1000 && $number < 1000000 ) {
		    $formatted = number_format( $number/1000, $precision ).'K';
	    } else if ( $number >= 1000000 && $number < 1000000000 ) {
		    $formatted = number_format( $number/1000000, $precision ).'M';
	    } else if ( $number >= 1000000000 ) {
		    $formatted = number_format( $number/1000000000, $precision ).'B';
	    } else {
		    $formatted = $number; // Number is less than 1000
	    }
	    $formatted = str_replace( '.00', '', $formatted );
	    return $formatted;
    } 

}// passport_sl_format_count()


/**
 * Utility retrieves count plus count options, 
 * returns appropriate format based on options
 * @since    0.5
 */
if( ! function_exists( 'passport_get_like_count' ) ) {

    function passport_get_like_count( $like_count ) {
	    $like_text = esc_html__( 'Like', 'passport' );
	    if ( is_numeric( $like_count ) && $like_count > 0 ) { 
		    $number = passport_sl_format_count( $like_count );
	    } else {
		    $number = $like_text;
	    }
	    $count = '<span class="sl-count">' . $number . '</span>';
	    return $count;
    } 

}// passport_get_like_count()


// User Profile List
add_action( 'show_user_profile', 'passport_show_user_likes' );
add_action( 'edit_user_profile', 'passport_show_user_likes' );

if( ! function_exists( 'passport_show_user_likes' ) ) {

    function passport_show_user_likes( $user ) { ?>        
	    <table class="form-table">
		    <tr>
			    <th><label for="user_likes"><?php esc_html_e( 'You Like:', 'passport' ); ?></label></th>
			    <td>
			    <?php
			    $types = get_post_types( array( 'public' => true ) );
			    $args = array(
			      'numberposts' => -1,
			      'post_type'   => $types,
			      'meta_query'  => array (
				    array (
				      'key'     => '_user_liked',
				      'value'   => $user->ID,
				      'compare' => 'LIKE'
				    )
			      ) );		
			    $sep = '';
			    $like_query = new WP_Query( $args );
			    if ( $like_query->have_posts() ) : ?>
			    <p>
			    <?php while ( $like_query->have_posts() ) : $like_query->the_post(); 
			    echo $sep; ?><a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a>
			    <?php
			    $sep = ' &middot; ';
			    endwhile; 
			    ?>
			    </p>
			    <?php else : ?>
			    <p><?php esc_html_e( 'You do not like anything yet.', 'passport' ); ?></p>
			    <?php 
			    endif; 
			    wp_reset_postdata(); 
			    ?>
			    </td>
		    </tr>
	    </table>
    <?php } 
 
}// passport_show_user_likes()